在你们都会用vue
的时代,咱们又如何去区别是新手小白仍是资深vue
玩家呢? 如何让本身与刚学vue
的人拉开差距呢? 其实,不少人对于vue
只停留在基础使用。想要提高本身,就应该想办法将其运用到更高的层次。前端
vue
的运用能力
组件
: 全局组件注册Render函数
: 拯救繁乱的templateVue权限控制
: 高精度全局权限控制组件是咱们很是经常使用的东西,不少人使用组件都是经过一个一个文件去引用和注册。若是一个组件在整个项目里面的使用次数较多,每一次使用都须要引用并注册,就会显得特别麻烦vue
<template> <div> <h1>I am HelloWorld</h1> <Child1></Child1> </div> </template> <script> import Child1 from './child1.vue' // 引入 export default { name: 'HelloWorld', data(){ return{ } }, components:{ // 注册 Child1 }, props: { msg: String }, methods:{ } } </script> <style scoped lang="less"> </style> 复制代码
当咱们在项目须要重复屡次使用该组件,会致使出现不少重复的引入和注册代码,既繁琐又不雅观。所以咱们能够经过一个全局的Js
文件来管理,将须要屡次使用的组件进行全局注册vue-router
.js
文件管理全局组件// 1 - globalComponent.js import Vue from 'vue' // 引入vue // 处理首字母大写 abc => Abc function changeStr(str){ return str.charAt(0).toUpperCase() + str.slice(1) } /* require.context(arg1,arg2,arg3) arg1 - 读取文件的路径 arg2 - 是否遍历文件的子目录 arg3 - 匹配文件的正则 关于这个Api的用法,建议小伙伴们去查阅一下,用途也比较普遍 */ const requireComponent = require.context('.', false, /\.vue$/) console.log('requireComponent.keys():',requireComponent.keys()) // 打印 requireComponent.keys().forEach(fileName => { const config = requireComponent(fileName) console.log('config:',config) // 打印 const componentName = changeStr( fileName.replace(/^\.\//, '').replace(/\.\w+$/, '') // ./child1.vue => child1 ) Vue.component(componentName, config.default || config) // 动态注册该目录下的全部.vue文件 }) 复制代码
// 2 - 将globalComponent.js引入main.js import global from './components/globalComponent' 复制代码
// 3 - 使用这类组件再也不须要引入和注册,直接标签使用便可
<template>
<div>
<h1>I am HelloWorld</h1>
<Child1></Child1>
</div>
</template>
复制代码
运行程序,咱们看下是否可以正常显示并分析两句打印数组
假设咱们有不少路由,每个路由都经过傻瓜式的引入方式,会致使整个项目代码量增多,繁琐,更重要的一点是增长后期维护的难度。所以咱们也能够经过上面相似的方式,对路由的引入和使用进行管理,实现分区引入路由,将不一样功能下的路由进行区分,经过动态的方式进行引入,即方便快捷又增长可维护bash
.js
文件管理全部的路由总路由管理文件 - index.js
分区路由
- index.routes.js
- login.routes.js
在大型项目中,每每会有不少互不关联的模块,例如电商平台中的商城,我的信息,这种状况下就能够对路由进行分区
复制代码
// 分区路由文件写法 export default { path:'/index', name:'Index', component: () => import('../views/Index.vue'), // 懒加载式引入,当跳转到时才进行引入chunk children: [...] } 复制代码
// 总路由管理文件 index.js 写法 import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const routerList = [] // 路由数组 - 存放全部路由 function importAll(routerArr){ // 该函数用于将全部分区路由中的路由添加到路由数组 routerArr.keys().forEach( key => { console.log(key) routerList.push(routerArr(key).default) }) } importAll(require.context('.',true,/\.routes\.js/)) const routes = [ ...routerList ] const router = new VueRouter({ routes }) export default router 复制代码
运行程序,咱们看下是否可以正常显示并分析两句打印markdown
优化以后的代码,会更灵活,更具备观赏性,既便捷高效,又方便维护less
不少人在写组件的时候,会依赖脚手架中的<template></template>
标签,其实template
也存在必定的缺陷,例如:dom
template
里存在一值多判断template
会使代码冗余,杂乱
VUE
给咱们提供了一个render
函数,咱们能够经过这个函数巧妙的解决template
形成的问题函数
<template> <div> <h1>I am Home</h1> <!-- 假设按钮有多种类型,经过value来显示不一样类型 --> <div v-if='value === 1'> <button>button1</button> </div> <div v-else-if='value === 2'> <button>button2</button> </div> <div v-else> <button>button3</button> </div> </div> </template> <script> export default { name: 'Home', data(){ return{ value:1 } }, methods:{ } } </script> <style scoped lang="less"> </style> 复制代码
上面这种写法,当出现多种类型的button,就会显得杂乱无章,固然,不少人会选择去封装一个button组件,那么这个组件的封装,又是一个技巧点,利用VUE
的render
函数,减小没必要要的template
,所以ru咱们能够这样写优化
// 建立一个button.vue文件 写法以下 <script> export default { props:{ type:{ type:String, default:'normal' }, text:{ type:String, default:'button' } }, render(h){ /* h 相似于 createElement, 接受2个参数 1 - 元素 2 - 选项 */ return h('button',{ // 至关于 v-bind:class class:{ btn:true, 'btn-success':this.type === 'success', 'btn-danger':this.type === 'danger', 'btn-warning':this.type === 'warning', 'btn-normal':this.type === 'normal', }, domProps:{ innerText: this.text || '默认' }, on:{ click:this.handleClick } }) }, methods:{ handleClick(){ this.$emit('myClick') } } } </script> <style scoped> .btn{ width: 100px; height:40px; line-height:40px; border:0px; border-radius:5px; color:#ffff; } .btn-success{ background:#2ecc71; } .btn-danger{ background:#e74c3c; } .btn-warning{ background:#f39c12; } .btn-normal{ background:#bdc3c7; } </style> 复制代码
// 引入 <template> <div> <h1>I am Home</h1> <!-- 按钮根据value显示不一样类型的button --> <Button type='success' text='button1' @myClick='...'></Button> </div> </template> <script> import Button from './button.vue' export default { name: 'Home', data(){ return{ value:1 } }, components:{ Button }, methods:{ } } </script> <style scoped lang="less"> </style> 复制代码
上面这种写法,根据value
来显示不一样类型的button
,咱们只须要经过value
去修改type,text
等,就能够实现这一目的,而不须要去建立多个<button>
,经过v-if
去判断
优化以后的代码,避免了一值多判断的缺点,减小冗余,更加灵活, 这种方式较适合业务简单,使用次数多的组件
权限的控制由前端处理的场景不少,例如根据后台返回内容,判断该人是否对此功能有权限,进而去修改元素
v-if / v-show
,这种状况下,当这个功能在多处地方出现,就会致使咱们作不少不少没必要要的重复代码,若是判断条件繁琐的状况,更加冗余,代码量也会增长不少。所以咱们能够造一个小车轮,挂在全局上对权限进行处理
这种场景出现概率极高,尤为是处理含有多种角色的项目,若是这一类型的权限判断有屡次处理,每一次出现都经历判断的话,代码将会异常难看且冗余,所以咱们能够经过全局权限判断来处理
/* 在项目里新建一个common文件夹用于存放全局 .js 文件 这种全局文件夹作法至关广泛,通常项目里都应该有这样一个文件夹来管理全局的东西 */ // common/jurisdiction.js 用于存放与权限相关的全局函数/变量 export function checkJurisdiction(key) { // 权限数组 let jurisdictionList = ['1', '2', '3', '5'] let index = jurisdictionList.indexOf(key) console.log('index:',index) if (index > -1) { // 有权限 return true } else { // 无权限 return false } } 复制代码
// 将全局权限Js挂载到全局中 // main.js import { checkJurisdiction } from './common/jurisdiction' // 优雅操做 - VUE自定义指令 Vue.directive('permission',{ inserted(el, binding){ // inserted → 元素插入的时候 let permission = binding.value // 获取到 v-permission的值 if(permission){ let hasPermission = checkJurisdiction(permission) if(!hasPermission){ // 没有权限 移除Dom元素 el.parentNode && el.parentNode.removeChild(el) } }else{ throw new Error('须要传key') } } }) 复制代码
// 使用方式 <template> <div> <h1>I am Home</h1> <!-- 按钮根据value --> <div v-permission="'10'"> <button>权限1</button> </div> <div v-permission="'5'"> <button>权限2</button> </div> </div> </template> // 无需再经过value去判断,直接经过v-permission的值进行判断便可 复制代码
运行程序,咱们看下是否可以正常显示并分析打印
v-permission = "'10'"
是没有权限且不显示,
v-permission = "'5'"
是具备权限且显示
以上三个方面操做起来看似简单,但不少人在写代码的时候,喜欢停留在业务上,只考虑可否实现,实际上,不少大型项目都须要有这些理念去减小代码量,减小冗余,在合适的场景下使用合适的方法才能提升本身的能力
❗ Tips: 若是文章有错误的地方,但愿指出,以为有用的小伙伴点个赞哦 QAQ