前文
先來bb一堆廢話哈哈..
用vue做項(xiàng)目也有一年多了.除了用別人的插件之外.自己也沒嘗試去封裝指令插件之類的東西來用.
剛好最近在項(xiàng)目中遇到一個(gè)問題.(快速點(diǎn)擊按鈕多次觸發(fā)多次綁定的方法),于是就想說自己封裝一個(gè)
自定義指令來解決這個(gè)問題,于是便有了自己的第一個(gè)vue自定義指令 vue-reclick .
vue-reclick 傳送門
哈哈,好了!廣告打完了,開始進(jìn)入正題(等一下,聽說star有獎(jiǎng)哦)...
1.使用場(chǎng)景
在vue 2.0中,有的情況下,你需要對(duì)普通DOM元素進(jìn)行底層操作,這時(shí)候就需要用到自定義指令!
2.api詳解
其實(shí)關(guān)于vue自定義指令的使用 vue官方文檔已經(jīng)說的非常清楚.這里只是簡(jiǎn)單的照搬,哦不,講一下 (23333..)..
1.首先創(chuàng)建一個(gè)指令自定義對(duì)象directObj次哈。
let directObj = {}.
2.vue為所有指令的鉤子函數(shù)都提供一些函數(shù)參數(shù)。
let args = {
el:'指令所綁定的元素秸脱,可以用來直接操作 DOM ',
binding:{
name:'指令名,不包括 v- 前綴吗浩。',
value:'指令的綁定值偎行,例如:v-my-directive="1 + 1" 中,綁定值為 2泉褐。',
oldValue:'指令綁定的前一個(gè)值,僅在 update 和 componentUpdated 鉤子中可用鸟蜡。無論值是否改變都可用膜赃。',
expression:"字符串形式的指令表達(dá)式。例如 v-my-directive="1 + 1" 中揉忘,表達(dá)式為 "1 + 1"",
arg:"傳給指令的參數(shù)跳座,可選。例如 v-my-directive:foo 中泣矛,參數(shù)為 "foo"",
modifiers:"一個(gè)包含修飾符的對(duì)象疲眷。例如:v-my-directive.foo.bar 中,修飾符對(duì)象為 { foo: true, bar: true }乳蓄。",
vnode:"Vue 編譯生成的虛擬節(jié)點(diǎn)。",
oldVnode:"上一個(gè)虛擬節(jié)點(diǎn)"
}
}
3.在directObj上可根據(jù)需要定義一些鉤子函數(shù)
directObj.bind = function({...args }){
//只調(diào)用一次夕膀,指令第一次綁定到元素時(shí)調(diào)用虚倒。在這里可以進(jìn)行一次性的初始化設(shè)置。
}
directObj.inserted= function({...args }){
//被綁定元素插入父節(jié)點(diǎn)時(shí)調(diào)用 (僅保證父節(jié)點(diǎn)存在产舞,但不一定已被插入文檔中)魂奥。
}
directObj.update= function({...args }){
//所在組件的 VNode 更新時(shí)調(diào)用,但是可能發(fā)生在其子 VNode 更新之前易猫。
指令的值可能發(fā)生了改變耻煤,也可能沒有。
但是你可以通過比較更新前后的值來忽略不必要的模板更新
}
directObj.componentUpdated= function({...args }){
//指令所在組件的 VNode 及其子 VNode 全部更新后調(diào)用准颓。
}
directObj.unbind= function({...args }){
//只調(diào)用一次哈蝇,指令與元素解綁時(shí)調(diào)用。
}
4.注冊(cè)自定義指令
(1).全局注冊(cè):
Vue.directive('指令名稱','指令對(duì)象');
例:Vue.directive('reclick',directObj);
注意:全局注冊(cè)自定義指令需在實(shí)例化Vue之前.
(2).局部(組件)注冊(cè):
export default{
directives:{
'指令名稱':'指令配置'
}
}
例:
export default{
directives:{
'reclick':directObj
}
}
3.封裝自定義指令
好了,簡(jiǎn)單的講(抄)完 自定義指令相關(guān)的api,接下來我們通過vue-reclick來簡(jiǎn)單的講解一下如何封裝一個(gè)vue自定義指令吧.
由于vue-reclick 只是用來解決一個(gè)問題的小東西,所以代碼也相對(duì)簡(jiǎn)單,這里主要講一個(gè)封裝自定義指令的過程.
下面我們先來看下vue-reclick的源碼:
;(function() {
/**
* 函數(shù)節(jié)流
*
* @param {any} method 方法名
*/
function throttle(method) {
clearTimeout(method.tId);
method.tId = setTimeout(function() {
method.call();
}, 200);
}
/**
* 事件綁定
*
* @param {any} element 綁定dom
* @param {any} event 事件類型
* @param {any} listener 方法
*/
function addEvent(element, event, listener) {
if (element.addEventListener) {
element.addEventListener(event, listener, false);
} else if (element.attachEvent) {
element.attachEvent('on' + event, listener);
} else {
element['on' + event] = listener;
}
}
var vueReclick = {};
var reclick = {
bind: function(el, binding) {
addEvent(el, 'click', function() {
throttle(binding.value);
});
},
unbind: function(el) {
addEvent(el, 'click', function() {});
}
};
vueReclick.install = function(Vue) {
Vue.directive('reclick', reclick);
};
if (typeof exports == 'object') {
module.exports = vueReclick;
} else if (typeof define == 'function' && define.amd) {
define([], function() {
return vueReclick;
});
} else if (window.Vue) {
window.vueReclick = vueReclick;
Vue.use(vueReclick);
}
})();
1.將所有代碼包裹在一個(gè)立即執(zhí)行函數(shù)之中.
立即執(zhí)行函數(shù)有自己的作用域,可以避免變量沖突與污染.
將獨(dú)立的功能封裝在自包含模塊中.
2.vue-reclick功能相關(guān)的代碼這里簡(jiǎn)單說明下.
這里封裝了兩個(gè)方法(1.throttle,2.addEvent)
一個(gè)指令配置對(duì)象(reclick)
在reclick對(duì)象里定義了bind方法,在指令綁定到dom的時(shí)候,在dom上綁定點(diǎn)擊事件,并獲取指令綁定的方法名稱.
在觸發(fā)點(diǎn)擊事件的時(shí)候通過函數(shù)節(jié)流的方法來調(diào)用該方法,從而解決短時(shí)間快速點(diǎn)擊觸發(fā)多次方法的問題.
在reclick對(duì)象里定義了unbind方法,在指令與dom解綁的時(shí)候,將傳入方法與dom進(jìn)行解綁..
3.定義一個(gè)vueReclick插件對(duì)象,并在該對(duì)象上定義一個(gè)install方法.
(Vue.js 的插件應(yīng)當(dāng)有一個(gè)公開方法 install 攘已。這個(gè)方法的第一個(gè)參數(shù)是 Vue 構(gòu)造器)
4.在install方法里全局注冊(cè)指令
vueReclick.install = function(Vue) {
Vue.directive('reclick', reclick);
};
5.兼容多種模塊規(guī)范暴露該插件
if (typeof exports == 'object') {
module.exports = vueReclick;
} else if (typeof define == 'function' && define.amd) {
define([], function() {
return vueReclick;
});
} else if (window.Vue) {
window.vueReclick = vueReclick;
Vue.use(vueReclick);
}
6.到這一步,其實(shí)一個(gè)簡(jiǎn)單的自定義組件就已經(jīng)大功告成了.
7.最后.我們來講一下如何在項(xiàng)目中引入vueReclick并使用.
(1).非node環(huán)境中
在第5點(diǎn)我們?cè)趀lse if(window.Vue)中其實(shí)已經(jīng)Vue的全局方法來使用該插件.
所以我們可以直接在項(xiàng)目中使用該指令.
例:https://github.com/webfansplz/vue-reclick/blob/master/example/index.html
(2).node環(huán)境中
我們可以在項(xiàng)目入口文件中引入該插件,然后全局使用它,下面我們會(huì)講解如何將插件發(fā)布到Npm.
例:
import vueReclick from 'vue-reclick';
Vue.use(vueReclick);
4.將封裝好的插件發(fā)布到npm.
1.在Npm官網(wǎng)注冊(cè)一個(gè)賬號(hào)
2.在項(xiàng)目目錄下 使用npm login 登錄.
3.在項(xiàng)目目錄下 使用npm publish 上傳插件
4.大功告成,這樣以后我們?cè)谒许?xiàng)目中就都可以使用npm install 來下載我們自己封裝好的插件啦!.