在我們開發(fā)過程中,有些處理起來非常麻煩的小功能,用自定義指令可能非常簡單就能實現(xiàn)。首先看下vue官網(wǎng)關于自定義指令的介紹:
簡介
除了核心功能默認內(nèi)置的指令 (v-model 和 v-show),Vue 也允許注冊自定義指令。注意,在 Vue2.0 中,代碼復用和抽象的主要形式是組件。然而,有的情況下,你仍然需要對普通 DOM 元素進行底層操作,這時候就會用到自定義指令。舉個聚焦輸入框的例子。
當頁面加載時,該元素將獲得焦點。只要你在打開這個頁面后還沒點擊過任何內(nèi)容,這個輸入框就應當還是處于聚焦狀態(tài)?,F(xiàn)在讓我們用指令來實現(xiàn)這個功能:
基礎用法
// 注冊一個全局自定義指令 `v-focus`
Vue.directive('focus', {
// 當被綁定的元素插入到 DOM 中時……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
// template
<input v-focus>
除了可以在vue的全局注冊全局的自定義指令,vue也支持在組件內(nèi)注冊組建的自定義指令。
鉤子函數(shù)
一個指令定義對象可以提供如下幾個鉤子函數(shù) (均為可選):
bind:只調(diào)用一次,指令第一次綁定到元素時調(diào)用。在這里可以進行一次性的初始化設置。
inserted:被綁定元素插入父節(jié)點時調(diào)用 (僅保證父節(jié)點存在,但不一定已被插入文檔中)。
update:所在組件的 VNode 更新時調(diào)用,但是可能發(fā)生在其子 VNode 更新之前。指令的值可能發(fā)生了改變,也可能沒有。但是你可以通過比較更新前后的值來忽略不必要的模板更新 (詳細的鉤子函數(shù)參數(shù)見下)。
componentUpdated:指令所在組件的 VNode 及其子 VNode 全部更新后調(diào)用。
unbind:只調(diào)用一次,指令與元素解綁時調(diào)用。
鉤子函數(shù)參數(shù)
指令鉤子函數(shù)會被傳入以下參數(shù):
el:指令所綁定的元素,可以用來直接操作 DOM。
binding:一個對象,包含以下 property:
name:指令名,不包括 v- 前綴。
value:指令的綁定值,例如:v-my-directive="1 + 1" 中,綁定值為 2。
oldValue:指令綁定的前一個值,僅在 update 和 componentUpdated 鉤子中可用。無論值是否改變都可用。
expression:字符串形式的指令表達式。例如 v-my-directive="1 + 1" 中,表達式為 "1 + 1"。
arg:傳給指令的參數(shù),可選。例如 v-my-directive:foo 中,參數(shù)為 "foo"。
modifiers:一個包含修飾符的對象。例如:v-my-directive.foo.bar 中,修飾符對象為 { foo: true, bar: true }。
vnode:Vue 編譯生成的虛擬節(jié)點。移步 VNode API 來了解更多詳情。
oldVnode:上一個虛擬節(jié)點,僅在 update 和 componentUpdated 鉤子中可用。
在項目中的使用
在我們開發(fā)后臺管理系統(tǒng)過程中,會經(jīng)常遇到這樣的需求,根據(jù)這個用戶的權限或者類型,來控制某個按鈕顯不顯示,比如審批按鈕、下載按鈕,實現(xiàn)方式非常多,這個地方就可以用自定義指令來實現(xiàn)。
可以給用戶加一個標記,比如userType,也可以根據(jù)用戶的角色,比如有某個審批角色的用戶,也可以根據(jù)用戶是否有某個菜單權限來控制,這里就以根據(jù)用戶是否有某個角色來控制
首先創(chuàng)建一個全局的自定義指令:
Vue.directive('has', {
// 當被綁定的元素插入到 DOM 中時……
inserted: function(el, binding) {
var sysRoles = store.state.user.sysRoles
if (!sysRoles) return false
var isHas = sysRoles.some(e => {
return e.id === 1
})
!isHas ? el.style.display = 'none' : el.style.display = 'inline-block'
}
})
當某個角色的id等于1的時候,顯示按鈕,否則不顯示
<el-button v-has="" type="primary" size="small>審批</el-button>
全局都可以使用,一個標簽就可以實現(xiàn)業(yè)務功能
實用插件
網(wǎng)上有非常多非常實用的自定義指令,這里推薦常用的兩款
v-clipboard(點擊復制內(nèi)容到粘貼板功能)
在我們開發(fā)后臺管理系統(tǒng)的時候,實現(xiàn)點擊表格的某一項,復制到粘貼板的功能。
1、安裝
npm install --save v-clipboard
2、引用
import Vue from 'vue'
import Clipboard from 'v-clipboard'
Vue.use(Clipboard)
3、table組件中使用
<el-table-column label="姓名" align="center">
<template slot-scope="scope">
<div @click="handleCopy(scope.row.name)">{{ scope.row.name }}</div>
</template>
</el-table-column>
4、mixins中創(chuàng)建一個全局的方法
在全局的mixins里面創(chuàng)建一個方法
var mixins = {
data() {
return {
}
},
methods: {
handleCopy(value) {
this.$clipboard(value)
this.$message.success('已復制到粘貼板')
}
}
}
export default mixins
5、完成

項目是基于自定義指令實現(xiàn)的,有興趣的可以關注一下項目源碼:
https://github.com/euvl/v-clipboard
Vue-Lazyload(圖片懶加載)
demo地址:http://hilongjw.github.io/vue-lazyload/
源碼地址:https://github.com/hilongjw/vue-lazyload
非常簡單實用的圖片懶加載工具
1、安裝
npm install --save vue-lazyload
2、引用
import loading from './assets/common/loading.gif'
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload, {
preload: .8,
loading,
// error,
})
3、使用
<img v-lazy="https://www.domain.com/image.jpg">
可以非常簡單的實現(xiàn)圖片懶加載

vue確實有很多非常實用的小技巧能幫助我們提高開發(fā)效率,提升用戶體驗,多看大神的開源代碼,對我們找到最合適的解決方案提升會很大。