vue的高級(jí)實(shí)戰(zhàn)技巧

今天從四個(gè)方面給大家分享一下vue的實(shí)戰(zhàn)技巧
1.全局組件注冊(cè)
2.render函數(shù)拯救繁亂的template
3.vue權(quán)限控制
4.路由的優(yōu)化
下面我們開(kāi)始吧!

全局組件注冊(cè)

先看看我們平時(shí)注冊(cè)組件是如何做的


微信圖片_20191018153204.png

當(dāng)我們需要在HelloWorld里面引入child1和child2的時(shí)候,我們一般先通過(guò)import導(dǎo)入這兩個(gè)文件,然后通過(guò)components注冊(cè),這樣就能使用了,這只是在一個(gè)文件里面引入,如果還有別的文件也需要引入,我們又得這樣重復(fù)一遍,或者說(shuō)如果HelloWorld還需要引入幾十個(gè)組件,按照這個(gè)寫法會(huì)顯得非常的繁瑣而且低效,那怎么寫才能更高效呢?且看下面:


微信圖片_20191018153929.png

首先我們?cè)谂c組件同級(jí)的地方新建一個(gè)golbal.js,這個(gè)js的作用就是幫助我們?nèi)纸M件注冊(cè),其中require.context它是一個(gè)webpack的api,通過(guò)執(zhí)行require.context函數(shù)獲取一個(gè)特定的上下文,主要用來(lái)實(shí)現(xiàn)自動(dòng)化導(dǎo)入模塊,它接收三個(gè)參數(shù):
1.directory {String} -讀取文件的路徑
2.useSubdirectories {Boolean} -是否遍歷文件的子目錄
3.regExp {RegExp} -匹配文件的正則

requireComponent.keys()獲取到的是一個(gè)數(shù)組,
微信圖片_20191021111704.png

接著匹配 / 和.vue中間的字符串并且用過(guò)changeStr()方法將首字符轉(zhuǎn)換為大寫,這個(gè)得到的就是我們需要的組件名稱。最后通過(guò)Vue.component()方法注冊(cè)
注意:哪些組件可以全局注冊(cè)?如果只是用到一次兩次的可以不需要注冊(cè)為全局的,如果是頻繁使用的,比如彈窗,提示語(yǔ)在很多頁(yè)面都會(huì)用到,這種情況下就可以使用全局注冊(cè)了。

最后還有一點(diǎn),需要在main.js里面進(jìn)入global.js

render函數(shù)拯救繁亂的template

因?yàn)閠emplate存在一值多判的情況,這樣就會(huì)導(dǎo)致代碼冗余,代碼雜亂的結(jié)果,這種時(shí)候就可以使用render函數(shù)來(lái)優(yōu)化,我們先看下一值多判的情況:

<template>
  <div v-if="value === 1">
    <button>按鈕1</button>
  </div>
<div v-if="value === 2">
    <button>按鈕1</button>
  </div>
<div v-if="value === 3">
    <button>按鈕1</button>
  </div>
</template>

那么我們?nèi)绾问褂胷ender來(lái)優(yōu)化呢?
首先父組件

<template>
  <div id="app">
    <Button 
      :type="type"
      :text="text"
      @myEvent="myDemo">
    </Button>
  </div>
</template>

<script>
import Button from './button'
export default {
  name: 'App',
  data(){
    return{
      type:'danger',
      text:1
    }
  },
  compontents:{Button},
  methods:{
    myDemo(){
      console.log(111)
    }
  }
}
</script>

render組件:

<script>
export default {
  name: 'Button',
  props:{
    type:{
      type:String,
      defalut:'normal'
    },
    text:{
      type:String,
      defalut:'normal'
    }
  },
  render(h){
    return h('button',{
      //v-bind:class
      class:{
        'btn':true,
        'btn-success': this.type === 'success',
        'btn-danger': this.type === 'danger',
        'btn-warning': this.type === 'warning',
        'normal' : !this.type
      },
      //dom
      domprops:{
        innerText: this.text || '默認(rèn)'
      },
      on:{
        click: handleClck
      }
    })
  },
  methods:{
    handleClck(){
      this.$emit('myEvent')
    }
  }
}
</script>

<style>
.btn {
  width: 100px;
  height: 40px;
  line-height: 40px;
  color: #ffffff;
}
.btn-success {
  background: green;
}
.btn-danger {
  background: red;
}
.btn-warning {
  background: orange;
}
.btn-normal {
  background: gray;
}
</style>

vue權(quán)限控制

當(dāng)我們需要根據(jù)某些特殊的權(quán)限對(duì)應(yīng)顯示頁(yè)面的操作的時(shí)候,一般情況下我們是這樣寫

<template>
  <div id="app">
    <div v-show="isShow">
      <div>我是權(quán)限1</div>
    </div>
    <div>
      <div>我是權(quán)限2</div>
    </div>
    <div>
      <div>我是權(quán)限3</div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'App',
  data(){
    return {
      isShow:false
    }
  }
}
</script>

這種寫法存在安全問(wèn)題,現(xiàn)在我們可以寫一個(gè)全局的權(quán)限控制指令
首先我們新建一個(gè)array.js

export function checkArray(key){
    //權(quán)限數(shù)組
    let arr = ['1','2','3',5];
    let index = arr.indexOf(key);
    if(index > -1){
        return
    } else {
        return false
    }
}

然后在main.js里面引入這個(gè)方法,并寫一個(gè)指令

import {checkArray} from './assets/common/array.js'
Vue.config.productionTip = false
Vue.directive('display-key',{
  inserted(el,binding){
    let displayKey = binding.value;
    if(displayKey){
      let hasPermission = checkArray(displayKey);
      //如果沒(méi)有權(quán)限則刪除dom
      if(!hasPermission){
        el.parentNode && el.parentNode.removeChild(el);
      }
    } else {
      throw new Error('需要傳key')
    }
  }
})

最后在dom里面使用自定義指令

<div v-display-key="'1'">
  <div>我是權(quán)限1</div>
 </div>

路由引入優(yōu)化

通常情況下我們的router.js是這樣的

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
Vue.use(Router)
export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    }
  ]
})

這只是一個(gè)路由,如果有幾十個(gè)甚至上百個(gè)呢,再使用這樣的寫法會(huì)顯得太凌亂,并且很不好維護(hù),接下來(lái)我們可以優(yōu)化下
router.js

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
Vue.use(Router)

//重點(diǎn)
const routerList = [];
function importAll(r){
  r.keys().forEach(
    (key) => routerList.push(r(key).default)
  );
}
importAll(require.context('.',true,/\.router\.js/));
export default new Router({
  routes: [
    ...routerList,
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    }
  ]
})

項(xiàng)目目錄結(jié)構(gòu)


WechatIMG456.jpeg

以上就是vue的一些實(shí)戰(zhàn)技巧,也可以說(shuō)是優(yōu)化技巧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容