还不懂VUE2的实战技巧,怎么让你同事崇拜你呢

203 阅读3分钟

这三个小技巧应该熟知:

  • 组件 : 全局组件注册
  • Vue权限控制 : 高精度全局权限控制
  • Render函数 : 拯救繁乱的template
  • 路由分区以及动态添加路由

「全局组件注册」

创建全局.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文件
})

使用globalComponents

// 2 - 将globalComponent.js引入main.js

import global from './components/globalComponent'

// 3 - 使用这类组件不再需要引入和注册,直接标签使用即可

「高精度全局权限处理」

开发中 - 处理一些按钮显示权限问题

这种场景出现几率极高,尤其是处理含有多种角色的项目,如果这一类型的权限判断有多次处理,每一次出现都经历判断的话,代码将会异常难看且冗余,因此我们可以通过全局权限判断来处理

/*
    在项目里新建一个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的值进行判断即可

「拯救繁乱的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,因此我们可以这样写

// 创建一个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等,就可以实现这一目的,而不需要去创建多个,通过v-if去判断

「路由分区以及动态添加路由」

总路由管理文件 - index.js

分区路由
- index.routes.js
- login.routes.js

在大型项目中,往往会有很多互不关联的模块,例如电商平台中的商城,个人信息,这种情况下就可以对路由进行分区

// 总路由管理文件 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

总结:这些方法看似简单,但运用起来能给我们的开发带来不小的便利,理解其中的理念去减少代码量,减少冗余,在合适的场景下使用合适的方法才能提高自己的能力