這次帶給大家Vue.JS的自訂指令應該如何使用,使用Vue.JS的自訂指令的注意事項有哪些,下面就是實戰案例,一起來看一下。
Vue.js 允許你註冊自訂指令,實質上是讓你教 Vue 一些新技巧:怎麼將資料的變化對應到 DOM 的行為。你可以使用Vue.directive(id, definition)的方法傳入指令id和定義物件來註冊一個全域自訂指令。定義物件需要提供一些鉤子函數(全部可選):
bind: 只呼叫一次,當指令第一次綁定元素的時候。
update: 第一次是緊跟在bind 之後調用,獲得的參數是綁定的初始值;以後每當綁定的值發生變化就會被調用,獲得新值與舊值兩個參數。
unbind:只呼叫一次,當指令解綁元素的時候。
範例:
Vue.directive('my-directive', { bind: function () { // 做绑定的准备工作 // 比如添加事件监听器,或是其他只需要执行一次的复杂操作 }, update: function (newValue, oldValue) { // 根据获得的新值执行对应的更新 // 对于初始值也会被调用一次 }, unbind: function () { // 做清理工作 // 比如移除在 bind() 中添加的事件监听器 } })
一旦註冊好自訂指令,你就可以在Vue.js 範本中像這樣來使用它(需要加入Vue.js 的指令前綴,預設為v- ):
<div v-my-directive="someValue"></div>
如果你只需要update 函數,你可以只傳入一個函數,而不用傳定義物件:
Vue.directive('my-directive', function (value) { // 这个函数会被作为 update() 函数使用})
所有的鉤子函數會被複製到實際的指令物件中,而這個指令物件將會是所有鉤子函數的this
上下文環境。指令物件上揭露了一些有用的公開屬性:
el: 指令綁定的元素
vm: 擁有該指令的上下文ViewModel
expression: 指令的表達式 ,不包含參數和過濾器
arg: 指令的參數
raw: 未被解析的原始表達式
name: 不含前綴的指令名
這些屬性是唯讀的,不要修改它們。你也可以給指令物件附加自訂的屬性,但是注意不要覆寫已有的內部屬性。
使用指令物件屬性的範例:
<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8"> <title></title> <script src="http://cdnjs.cloudflare.com/ajax/libs/vue/0.12.16/vue.min.js"></script></head><body><div id="demo" v-demo-directive="LightSlateGray : msg"></div><script> Vue.directive('demoDirective', { bind: function () { this.el.style.color = '#fff' this.el.style.backgroundColor = this.arg }, update: function (value) { this.el.innerHTML = 'name - ' + this.name + '<br>' + 'raw - ' + this.raw + '<br>' + 'expression - ' + this.expression + '<br>' + 'argument - ' + this.arg + '<br>' + 'value - ' + value } }); var demo = new Vue({ el: '#demo', data: { msg: 'hello!' } })</script></body></html>
多重子句
同一個特性內部,逗號分隔的多個子句將被綁定為多個指令實例。在下面的範例中,指令會被建立和呼叫兩次:
<div v-demo="color: 'white', text: 'hello!'"></div>
如果想要用單一指令實例處理多個參數,可以利用字面量物件作為表達式:
<div v-demo="{color: 'white', text: 'hello!'}"></div> Vue.directive('demo', function (value) { console.log(value) // Object {color: 'white', text: 'hello!'}})
字面指令
如果在建立自訂指令的時候傳入isLiteral: true ,那麼特性值就會被看成直接字串,並被賦值給該指令的expression。字面指令不會試圖建立資料監視。
範例:
<div v-literal-dir="foo"></div> Vue.directive('literal-dir', { isLiteral: true, bind: function () { console.log(this.expression) // 'foo' } })
動態字面指令
然而,在字面指令含有Mustache 標籤的情況下,指令的行為如下:
指令實例會有一個屬性,this._isDynamicLiteral被設為true;
如果沒有提供update函數,Mustache 表達式只會被求值一次,並將該值賦給this.expression。不會對表達式進行資料監視。
如果提供了update函數,指令將會為表達式建立資料監視,並且在計算結果變化的時候呼叫update。
雙向指令
如果你的指令想向 Vue 實例寫回數據,你需要傳入 twoWay: true 。此選項允許在指令中使用 this.set(value)。
Vue.directive('example', { twoWay: true, bind: function () { this.handler = function () { // 把数据写回 vm // 如果指令这样绑定 v-example="a.b.c", // 这里将会给 `vm.a.b.c` 赋值 this.set(this.el.value) }.bind(this) this.el.addEventListener('input', this.handler) }, unbind: function () { this.el.removeEventListener('input', this.handler) } })
內聯語句
傳入acceptStatement: true 可以讓自訂指令像v-on 一樣接受內聯語句:
<div v-my-directive="a++"></div> Vue.directive('my-directive', { acceptStatement: true, update: function (fn) { // the passed in value is a function which when called, // will execute the "a++" statement in the owner vm's // scope. } })
但請明智地使用此功能,因為通常我們希望避免在模板中產生副作用。
深度資料觀察值
如果你希望在一個物件上使用自訂指令,並且當物件內部嵌套的屬性發生變化時也能夠觸發指令的update 函數,那麼你就要在指令的定義中傳入deep: true。
<div v-my-directive="obj"></div> Vue.directive('my-directive', { deep: true, update: function (obj) { // 当 obj 内部嵌套的属性变化时也会调用此函数 } })
指令優先權
你可以選擇給指令提供一個優先權數(預設是0)。同一個元素上優先權越高的指令會比其他的指令處理得更早。優先權一樣的指令會依照其在元素特性清單中出現的順序依序處理,但是不能保證這個順序在不同的瀏覽器中是一致的。
通常來說身為用戶,你並不需要關心內建指令的優先級,如果你有興趣的話,可以參閱原始碼。邏輯控制指令 v-repeat, v-if 被視為 “終結性指令”,它們在編譯過程中始終擁有最高的優先權。
元素指令
有時候,我們可能想要我們的指令可以以自訂元素的形式被使用,而不是作為一個特性。這與 Angular 的 E 類指令的概念非常相似。元素指令可以看做是一個輕量的自定義元件(後面會講到)。你可以像下面這樣註冊一個自訂的元素指令:
Vue.elementDirective('my-directive', { // 和普通指令的 API 一致 bind: function () { // 对 this.el 进行操作... } })
使用時我們不再用這樣的寫法:
<div v-my-directive></div>
而是寫成:
<my-directive></my-directive>
元素指令不能接受参数或表达式,但是它可以读取元素的特性,来决定它的行为。与通常的指令有个很大的不同,元素指令是终结性的,这意味着,一旦 Vue 遇到一个元素指令,它将跳过对该元素和其子元素的编译 - 即只有该元素指令本身可以操作该元素及其子元素。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
相关阅读:
一个用Vue.js 2.0+做出的石墨文档样式的富文本编辑器
以上是Vue.JS的自訂指令應該如何使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!