版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
vue-element-adminv4.4后台前端解决方案指南目\h基础\h介绍\h布局\h路由和侧边栏\h权限验证\h快捷导航(标签栏导航)\h新增页面\h样式\h和服务端进行交互\hMockData\h引入外部模块\h构建和发布\h环境变量\h进阶\h跨域问题\hESLint\hGitHooks\h风格指南\h路由懒加载\h图表\h图标\hCDN\h更换主题\h国际化\h错误处理\hebpack指南\hNodeSasstoartSass\h其它\h常见问题\h更新记录\h项目捐赠与字节跳动内推介绍vue2.6.10 eemn-i2.7.0 buildpassing eMIT ev4.4.0 $e\hvue-eleent-是一个后台前端解决方案,它基于\hvue和\helementui实现。它使用了最新的前端技术栈,内置了i18国际化解决方案,动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件,它可以帮助你快速搭建企业级中后台产品原型。相信不管你的需求是什么,本项目都能帮助到你。建议本项目的定位是后台集成方案,不太适合当基础模板来进行二次开发。因为本项目集成了很多你可能用不到的功能,会造成不少的代码冗余。如果你的项目不关注这方面的问题,也可以直接基于它进行二次开发。集成方案:\hvue-eleent-基础模板:\hvue-admn-teplate桌面终端:\helectro-vueadminTypescrpt版\hvue-typscrit-admin-temlate(鸣谢:\h@Armour)Others:\hawesomeprojct功能1.-登录/注销2.3.-权限验证4.-页面权限5.-指令权限6.-权限配置7.-二步登录8.9.-多环境发布10.-devsitstageprod11.12.-全局功能13.-国际化多语言14.-多种动态换肤15.-动态侧边栏(支持多级路由嵌套)16.-动态面包屑17.-快捷导航(标签页)18.-SvgSprite图标19.-本地/后端mock数据20.-Screenfull全屏 -5-介绍21.-自适应收缩侧边栏22.23.-编辑器24.-富文本25.-Markdown26.-JSON等多格式27.28.-Excel29.-导出excel30.-导入excel31.-前端可视化excel32.-导出zip33.34.-表格35.-动态表格36.-拖拽表格37.-内联编辑38.39.-错误页面40.-40141.-40442.43.-組件44.-头像上传45.-返回顶部46.-拖拽Dialog47.-拖拽Select48.-拖拽看板49.-列表拖拽50.-SplitPane51.-Dropzone52.-Sticky53.-CountTo54.55.-综合实例56.-错误日志57.-Dashboard58.-引导页59.-ECharts图表60.-Clipboard(剪贴复制)61.-Markdown2html前序准备你需要在本地安装\hnode和\hgit。本项目技术栈基于\hES2015+、\hvue、\hvuex\h、ve-ro\h、ve-cli\h、aios和\helementui,所有的请求数据都使\h用Mck.js进行模拟,提前了解和学习这些知识会对使用本项目有很大的帮助。同时配套一个系列的教程文章,如何从零构建一个完整的管理后台项目,建议大家先看完这些文章再来实践本项目。 -6-介绍\h手摸手,带你用vue撸后台系列一(基础篇)\h手摸手,带你用vue撸后台系列二(登录权限篇)\h手摸手,带你用vue撸后台系列三(实战篇)\h手摸手,带你用vue撸后台系列四(vueAmin一个极简的后台基础模板)\h手摸手,带你用vue撸后台系列五(v4.0新版本)\h手摸手,带你封装一个vuecompnent\h手摸手,带你优雅的使用icon\h手摸手,带你用合理的姿势使用weback4\h手摸手,带你用合理的姿势使用weback4本项目不支持低版本浏览器(如ie),有需求请自行添加polyill\h详情目录结构本项目已经为你生成了一个完整的开发框架,提供了涵盖中后台开发的各类功能和坑位,下面是整个项目的目录结构。1.├──build2.├──mock3.├──plop-templates4.├──public
#构建相关#项目mock模拟数据#基本模板#静态资源5.││──favicon.ico6.│└──index.html
#favicon图标#html模板7.├──src #源代码8.│├──api9.│├──assets10.│├──components11.│├──directive12.│├──filters13.│├──icons14.│├──lang15.│├──layout16.│├──router17.│├──store18.│├──styles19.│├──utils20.│├──vendor21.│├──views22.│├──App.vue23.│├──main.js24.│└──permission.js
#所有请求#主题字体等静态资源#全局公用组件#全局指令#全局filter#项目所有svgicons#国际化language#全局layout#路由#全局store管理#全局样式#全局公用方法#公用vendor#views所有页面#入口页面#入口文件加载组件初始化等#权限管理25.├──tests #测试 -7-介绍26.├──.env.xxx27.├──.eslintrc.js28.├──.babelrc29.├──.travis.yml30.├──vue.config.js31.├──postcss.config.js32.└──package.json
#环境变量配置#eslint配置项#babel-loader配置#自动化CI配置#vue-cli配置#postcss配置#package.json安装1.#克隆项目2.gitclone/PanJiaChen/vue-element-admin.git3.4.#进入项目目录5.cdvue-element-admin6.7.#安装依赖8.npminstall9.10.#建议不要用cnpm安装会有各种诡异的bug可以通过如下操作解决npm下载速度慢的问题11.npminstall--registry=12.13.#本地开发启动项目14.npmrundevTIP强烈建议不要用直接使用cnpm安装,会有各种诡异的bug,可以通过重新指定regstry来解决npm安装速度慢的问题。若还是不行,可使用\hyarn替代npm。Windows用户若安装不成功,很大概率是node-sass安装失败,\h解决方案另外因为node-sass是依赖python环境的,如果你之前没有安装和配置过的话,需要自行查看一下相关安装教程。启动完成后会自动打开浏览器访问\hhttp://ocalost:9527,你看到下面的页面就代表操作成功了。 -8-介绍接下来你可以修改代码进行业务开发了,本项目内建了典型业务模板、常用业务组件、模拟数据、实时预览、状态管理、国际化、全局路由等等各种实用的功能来辅助开发,你可以继续阅读和探索左侧的其它文档。建议你可以把vue-element-admin当做工具箱或者集成方案仓库,在vue-admin-template的基础上进行二次开发,想要什么功能或者组件就去vue-element-admin那里复制过来。Contribution本文档项目地址\hvue-eleent-dmin-site基于\hvuepress开发。有任何修改和建议都可以该项目pr和issue\hvue-eleent-还在持续迭代中,逐步沉淀和总结出更多功能和相应的实现代码,总结中后台产品模板/件/\h和反馈。捐赠如果你觉得这个项目帮助到了你,你可以帮作者买一杯果汁表示鼓励❤\hDonateBrowsersSupportModernbrosersandIntrnetExplorer10+. -9-介绍IE/EdgeIE10,IE11,Edge
Firefoxlast2versios
Chromelast2versios
Safarilast2versios其它群主\h圈子群主会经常分享一些技术相关的东西,或者加入\hqq群或者关注\h微博。Vue生态圈首先了解这些vue生态圈的东西,会对你上手本项目有很大的帮助。\hVueRouter是vue官方的路由。它能快速的帮助你构建一个单页面或者多页面的项目。\hVuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。它能解决你很多全局状态或者组件之间通信的问题。\hVueLoader是为vue文件定制的一个webpack的loaer,它允许你以一种名为单文件组件(SFCs)的格式撰写Vue组件。它能在开发过程中使用热重载来保持状态,为每个组件模拟出scopedCSS等等功能。不过大部分情况下你不需要对它直接进行配置,脚手架都帮你封装好了。\hVueTestUtils\hVueDev-Tols率。
是官方提供的一个单元测试工具。它能让你更方便的写单元测试。Vue在浏览器下的调试工具。写vue必备的一个浏览器插件,能大大的提高你调试的效\hVueCLI是官方提供的一个vue项目脚手架,本项目也是基于它进行构建的。它帮你封装了大量的webpack、等其它配置,让你能花更少的精力在搭建环境上,从而能更专注于页面代码的编写。不过所有的脚手架都是针对大部分情况的,所以一些特殊的需求还是需要自己进行配置。建议先阅读一遍它的文档,对一些配置有一些基本的了解。\hVetur是VSCode的插件.如果你使用VSCoe来写vue的话,这个插件是必不可少的。 -10-布局布局页面整体布局是一个产品最外层的框架结构,往往会包含导航、侧边栏、面包屑以及内容等。想要了解一个后台项目,先要了解它的基础布局。Layout对应代码\h@/layout@是webpack的\halias不懂得请自行研究vue-element-admin中大部分页面都是基于这个layout的,除了个别页面如:login,404,401等页面没有使用该layout。如果你想在一个项目中有多种不同的layout也是很方便的,只要在一级路由那里选择不同的layout组件就行。1.//Nolayout2.{3.path:'/401',4.component:()=>import('errorPage/401')5.}6.7.//Haslayout8.{9.path:'/documentation',10.11.//你可以选择不同的layout组件 --布局12.component:Layout,13.14.//这里开始对应的路由都会显示在app-main中如上图所示15.children:[{16. path:'index',17. component:()=>import('documentation/index'),18. name:'documentation'19.}]20.}这里使用了vue-router\h路由嵌套,所以一般情况下,你增加或者修改页面只会影响app-main这个主体区域。其它配置在layout中的内容如:侧边栏或者导航栏都是不会随着你主体页面变化而变化的。1./foo2.++
/bar++3.|layout | |layout |4.|++| |++|5.||foo.vue6.||
||+>||
||bar.vue |||| ||7.|++|8.++
|++|++当然你也可以一个项目里面使用多个不同的layout,只要在你想作用的路由父级上引用它就可以了。app-main对应代码\h@/layou/comonents/AppM这里在app-main外部包了一层keep-alive主要是为了缓存<router-view>的,配合页面的tabs-view标签导航使用,如不需要可自行去除其中transition定义了页面之间切换动画,可以根据自己的需求,自行修改转场动画。相关\h文档默认提供了fade和fade-transform两个转场动画,具体css实现见\htransiton.sss。如果需要调整可\h在ApMai.vue中调整transition的name。router-viewDifferetrouterthesaecomponentvue真实的业务场景中,这种情况很多。比如: -12-布局我创建编辑的页面使用的是同一个componnt发vue的created或者mounted钩子\h,官方说你可以通过watch$rute的变化来进行处理,但说真的还是蛮麻烦的。后来发现其实可以简单的在router-view上加上一个唯一的key,来保证路由切换时都会重新渲染触发钩子了。这样简单的多了。1.<router-view:key="key"></router-view>2.3.computed:{4.key(){5. //只要保证key唯一性就可以了,保证不同页面的key不相同6. returnthis.$route.fullPath7.}8.}TIP或者可以像本项目中editForm和createForm声明两个不同的view但引入同一个component。示例代码\h:@view/example1.<!--create.vue-->2.<template>3.<article-detail:is-edit='false'></article-detail>//create4.</template>5.<script>6.importArticleDetailfrom'./components/ArticleDetail'7.</script>8.9.<!--edit.vue-->10.<template>11. <article-detail:is-edit='true'></article-detail>//edit12.</template>13.<script>14.importArticleDetailfrom'./components/ArticleDetail'15.</script>移动端element-ui官方对自己的定位是桌面端后台框架,而且对于管理后台这种重交互的项目来说是不能通过简单的适配来满足桌面端和移动端两端不同的交互,所以真要做移动版后台,建议重新做一套系统。所以本项目也不会适配移动端,只是用mediaquery做了一点简单的响应式布局,有需求请自行修改。 -13-路由和侧边栏路由和侧边栏路由和侧边栏是组织起一个后台应用的关键骨架。本项目侧边栏和路由是绑定在一起的,所以你只有在@/router/index.js下面配置对应的路由,侧边栏就能动态的生成了。大大减轻了手动重复编辑侧边栏的工作量。当然这样就需要在配置路由的时候遵循一些约定的规则。配置项首先我们了解一下本项目配置路由时提供了哪些配置项。1.//当设置true的时候该路由不会在侧边栏出现如401,login等页面,或者如一些编辑页面/edit/12.hidden:true//(默认false)3.4.//当设置noRedirect的时候该路由在面包屑导航中不可被点击5.redirect:'noRedirect'6.7.//当你一个路由下面的children声明的路由大于1个时,自动会变成嵌套的模式--8.//只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面9.//若你想不管路由下面的children声明的个数都显示你的根路由10.//你可以设置alwaysShow:true,这样它就会忽略之前定义的规则,一直显示根路由11.alwaysShow:true12.13.name:'router-name'//设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题14.meta:{15.roles:['admin','editor']//设置该路由进入的权限,支持多个权限叠加16.title:'title'//设置该路由在侧边栏和面包屑中展示的名字17.icon:'svg-name'//设置该路由的图标,支持svg-class,也支持el-icon-xelement-ui的icon18.noCache:true//如果设置为true,则不会被<keep-alive>缓存(默认false)19.breadcrumb:false//如果设置为false,则不会在breadcrumb面包屑中显示(认true)20.affix:true//如果设置为true,它则会固定在tags-view中(默认false)21.22.//当路由设置了该属性,则会高亮相对应的侧边栏。23.//这在某些场景非常有用,比如:一个文章的列表页路由为:/article/list24.//点击文章进入文章详情页,这时候路由为/article/1,但你想在侧边栏高亮文章列表的路由,就可以进行如下设置25.activeMenu:'/article/list'26.}示例:1.{2.path:'/permission',3.component:Layout,4.redirect:'/permission/index',//重定向地址,在面包屑中点击会重定向去的地址5.hidden:true,//不在侧边栏显示6.alwaysShow:true,//一直显示根路由7.meta:{roles:['admin','editor']},//你可以在根路由设置权限,这样它下面所有的子路由都继承了这个权限8.children:[{ -14-路由和侧边栏9. path:'index',10. component:()=>import('permission/index'),11. name:'permission',12. meta:{13. title:'permission',14. icon:'lock',//图标15. roles:['admin','editor'],//或者你可以给每一个子路由设置自己的权限16. noCache:true//不会被<keep-alive>缓存17. }18.}]19.}路由这里的路由分为两种,constantRoutes和asyncRoutes。constans:代表那些不需要动态判断权限的路由,如登录页、404、等通用页面。asyncRo:代表那些需求动态判断权限并通过addRoutes动态添加的页面。具体的会在权限验证页面介绍。TIP这里所有的路由页面都使用路由懒加载了,具体介绍见文档如果你想了解更多关于browsrHis和hashHis,请参看构建和发布。其它的配置和\hvue-rouer官方并没有区别,自行查看文档。注意事项如果这里有一个需要非常注意的地方就是404页面一定要最后加载,如果放在consantRou一同声明了\h404,后面的所有页面都会被拦截到404,详细的问题见addRoteswhenyouvegotawildcad\hroutefor404sdoesnotwork侧边栏本项目侧边栏主要基于element-ui的el-menu改造。前面也介绍了,侧边栏是通过读取路由并结合权限判断而动态生成的,而且还需要支持路由无限嵌套,所以这里还使用到了递归组件。代码地址\h@/layou/comonents/Side -15-路由和侧边栏这里同时也改造了element-ui默认侧边栏不少的样式,所有的css都可以在\h@/style/sidbar.scss中找到,你也可以根据自己的需求进行修改。这里需要注意一下,一般侧边栏有两种形式即:submenu和直接el-menu-item。一个是嵌套子菜单,另一个则是直接一个链接。如下图:在Sidebar中已经帮你做了判断,当你一个路由下面的children声明的路由大于>1个时,自动会变成嵌套的模式。如果子路由正好等于一个就会默认将子路由作为根路由显示在侧边栏中,若不想这样,可以通过设置在根路由中设置alwaysShow:true来取消这一特性。如:1.//Nosubmenu,becausechildren.length===12.{3.path:'/icon',4.component:Layout,5.children:[{6. path:'index',7. component:()=>import('svg-icons/index'),8. name:'icons',9. meta:{title:'icons',icon:'icon'}10.}]11.},12.13.//Hassubmenu,becausechildren.length>=114.{15.path:'/components',16.component:Layout,17.name:'component-demo',18.meta:{19. title:'components',20. icon:'component'21.},22.children:[{path:'tinymce',component:()=>import('components-demo/tinymce'),name:'tinymce-demo',meta:{title:23.'tinymce'}},{path:'markdown',component:()=>import('components-demo/markdown'),name:'markdown-demo',meta:{24.title:'markdown'}},25.]26.}unique-pened你可以\h在S/index.vue中设置unique-opened来控制侧边栏,是否只保持一个子菜单的展开。 -16-路由和侧边栏多级目录(嵌套路由)如果你的路由是多级目录,如本项目\h@/viewsnest那样,有三级路由嵌套的情况下,不要忘记还要手动在二级目录的根文件下添加一个<router-view>。1.<!--父级路由组件-->2.<template>3.<div>4. <!--xxxhtml内容-->5. <router-view/>6.</div>7.</template>如:\h@/viewsnestd/menu1/ind,原则上有多少级路由嵌套就需要多少个<router-view>。点击侧边栏刷新当前路由在用sp(单页面应用)这种开发模式之前,用户每次点击侧边栏都会重新请求这个页面,用户渐渐养成了点击侧边栏当前路由来刷新view的习惯。但现在spa就不一样了,用户点击当前高亮的路由并不会刷新viwvue-rouer会拦截你的路由,它判断你的url并没有任何变化,所以它不会触发任何钩子或者是view的变化。\hissue地址,社区也对该问题展开了激烈讨论。 -17-路由和侧边栏尤大本来也说要增加一个方法来强刷vie,但后来他又改变了心意ㄒoㄒ)/~~就摆在这里,我们该怎么办呢?他说了不改变curretURL就不会触发任何东西,那我可不可以强行触发你的hook呢?上有政策,下有对策我们变着花来hack。方法也很简单,通过不断改变url的query来触发view的变化。我们监听侧边栏每个link的click事件,每次点击都给routerpush一个不一样的query来确保会重新刷新view。1.clickLink(path){2.this.$router.push({3. path,4. query:{5. t:+newDate()//保证每次点击路由的query项都是不一样的,确保会重新刷新6. }7.})8.}ps:不要忘了在router-view加上一个特定唯一的key,如<router-view:key="$route.path"></router-view>,但这也有一个弊端就是url后面有一个很难看的query后缀如/article/list?t=1496832345025你可以从前面的isue中知道还有很多其它方案。我本人在公司项目中,现在采取的方案是判断当前点击的菜单路由和当前的路由是否一致,若一致的时候,会先跳转到一个专门Redirect的页面,它会将路由重定向到我想去的页面,这样就起到了刷新的效果了。相关例子 -18-路由和侧边栏点击图片所示的全局size大小切换按钮,你会发现页面app-main区域进行了刷新。它就是运用了重定向到Redirect页面之后再重定向回原始页面的方法。点击的时候重定向页面至/redirect1.const{fullPath}=this.$route2.this.$router.replace({3.path:'/redirect'+fullPath4.})redirect页面在重定向回原始页面1.//redirect.vue2.///PanJiaChen/vue-element-admin/blob/master/src/views/redirect/index.vue3.exportdefault{4.beforeCreate(){5. const{params,query}=this.$route6. const{path}=params7. this.$router.replace({path:'/'+path,query})8.},9.render:function(h){10. returnh()//avoidwarningmessage11.}12.}面包屑本项目中也封装了一个面包屑导航,它也是通过watch$route变化动态生成的。它和menu也一样,也可以通过之前那些配置项控制一些路由在面包屑中的展现。大家也可以结合自己的业务需求增改这些自定义属性。比如可以在路由中声明breadcrumb:false,让其不在breacrumb面包屑显示。 -19-路由和侧边栏代码地址\h@/compoentsBreadcrumb侧边栏滚动问题之前版本的滚动都是用css来做处理的1.overflow-y:scroll;2.3.::-webkit-scrollbar{4.display:none;5.}首先这样写会有兼容性问题,在火狐或者其它低版本浏览器中都会比较不美观。其次在侧边栏收起的情况下,受限于element-ui的menu组件的实现方式,不能使用该方式来处理。所以现版本中使用了el-scrollbar来处理侧边栏滚动问题。代码地址\h@/layou/comonents/Side侧边栏外链v3.8.2+你也可以在侧边栏中配置一个外链,只要你在path中填写了合法的url路径,当你点击侧边栏的时候就会帮你新开这个页面。例如:1.{2."path":"external-link",3."component":Layout,4."children":[5. {6. "path":"/PanJiaChen/vue-element-admin",7. "meta":{"title":"externalLink","icon":"link"}8. }9.]10.}侧边栏默认展开 -20-路由和侧边栏某些场景下,用户需要默认展开侧边栏的某些sub-menu,如下图:可以通过default-openeds来进行设置,首先找到\h侧边栏代码1.<el-menu2. :default-openeds="['/example','/nested']"//添加本行代码3. :default-active="activeMenu" -21-路由和侧边栏4. :collapse="isCollapse"5. :background-color="variables.menuBg"6. :text-color="variables.menuText"7. :unique-opened="false"8. :active-text-color="variables.menuActiveText"9. :collapse-transition="false"10. mode="vertical"11. ><sidebar-itemv-for="routeinpermission_routes":key="route.path":item="route":base-12.path="route.path"/>13. </el-menu>注意:dfault-openes=”[/exampe’,’nested’]“里面填写的是submnu的route-p -22-权限验证权限验证在\h手摸手,带你用vue撸后台系列二(登录权限篇)这篇文章中其实已经详细介绍过了。该项目中权限的实现方式是:通过获取当前用户的权限去比对路由表,生成当前用户具有的权限可访问的路由表,通过router.addRoutes动态挂载到router上。但其实很多公司的业务逻辑可能不是这样的,举一个例子来说,很多公司的需求是每个页面的权限是动态配置的,不像本项目中是写死预设的。但其实原理是相同的。如:你可以在后台通过一个tree控件或者其它展现形式给每一个页面动态配置权限,之后将这份路由表存储到后端。当用户登录后得到roles,前端根据roles去向后端请求可访问的路由表,从而动态生成可访问页面,之后就是routr.addRutes动态挂载到rouer上,你会发现原理是相同的,万变不离其宗。只是多了一步将后端返回路由表和本地的组件映射到一起。相\h关isue1.constmap={2.login:require('login/index').default//同步的方式3.login:()=>import('login/index') //异步的方式4.}5.//你存在服务端的map类似于6.constserviceMap=[7.{path:'/login',component:'login',hidden:true}8.]9.//之后遍历这个map,动态生成asyncRoutes10.并将component替换为map[component]Ps:不排除之后本项目会增加权限控制面板支持真正的动态配置权限。逻辑修改现在路由层面权限的控制代码都在@/permission.js中,如果想修改逻辑,直接在适当的判断逻辑中next()释放钩子即可。指令权限封装了一个指令权限,能简单快速的实现按钮级别的权限判断。\hv-permision使用1.<template>2.<!--Admincanseethis-->3.<el-tagv-permission="['admin']">admin</el-tag>4.5.<!--Editorcanseethis--> -23-权限验证6.<el-tagv-permission="['editor']">editor</el-tag>7.8.<!--Editorcanseethis-->9.<el-tagv-permission="['admin','editor']">Bothadminoreditorcanseethis</el-tag>10.</template>11.12.<script>13.//当然你也可以为了方便使用,将它注册到全局14.importpermissionfrom'@/directive/permission/index.js'//权限判断指令15.exportdefault{16.directives:{permission}17.}18.</script>局限Insomecasesitisnotsuiabletousev-prmission,suchaselementTabcomonentwhichcanonlybeachevedbymanuallysetingthev-if.可以使用全局权限判断函数,用法和指令v-permission类似。1.<template>2.<el-tab-panev-if="checkPermission(['admin'])"label="Admin">Admincanseethis</el-tab-pane>3.<el-tab-panev-if="checkPermission(['editor'])"label="Editor">Editorcanseethis</el-tab-pane><el-tab-panev-if="checkPermission(['admin','editor'])"label="Admin-OR-Editor">Bothadminoreditorcansee4.this</el-tab-pane>5.</template>6.7.<script>8.importcheckPermissionfrom'@/utils/permission'//权限判断函数9.10.exportdefault{11. methods:{12. checkPermission13. }14.}15.</script> -24-快捷导航标签栏导航快捷导航本功能是响应大家需求,后期加上的,其实本人在公司项目或者个人项目中是不太使用该功能的。以前那些传统后台框架往往会包含此功能,由于以前的后台项目大部分都是多页面的形式,所以标签栏导航功能还是具有一定意义的,大部分都是基于if的方式实现的。但随着时代的发展,现在的后台项目几乎都是spa(siglepagewebaplication单页面开发)的方案来实现标签导航显然是不合适的。所以目前的方案大致为:运用keep-alive和router-view的结合。代码:@/layout/components/AppMain.vue1.<keep-alive:include="cachedViews">2.<router-view></router-view>3.</keep-alive>顶部标签栏导航实际作用相当于nav的另一种展现形式,其实说白了都是一个个roter-lik,点击跳转到相应的页面。然后我们再来监听路由$route的变化,来判断当前页面是否需要重新加载或者已被缓存。visitedViews&&cachedViews目前tags-view维护了两个数组。visitediews:用户访问过的页面就是标签栏导航显示的一个个tag数组集合cachedVews:实际keep-alive的路由。可以在配置路由的时候通过meta.noCache来设置是否需要缓存这个路由默认都缓存。配置文档注意事项由于目前keep-alive和router-view是强耦合的,而且查看文档和源码不难发现keep-alive的\hinclude默认是优先匹配组件的name,所以在编写路由router和路由对应的viewcomponent的时候一定要确保两者的name是完全一致的。(切记name命名时候尽量保证唯一性切记不要和某些组件的命名重复了,不然会递归引用最后内存溢出等问题)DEMO:1.//router路由声明2.{3.path:'create-form',4.component:()=>import('@/views/form/create'),5.name:'createForm',6.meta:{title:'createForm',icon:'table'}7.} -25-快捷导航标签栏导航1.//路由对应的viewform/create2.exportdefault{3.name:'createForm'4.}一定要保证两者的名字相同,切记写重或者写错。默认如果不写name就不会被缓存,详情\h见isue。缓存不适合场景目前缓存的方案对于某些业务是不适合的,比如文章详情页这种/article/1 /article/2,他们的路由不同但对应的组件却是一样的,所以他们的组件nae就是一样的,就如前面提到的,keep-alive的include只能根据组件名来进行缓存,所以这样就出问题了。目前有两种解决方案:不使用keep-alive的include功能,直接是用keep-aive缓存所有组件,这样子是支持前面所说的业务情况的。前\h往@t/componentain.vue文件下,移除include相关代码即可。当然直接使用keeve也是有弊端的,他并不能动态的删除缓存,你最多只能帮它设置一个最大缓存实例的个数limit\h。相关issue使用loc等浏览器缓存方案,自己进行缓存处理Affix固钉v3.10.0+当在声明路由是添加了Afix属性,则当前tag会被固定在tags-view中(不可被删除)。1.{2. path:'',3. component:Layout,4. redirect:'dashboard',5. children:[6. {7. path:'dashboard', -26-快捷导航标签栏导航8. component:()=>import('@/views/dashboard/index'),9. name:'Dashboard',10. meta:{11. title:'dashboard',12. icon:'dashboard',13. noCache:true,14. affix:true15. }16. }17. ]18.}移除其实kep-alive\h源码不复杂,但逻辑还是蛮绕的,之前尤大自己修复一个bug的时候也不小心搞错了,连发两个版本来修复,所以如果没有标签导航栏需求的用户,建议移除此功能。首先找到@/layout/components/AppMain.vue然后移除keep-alive1.<template>2.<sectionclass="app-main"style="min-height:100%">3. <transitionname="fade-transform"mode="out-in">4. <router-view></router-view>5. </transition>6.</section>7.</template>然后移除整个@/layout/components/TagsView.vue文件,并在@/layout/components/index和@/layout/Layout.vue移除相的依赖。最后把@/store/modules/tagsView相关的代码删除即可。 -27-新增页面新增页面如果熟悉vue-router的配置就很简单了。首先在@/router/index.js中增加你需要添加的路由。如:新增一个excel页面1.{2.path:'/excel',3.component:Layout,4.redirect:'/excel/export-excel',5.name:'excel',6.meta:{7. title:'excel',8. icon:'excel'9.}10.}TIP仅仅这样不会有任何效果的,它只是创建了一个基于layout的一级路由,你还需要在它下面的children中添加子路由。1.{2.path:'/excel',3.component:Layout,4.redirect:'/excel/export-excel',5.name:'excel',6.meta:{7. title:'excel',8. icon:'excel'9.},10.children:[11. {12. path:'export-excel',13. component:()=>import('excel/exportExcel'),14. name:'exportExcel',15. meta:{title:'exportExcel'}16. }17.]18.}这样侧边栏就会出现如图所示的menu-item了 -28-新增页面TIP由于children下面只声明了一个路由所以不会有展开箭头,如果children下面的路由个数大于1就会有展开箭头,如下面所示。如果你想忽视这个自动判断可以使用alwaysShow:true,这样它就会忽略之前定义的规则,一直显示根路由。详情见路由和侧边栏1.{2.path:'/excel',3.component:Layout,4.redirect:'/excel/export-excel',5.name:'excel',6.meta:{7. title:'excel',8. icon:'excel'9.},10.children:[{path:'export-excel',component:()=>import('excel/exportExcel'),name:'exportExcel',meta:{title:11.'exportExcel'}},{path:'export-selected-excel',component:()=>import('excel/selectExcel'),name:'selectExcel',meta:{12.title:'selectExcel'}},{path:'upload-excel',component:()=>import('excel/uploadExcel'),name:'uploadExcel',meta:{title:13.'uploadExcel'}}14.]15.}侧边栏就会出现如图所示的submenu了多级目录(嵌套路由)如果你的路由是多级目录,如本项目\h@/viewsnest那样,有三级路由嵌套的情况下,不要忘记还要手动在二级目录的根文件下添加一个<router-view>。1.<!--父级路由组件-->2.<template>3.<div>4. <!--xxxhtml内容-->5. <router-view/>6.</div> -29-新增页面7.</template>如\h:@/nested/menex.vue,原则上有多少级路由嵌套就需要多少个<router-view>。新增view新增完路由之后不要忘记在@/views文件下创建对应的文件夹,一般一个路由对应一个文件,该模块下的功能组件或者方法就建议在本文件夹下创建一个utils或components文件夹,各个功能模块维护自己的utils或components组件。如:新增api最后在\h@/api文件夹下创建本模块对应的api服务。新增组件个人写vue项目的习惯,在全局的@/components只会写一些全局的组件,如富文本,各种搜索组件,封装的日期组件等等能被公用的组件。每个页面或者模块特定的业务组件则会写在当前views下面。如:@/views/article/components/xxx.vue。这样拆分大大减轻了维护成本。请记住拆分组件最大的好处不是公用而是可维护性! -30-新增页面新增样式页面的样式和组件是一个道理,全局的@/style放置一下全局公用的样式,每一个页面的样式就写在当前views下面,请记住加上scoped或者命名空间,避免造成全局的样式污染。1.<style>2./*globalstyles*/3.</style>4.5.<stylescoped>6./*localstyles*/7..xxx-container{8./*namescoped*/9.xxx10.}11.</style> -31-样式样式CSSModules在样式开发过程中,有两个问题比较突出:全局污染——CSS文件中的选择器是全局生效的,不同文件中的同名选择器,根据buid后生成文件中的先后顺序,后面的样式会将前面的覆盖;选择器复杂——为了避免上面的问题,我们在编写样式的时候不得不小心翼翼,类名里会带上限制范围的标示,变得越来越长,多人开发时还很容易导致命名风格混乱,一个元素上使用的选择器个数也可能越来越多,最终导致难以维护。好在vue为我们提供了\hscoped可以很方便的解决上述问题。它顾名思义给css加了一个域的概念。1./*编译前*/2..example{3.color:red;4.}5.6./*编译后*/7..example[_v-f3f3eg9]{8.color:red;9.}只要加上<stylescoped>这样css就只会作用在当前组件内了。详细文档见\hvue-loaerTIP使用scoped后,父组件的样式将不会渗透到子组件中。不过一个子组件的根节点会同时受其父组件的scpedCSS和子组件的scopedCSS的影响。这样设计是为了让父组件可以从布局的角度出发,调整其子组件根元素的样式。目录结构vue-eleent-所有全局样式都在@/styles下设置1.├──styles2.│├──btn.scss3.│├──element-ui.scss4.│├──index.scss5.│├──mixin.scss6.│├──sidebar.scss7.│├──transition.scss8.│└──variables.scss
#按钮样式#全局自定义element-ui样式#全局通用样式#全局mixin#sidebarcss#vuetransition动画#全局变量 -32-样式常见的工作流程是,全局样式都写在src/styles目录下,每个页面自己对应的样式都写在自己的.vue文件之中1.<style>2./*globalstyles*/3.</style>4.5.<stylescoped>6./*localstyles*/7.</style>自定义element-ui样式现在我们来说说怎么覆盖elemnt-ui样式。由于elment-ui的样式我们是在全局引入的,所以你想在某个页面里面覆盖它的样式就不能加scopd的element样式,你就可在它的父级加一个class,用命名空间来解决问题。1..article{2./*你的命名空间*/3..el-tag{4. /*element-ui元素*/5. margin-right:0px;6.}7.}当然也可以使用深度作用选择器下文会介绍父组件改变子组件样式深度选择器当你子组件使用了scoped但在父组件又想修改子组件的样式可以通过>>>来实现:1.<stylescoped>2..a>>>.b{/*...*/}3.</style>将会编译成1..a[data-v-f3f3eg9].b{2./*...*/3.}如果你使用了一些预处理的东西,如sass你可以通过/deep/来代替>>>实现想要的效果。所以你想覆盖某个特定页面element的button的样式,你可以这样做: -33-样式1..xxx-container>>>.el-button{2.xxxx3.}\h官方文档Autoprefixer[新版本已无该问题]vue-cli有一个小坑,它默认autoprfixer只会对通过vue-loader引入的样式才会有有作用,换而言之也就是.ve文件里面的cssautopreixer才会效果。相关问题\hissues/44,\hissues/00。解决方案也很简单粗暴1.//app.vue2.<stylelang="scss">3.@import'./styles/index.scss';//全局自定义的css样式4.</style>你在.ve文件中引入你要的样式就可以了,或者你可以改变vue-cli的文件在css-loader前面在加一个postcssloadr,在前面的issue地址中已经给出了解决方案。不过新版本已经默认解决处理了这个问题。Postcss这里再来说一下pstcss的配置问题,新版的\hvue-cliwepack模板init之后根目录下默认有一个postcss.config.js。vueloadr的postcss会默认读取这个文件的里的配置项,所以在这里直接改配置文件就可以了。配置和\hpostcss是一样的。1.//postcss.config.js2.module.exports={3.plugins:{4. autoprefixer:{}5.}6.}7.8.//package.json9."browserslist":[10. ">1%",11. "last2versions",12. "notie<=8"13.]如上面代码所述的,auer会去读取packag.json下browserslst的配置参数>1%兼容全球使用率大于1%的浏览器last2versions兼容每个浏览器的最近两个版本 -34-样式notie<=8不兼容ie8及以下具体可见\hbrowserlistpostcss也还有很多很多其它的功能大家可以\h自行去探究Mixin本项目没有设置自动注入sass的mixin到全局,所以需要在使用的地方手动引入mixn1.<stylerel="stylesheet/scss"lang="scss">2.@import"src/styles/mixin.scss";3.</style>如需要自动将mixin注入到全局,可以使用\hsass-reourcs-loader -35-和服务端进行交互和服务端进行交互前端请求流程在vue-element-admin中,一个完整的前端UI交互到服务端处理流程是这样的:UI组件交互操作;调用统一管理的apiservie请求函数;使用封装的reques.js发送请求;获取服务端返回;更新data;从上面的流程可以看出,为了方便管理维护,统一的请求处理都放在@/api文件夹中,并且一般按照model纬度进行拆分文件,如:1.api/2.login.js3.article.js4.remoteSearch.js5....request.js其中,@/utils/request.js是基于\haxios的封装,便于统一处理POS,GET等请求参数,请求头,以及错误提示信息等。具体可以参看\hrequestjs。它封装了全局request拦截器、response拦截器统一的错误处理统一做了超时处理、baseURL设置等。一个请求文章列表页的例子:1.//api/article.js2.importrequestfrom'../utils/request';3.exportfunctionfetchList(query){4.returnrequest({5. url:'/article/list',6. method:'get',7. params:query8.})9.}10.11.12.//views/example/list13.import{fetchList}from'@/api/article'14.exportdefault{ -36-和服务端进行交互15.data(){16. list:null,17. listLoading:true18.},19.methods:{20. fetchData(){21. this.listLoading=true22. fetchList().then(response=>{23. this.list=response.data.items24. this.listLoading=false25. })26. }27.}28.}设置多个baseURL我们可以通过环境变量baseURL,从而请求不同的api地址。1.#.env.development2.VUE_APP_BASE_API='/dev-api'#注入本地api的根路径3.VUE_APP_BASE_API2='/dev-api2'#注入本地api2的根路径之后根据环境变量创建axios实例,让它具有不同的baseURL。\h@/utilsrequst.js1.//createanaxiosinstance2.constservice=axios.create({3.baseURL:process.env.BASE_API,//api的base_url4.timeout:5000//requesttimeout5.})6.7.constservice2=axios.create({8.baseURL:process.env.BASE_API2,//api2的base_url9.timeout:5000//requesttimeout10.})或者1.exportfunctionfetchList(query){2.returnrequest({3. url:'/article/list',4. method:'get',5. params:query,6. baseURL:'xxxx'//直接通过覆盖的方式7.})8.} -37-和服务端进行交互从mock直接切换到服务端请求见Mock和联调 -38-MockDaaMockDataMock数据是前端开发过程中必不可少的一环,是分离前后端开发的关键链路。通过预先跟服务器端约定好的接口,模拟请求数据甚至逻辑,能够让前端开发更加独立自主,不会被服务端的开发所阻塞。Swagger在公司的项目中通常使用\hswagger,由后端来模拟业务数据。swager是一个RESTAPIs文档生成工具,\h它从代码注释中自动生成文档,可以跨平台,开源,支持大部分语言,社区好,总之非常不错,强烈推荐。线上\hdemoEasy-Mock\hvue-admn-teplate之前使用的是\heasy-mok来模拟数据。它是一个纯前端可视化,并且能快速生成模拟数据的持久化服务。非常的简单易用还能结合swagger,天然支持跨域,不管团队还是个人项目都值得一试。WARNING现在线上版本的vue-admin-template已经不使用easy-mock。因为easy-mock提供的线上免费服务很不稳定,时不时的就会挂掉,如果有需要的可以自己按照它的教程,搭建自己的服务。Mockjs由于\hvue-eleent-是一个纯前端个人项目,所有的数据都是用\hmockjs模拟生成。它的原理是:拦截了所有的请求并代理到本地,然后进行数据模拟,所以你会发现network中没有发出任何的请求。但它的最大的问题是就是它的实现机制。它会重写浏览器的XMLHttpRequest对象,从而才能拦截所有请求,代理到本地。大部分情况下用起来还是蛮方便的,但就因为它重写了XMLHttpRequest对象,所以比如progress方法,或者一些底层依赖XMLHttpRequest的库都会和它发生不兼容,可以看一下我项目的\hissues,就知道多少人被坑了。它还有一个问题是,因为是它本地模拟的数据,实际上不会走任何网络请求。所以本地调试起来很蛋疼,只能通过console.log来调试。就拿vue-element-admin来说,想搞清楚getInfo()接口返回了什么数据,只能通过看源码或者手动Debug才能知道。新方案v4.0.0+在v4.0版本之后,在本地会启动一个mock-server来模拟数据,线上环境还是继续使用mockjs来进行模拟(因为本项目是一个纯前端项目,你也可以自己搭建一个线上servr来提供数据)都是基于mockjs生成的,所以只要写一套mok数据,就可以在多环境中使用。 -39-MockDaa该方案的好处是,在保留mockjs的优势的同时,解决之前的痛点。由于我们的mok是完全基于webpack-dev-serve来实现的,所以在你启动前端服务的同时,mock-server就会自动启动,而且这里还通过\hchokidar来观察mock文件夹内容的变化。在发生变化时会清除之前注册的mock-api接口,重新动态挂载新的接口,从而支持热更新。有兴趣的可以自己看一下代\h码mrver.js。由于是一个真正的server,所以你可以通过控制台中的network,清楚的知道接口返回的数据结构。并且同时解决了之前mockjs会重写XMLHttpRequest对象,导致很多第三方库失效的问题。本项目的所有请求都是通过封装\h的rques进行发送的,通过阅读源码可以发现所有的请求都设置了一个baseURL,而这个baseURL又是通过读取process.env.VUE_APP_BASE_API这个环境变量来动态设置的,这样方便我们做到不同环境使用不同的api地址。移除如果你不想使用mock-servr的话只要在\hvue.conig.js中移除webpack-dev-server中proxy和after这个Middleware就可以了。现在默认情况下本地的请求会代理到http://localhost:${port}/mock下,如果你想调整为自己的mock地址可以修改proxy1.proxy:{2.//changexxx-api/login=>mock/login3.//detail:/config/#devserver-proxy4.[process.env.VUE_APP_BASE_API]:{5. target:`http://localhost:${port}/mock`,6. changeOrigin:true,7. pathRewrite:{8. ['^'+process.env.VUE_APP_BASE_API]:''9. }10.}11.},12.after:require('./m
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- UC矩阵试题与答案分享
- 汽修初级专项试题及答案
- 腹腔镜手术术前的护理和术后的观察要点
- 教育咨询基础试题与答案梳理
- 大学逻辑期末试题及答案分享
- OOS培训检验试题及答案分析
- PLC原理及应用测验试题及答案
- 护理人员技能提升培训成果
- DN600顶管及牵引管工程施工方案
- 2026病毒性肝炎诊治试题及答案
- 2026浙江金华市自然资源和规划局婺城分局招聘编外人员1人考试备考试题及答案详解
- 2026年高处作业企业员工安全培训考试题及答案
- 2026中国银行消防安全专项社会招聘备考题库含答案详解【培优】
- 化工园区公共管廊钢结构工程竣工验收报告
- 固态聚合物锂离子电池项目可行性研究报告
- 2026年贵州省、市两级机关公开遴选公务员考试(公共科目)综合能力测试题及答案
- 倍智tas人才测评系统题库及答案
- 2026年医院抗菌药物临床应用管理试题
- 2026年一级建造师(港口与航道工程)模拟考试题及答案
- 抗日战争胜利纪念日
- 2024年黎明职业大学辅导员考试笔试真题汇编附答案
评论
0/150
提交评论