前言
從1.0.X版本就開始使用vue了,應該也是vue很早的一批使用者。在我司使用vue這一年多以來(偏向移動端),我發現vue的外掛真的是少之又少,這也是我當初一開始想寫v-tap指令外掛的初衷。
如今vue升級2.0後,在自定義指令部分的API全部變化了!對於一個外掛作者來說這簡直是崩潰的!毫無相容可言。本文我就講介紹下一個自定義指令從1.0升級到2.0所走的坑。T.T
吐槽
我們知道,一個方法最重要的就是傳參,所以自定義指令最需要的也是這點。在實現過程中,最大的變化就是這點。
// 1.0版本能實現以下API
v-tap="args($index,el,$event)"複製程式碼
// 而2.0版本後完全不能,必須使用物件的形式,如下
v-tap="{ methods:args , index : index, item:item }"複製程式碼
簡直了!完全不知道作者為啥這樣設計!(這太讓我蛋碎了,如果你有更好的姿勢,請儘快告訴我)
好吧,習慣了這樣不優雅的畫風之後其實還是可以勉強適應的。
踩坑
一開始如果你直接實現一個指令不需要傳參你會發現,vue的指令機制是直接取value
得,所以你可以直接寫v-directive="func"
這樣執行完全沒有問題,在你的自定義指令中只需要 binding.value.call
即可
但是如果你寫了 v-directive="func('aa')"
你將會發現,vue的指令機制把它解析成了expression,正如文件所說(大寫懵逼)
expression: 繫結值的字串形式。 例如 v-my-directive="1 + 1" , expression 的值是 "1 + 1"。
這又將導致了一個問題,在vue1.0中你可以寫v-directive="a++"
這樣可以直接使data裡的變數a++,而在2.0中這會報錯,應該都是解析成了expression的原因
在我使用百般姿勢後,最後不得不從了文件中的最後一種寫法--物件字面量
複製程式碼
Vue.directive('demo', function (el, binding) {
console.log(binding.value.color) // => "white"
console.log(binding.value.text) // => "hello!"
})複製程式碼
那指令外掛如何相容1.0和2.0呢?我是這樣處理的,分別寫兩個物件,判斷版本不同註冊不同指令
var vue1 = { ... };
var vue2 = { ... };
vueTap.install = function (Vue) {
if(Vue.version.substr(0,1) > 1 ) {
isVue2 = true;
}
Vue.directive('tap', isVue2 ? vue2 : vue1);
};複製程式碼
以上就是本次自定義指令升級的兩個大坑!
Have a nice day