首页IT科技若依框架官网(若依框架前端Vue项目分析实战)

若依框架官网(若依框架前端Vue项目分析实战)

时间2025-08-04 16:03:53分类IT科技浏览7710
导读:说明 前面讲解了vue2的单点知识,下面用若依提供的vue项目,实战分析一下,拿到一个vue项目,如何进行分析并进行二次开发。...

说明

前面讲解了vue2的单点知识                ,下面用若依提供的vue项目                        ,实战分析一下        ,拿到一个vue项目        ,如何进行分析并进行二次开发                。

一                、public/index.html与main.js和App.vue三者的关系

vue项目是单界面应用                        ,所有的界面将在public下的index.html里呈现                        。

main.js是程序的入口                ,在这里        ,定义了vue实例对象        。如下代码: new Vue({ el: #app, router,//路由插件 store,//vuex插件,所有的组件中都可以使用store中的action,mutation和state数据                。通过$strore调用或者mapXXX函数映射 render: h => h(App) })

其中                        ,el配置项是配置vm实例要填充的public/index.html里的元素对象                        。render属性配置的是用App.vue组件进行填充        。在vm实例对象挂载完成之前                ,即mouted函数执行之前,页面显示的是public/index.html中本身的元素                        ,在挂载完成后                        ,public/index.html中会显示App.vue中的元素        。

在public/index.html中,原有的是加载中插件                ,如下: <body> <div id="app"> <div id="loader-wrapper"> <div id="loader"></div> <div class="loader-section section-left"></div> <div class="loader-section section-right"></div> <div class="load_title">正在加载系统资源                        ,请耐心等待</div> </div> </div>

所以        ,刷新界面时                ,先出现加载中界面                        ,如下:

等vm实例挂载完成后        ,显示App.vue组件内容                        。

下面分析App.vue中组件的内容                。

看template内容: <template> <div id="app"> <!-- 路由占位,router-link在哪 --> <router-view /> </div> </template>

这里只有router-view        ,说明这里要进行路由的切换展示        。所以                        ,接下来该分析路由的配置                ,看App.vue跳转到了哪个组件                        。

二                        、路由分析

路由的配置在router/index.js下        ,进行分析:

{ path: , component: Layout, redirect: index, children: [ { path: index, component: () => import(@/views/index), name: Index, meta: { title: 首页, icon: dashboard, affix: true } } ] }

这段路由配置就是App.vue挂载完成后的展示组件                。首先                        ,项目访问路径为’(空)时                ,加载的组件是Layout组件,展示Layout组件内容。通过redirect属性重定向到index路径                        。index是子路由                        ,在Layout中展示index.vue界面                        。这就是为何每次刷新                        ,默认打开首页tab页的原因。

这里,补充个知识点:

不管是router-link的to属性                ,还是直接在浏览器输入路径                        ,如果输入的是子路由的路径        ,那么界面会展示子路由的组件                ,也会展示父路由的组件                。不会单独展示子路由对应的组件                        。

如:to=/home/SeatDistribute                        ,则对应的view会显示App.vue和Home.vue和/home/SeatDistribute组件        。

to=/home        ,view会显示App.vue组件和Home.vue组件                。

根据路径        ,找router-view的位置:

路径为一层的                        ,如:/home                        。则对应App.vue中的router-view        。

路径为多层的                ,如/home/SeatDistribute        ,则找其父组件的router-view                        ,即Home.vue组件中的router-view        。

所以                ,上面重定向到index.vue组件后,也是显示Layout组件的                        。即在Layout组件内部                        ,再显示index.vue组件                。router定义子路由时                        ,默认children子路由就是被父路由包裹的        。

三        、Layout组件分析

通过上面分析,可知App.vue展示的是Layout组件                ,那么下面就分析Layout组件                        。通过分析                        ,Layout组件是布局组件        ,即后台管理系统的整体布局                ,是通过这个组件完成的                。里面包含了很多子组件嵌套。下面先画一下其组件划分结构:

可见                        ,将整体布局划分成上图的几个组件                        。这也体现出了vue组件化编程的思想                        。在每个组件内部        ,又对各个部分进行了组件的拆分        ,例如在navbar组件中                        ,

每个元素                ,都划分成了一个组件。这里主要体会组件化编程思想                。具体组件的实现方式        ,这里不做深入研究                        。已经提供好的功能                        ,我们直接拿来用即可        。

四        、Vuex应用分析

在main.js中定义vue的时候                ,可以看到使用了Vuex技术,如下:

new Vue({ el: #app, router,//路由插件 store,//vuex插件,所有的组件中都可以使用store中的action,mutation和state数据                。通过$strore调用或者mapXXX函数映射 render: h => h(App), beforeMount() { debugger; } })

下面就分析一下Vuex技术在项目中是如何应用的                        。

首先                        ,看stroe/index.js文件: Vue.use(Vuex) const store = new Vuex.Store({ modules: { app, user, tagsView, permission, settings }, getters }) export default store

可以看到                        ,使用了模块化命名,分成了权限模块                ,设置模块                        ,用户模块等几个模块        。因为Vuex最终操作的都是state对象        ,所以                ,重点看一下这几个模块的state对象都存入了什么:

权限模块permission.js: state: { routes: [], addRoutes: [], defaultRoutes: [], topbarRouters: [], sidebarRouters: [] }

可见                        ,权限模块state存入了路由数据        。路由可以共享到每个组件去使用                        。

用户模块user.js:

state: { token: getToken(), name: , avatar: , roles: [], permissions: [] }

用户模块state定义了token,用户名        ,用户角色        ,用户权限等数据                        ,用于共享                。

设置模块settings.js:

const state = { title: , theme: storageSetting.theme || #409EFF, sideTheme: storageSetting.sideTheme || sideTheme, showSettings: showSettings, topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav, tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView, fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader, sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo, dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle }

可见                ,settings.js模块定义了皮肤颜色        ,主题风格                        ,边距等等数据用于共享        。

各模块的Actions和Mutations对象定义了各种函数来操作这些state数据                ,这里就 不一一列举了                        。

通过上面存入Vuex中的数据可以知道,在项目中                        ,把全局的一些信息                        ,存入Vuex中                。这些信息可以是前端自己设定的,也可以是后台获取的数据。这样                ,在项目的任何一个组件中                        ,都可以通过$store属性或者mapXXX函数获取到这些共享数据                        。

Vuex有点儿类似于原生js中的全局变量的感觉                        。

五                        、关于动态路由和菜单权限的实现

前面讲路由时        ,路由都是在router/index.js里预置好的。但是在真实项目中                ,菜单肯定是通过权限                        ,在后台获取的                。分析一下若依框架        ,是如何实现权限分配和动态路由的                        。

首先找到菜单的组件        ,上面已经分析过                        ,是Layout组件中的sidebar组件        。点进去                ,看sidebar组件的实现: <sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path + index" :item="route" :base-path="route.path" />

可见        ,其遍历了sidebarRouters                        ,而sidebarRouters通过Vuex的分析可知                ,其配置在了permissions模块的state中                。所以,在permissions.js的Actions对象和Mutations对象中                        ,肯定有操作这个数据的函数                        ,找相应的代码                        。

代码比较分散,下面看其实现思路:

首先                ,在Actions函数中                        ,利用axios发送请求到后台        ,获取用户菜单权限                ,该接口的返回值如下: { "msg": "操作成功", "code": 200, "data": [{ "name": "System", "path": "/system", "hidden": false, "redirect": "noRedirect", "component": "Layout", "alwaysShow": true, "meta": { "title": "系统管理", "icon": "system", "noCache": false, "link": null }, "children": [{ "name": "User", "path": "user", "hidden": false, "component": "system/user/index", "meta": { "title": "用户管理", "icon": "user", "noCache": false, "link": null } }, { "name": "Role", "path": "role", "hidden": false, "component": "system/role/index", "meta": { "title": "角色管理", "icon": "peoples", "noCache": false, "link": null } }, { "name": "Menu", "path": "menu", "hidden": false, "component": "system/menu/index", "meta": { "title": "菜单管理", "icon": "tree-table", "noCache": false, "link": null } }, { "name": "Dept", "path": "dept", "hidden": false, "component": "system/dept/index", "meta": { "title": "部门管理", "icon": "tree", "noCache": false, "link": null } }, { "name": "Post", "path": "post", "hidden": false, "component": "system/post/index", "meta": { "title": "岗位管理", "icon": "post", "noCache": false, "link": null } }, { "name": "Dict", "path": "dict", "hidden": false, "component": "system/dict/index", "meta": { "title": "字典管理", "icon": "dict", "noCache": false, "link": null } }, { "name": "Config", "path": "config", "hidden": false, "component": "system/config/index", "meta": { "title": "参数设置", "icon": "edit", "noCache": false, "link": null } }, { "name": "Notice", "path": "notice", "hidden": false, "component": "system/notice/index", "meta": { "title": "通知公告", "icon": "message", "noCache": false, "link": null } }, { "name": "Log", "path": "log", "hidden": false, "redirect": "noRedirect", "component": "ParentView", "alwaysShow": true, "meta": { "title": "日志管理", "icon": "log", "noCache": false, "link": null }, "children": [{ "name": "Operlog", "path": "operlog", "hidden": false, "component": "monitor/operlog/index", "meta": { "title": "操作日志", "icon": "form", "noCache": false, "link": null } }, { "name": "Logininfor", "path": "logininfor", "hidden": false, "component": "monitor/logininfor/index", "meta": { "title": "登录日志", "icon": "logininfor", "noCache": false, "link": null } }] }] }, { "name": "Monitor", "path": "/monitor", "hidden": false, "redirect": "noRedirect", "component": "Layout", "alwaysShow": true, "meta": { "title": "系统监控", "icon": "monitor", "noCache": false, "link": null }, "children": [{ "name": "Online", "path": "online", "hidden": false, "component": "monitor/online/index", "meta": { "title": "在线用户", "icon": "online", "noCache": false, "link": null } }, { "name": "Job", "path": "job", "hidden": false, "component": "monitor/job/index", "meta": { "title": "定时任务", "icon": "job", "noCache": false, "link": null } }, { "name": "Druid", "path": "druid", "hidden": false, "component": "monitor/druid/index", "meta": { "title": "数据监控", "icon": "druid", "noCache": false, "link": null } }, { "name": "Server", "path": "server", "hidden": false, "component": "monitor/server/index", "meta": { "title": "服务监控", "icon": "server", "noCache": false, "link": null } }, { "name": "Cache", "path": "cache", "hidden": false, "component": "monitor/cache/index", "meta": { "title": "缓存监控", "icon": "redis", "noCache": false, "link": null } }] }, { "name": "Tool", "path": "/tool", "hidden": false, "redirect": "noRedirect", "component": "Layout", "alwaysShow": true, "meta": { "title": "系统工具", "icon": "tool", "noCache": false, "link": null }, "children": [{ "name": "Build", "path": "build", "hidden": false, "component": "tool/build/index", "meta": { "title": "表单构建", "icon": "build", "noCache": false, "link": null } }, { "name": "Gen", "path": "gen", "hidden": false, "component": "tool/gen/index", "meta": { "title": "代码生成", "icon": "code", "noCache": false, "link": null } }, { "name": "Swagger", "path": "swagger", "hidden": false, "component": "tool/swagger/index", "meta": { "title": "系统接口", "icon": "swagger", "noCache": false, "link": null } }] }, { "name": "Http://ruoyi.vip", "path": "http://ruoyi.vip", "hidden": false, "component": "Layout", "meta": { "title": "若依官网", "icon": "guide", "noCache": false, "link": "http://ruoyi.vip" } }] }

分析其返回值                        ,可以看到        ,就是按照router的格式        ,将菜单数据进行了返回        。其中                        ,子菜单就以children属性                ,定义在了父菜单下面        。菜单名称        ,定义在了meta属性里面                        。

这样                        ,就根据用户权限获取了菜单路由信息                。下面                ,看这些信息是如何进行使用的        。

还回到Sidebar组件的这段代码: <sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path + index" :item="route" :base-path="route.path" />

可以看到,涉及到另一个自定义组件sidebar-item                        ,遍历菜单                        ,把获取到的路由信息传了过去,最终实现了菜单的展示和点击出现tab页面                        。具体实现不再详细解释                。

六                、自定义指令的应用

若依框架自定义了几个指令                ,下面看如何进行自定义指令和这几个指令的作用:

在directive包下                        ,进行了自定义指令。

重点看permissions相关的自定义指令                        。一个权限指令        ,一个角色指令                ,其实现思路就是根据Vuex中user的角色和权限数据                        ,判断是否有某个角色或者某个权限        ,从而判断是否有权限操作某个按钮                        。即菜单中按钮权限的判断        ,是通过自定义指令完成的。

七        、关于element-ui

在一个组件中                        ,有很多的标签                ,当是el-开头的时候        ,就是element-ui的标签                        ,可以根据官网查找对应属性的意思等                。不是以el开头的标签                ,可能是项目自定义的组件,也可能是第三方组件                        。具体的点进去一看便知        。

八                        、history模式与项目部署

前面讲到                        ,history模式下                        ,刷新浏览器,会报404                ,这里                        ,再说清楚一点                。

在开发环境中        ,即使使用history模式                ,刷新界面                        ,不会报404,但是项目打包部署到web服务器上后        ,再访问前端项目        ,再刷新界面                        ,会报404                ,这是为何呢?

个人理解        ,在开发环境中                        ,vue-cli自行解决了history刷新报404的问题                ,直接通过路由,定位到了相应的组件                        。但是项目部署到web服务器上后                        ,刷新界面                        ,浏览器中的url直接就发送到web服务器上了,服务器默认并不会处理路径                ,而是直接根据路径找资源                        ,找不到url的资源        ,所以就报404了        。

项目部署后                ,如何解决history模式的404问题呢?根据不同的web服务器                        ,进行简单的设置        ,就可以解决了        。

具体可参考:不同的历史模式

下面记录在nginx下部署vue项目的过程                        。

首先        ,在package.json中                        , 运行build命令                ,对项目进行打包                。

打包完成后        ,在项目根目录下                        ,会生成dist文件                ,dist文件里,打包好的文件                        ,有个index.html文件                        ,整个vue项目,就在这个单界面里展示        。

配置nginx服务器:

首先                ,配置nginx.config配置文件                        ,重点如下: server { listen 80; #nginx端口        ,也是前端项目访问的端口 server_name localhost;#nginx的ip                ,也是前端工程访问ip #charset koi8-r; #access_log logs/host.access.log main; location / { root "F:/java_structure/vue/RuoYi-Vue-master/ruoyi-ui/dist";#vue项目打包dist后的路径 index index.html index.htm;#这里配置index就行                        ,不用管 try_files $uri $uri/ /index.html;#解决history刷新报404问题        ,配置此项后刷新就不再报404了                        。 } #vue项目想后台发送请求的前缀                。在开发环境中        ,配置proxyTable可以进行代理转发。在nginx上                        ,在此进行代理转发配置 location ^~/prod-api { rewrite ^/prod-api/(.*)$ /$1 break; #此配置表明发送到后台的请求不带prod-api                ,将其自动去掉 proxy_pass http://localhost:8080; #后台服务器路径                        。此处需要注意        ,这里的后台服务器                        ,是为vue项目提供数据支撑的服务器                        。而上面配置的listen和server_name                ,是nginx的port和ip,也是前端项目的port和ip。解决history模式404的问题                        ,也是解决的nginx服务器返回的404的问题                        ,并不是解决后台项目返回的404的问题,这点一定要清楚                。 } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }

八                、统计图                ,报表使用

echarts可以和vue很好的配合使用                        ,此外        ,再提供一个很好的统计报表可视化插件库:Viser

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
php消息实时推送完整示例(phpcms推送失败怎么办) 云端存储服务器有哪些(云存储服务器的原理是什么)