前言 最近搞了畢設,須要實現一個場景,點擊一塊區域,彈出一個編輯區域,點擊頁面的其餘地方的時候,這個編輯區域就隱藏,本想一想以前寫模態框同樣寫個方法的時候,忽然javascript
以爲能夠嘗試用 vue 相關的東西優雅的解決這個事情,而後就學了下面的自定義指令了。html
直接看官網的介紹吧(以爲官方文檔說的很清楚了,因此我基本都是抄他的了)。vue
除了核心功能默認內置的指令 (v-model 和 v-show),Vue 也容許註冊自定義指令。注意,在 Vue2.0 中,代碼複用和抽象的主要形式是組件。然而,有的狀況下,你仍然須要對普通 DOM 元素進行底層操做,這時候就會用到自定義指令。
這個在分兩種狀況,若是你想定義一個全局的自定義組件的話,那麼就在項目中的 main.js
裏面定義了,例如定義一個官網中的自動聚焦的指令java
// 註冊一個全局自定義指令 `v-focus` Vue.directive('focus', { // 當被綁定的元素插入到 DOM 中時…… inserted: function (el) { // 聚焦元素 el.focus() } })
要是你只是想定義一個局部的指令在某個組件內部用的話,那麼就在相應的組件內定義了node
// 跟 data(),methods:{} 那些同級寫了 directives: { focus: { // 指令的定義 inserted: function (el) { el.focus() } } }
定義完後咱們就能愉快的使用了express
<input v-focus>
固然這個自定義指令不會就這麼一點東西啦,爲了解決一些現實中場景,Vue 給咱們一堆鉤子函數用來實現咱們的一些騷操做。具體以下 (均爲可選):async
bind
:只調用一次,指令第一次綁定到元素時調用。在這裏能夠進行一次性的初始化設置。inserted
:被綁定元素插入父節點時調用 (僅保證父節點存在,但不必定已被插入文檔中)。update
:所在組件的 VNode 更新時調用,可是可能發生在其子 VNode 更新以前。指令的值可能發生了改變,也可能沒有。可是你能夠經過比較更新先後的值來忽略沒必要要的模板更新 (詳細的鉤子函數參數見下)。componentUpdated
:指令所在組件的 VNode 及其子 VNode 所有更新後調用。unbind
:只調用一次,指令與元素解綁時調用。接下來咱們來看一下鉤子函數的參數 (即 el、binding、vnode 和 oldVnode)。ide
固然要想好好用用這寫鉤子函數,就要懂得用下面的這些參數函數
指令鉤子函數會被傳入如下參數:ui
el
:指令所綁定的元素,能夠用來直接操做 DOM 。binding
:一個對象,包含如下屬性:
name
:指令名,不包括 v- 前綴。value
:指令的綁定值,例如:- v-my-directive="1 + 1" 中,綁定值爲 2。oldValue
:指令綁定的前一個值,僅在 update 和 componentUpdated 鉤子中可用。不管值是否改變均可用。expression
:字符串形式的指令表達式。例如 v-my-directive="1 + 1" 中,表達式爲 "1 + 1"。arg
:傳給指令的參數,可選。例如 v-my-directive:foo 中,參數爲 "foo"。modifiers
:一個包含修飾符的對象。例如:v-my-directive.foo.bar 中,修飾符對象爲 { - foo: true, bar: true }。vnode
:Vue 編譯生成的虛擬節點。移步 VNode API 來了解更多詳情。oldVnode
:上一個虛擬節點,僅在 update 和 componentUpdated 鉤子中可用。而後官網有話說
除了 el 以外,其它參數都應該是隻讀的,切勿進行修改。若是須要在鉤子之間共享數據,建議經過元素的 dataset 來進行。
而後下面咱們給一個簡單的例子
// 在組件內部定義一個局部指令 directives:{ demo:{ bind: function (el, binding, vnode) { var s = JSON.stringify; el.innerHTML = `name: ${s(binding.name)} <br> value: ${s(binding.value)} <br> expression: ${s(binding.expression)} <br> argument: ${s(binding.arg)} <br> modifiers: ${s(binding.modifiers)} <br> vnode keys: ${Object.keys(vnode).join(', ')}` } } } // 綁定到組件中的一個 div 中 <div v-demo:foo.a.b="message"></div>
而後咱們在網頁中就能夠看到這麼一堆文字了(固然下面的註釋是我本身寫的)
name: "demo" // 指定名稱 value: "Welcome to Your Vue.js App" // 指令綁定值 expression: "message" // 字符串形式的指令表達式 argument: "foo" // 傳給指令的參數 modifiers: {"a":true,"b":true} // 修飾符的對象 vnode keys: tag, data, children, text, elm, ns, context, fnContext, fnOptions, fnScopeId, key, componentOptions, componentInstance, parent, raw, isStatic, isRootInsert, isComment, isCloned, isOnce, asyncFactory, asyncMeta, isAsyncPlaceholder // Vue 編譯生成的虛擬節點
在不少時候,你可能想在 bind
和 update
時觸發相同行爲,而不關心其它的鉤子。好比這樣寫:
colorSwatch: function colorSwitch(el, binding) { el.style.backgroundColor = binding.value },
若是指令須要多個值,能夠傳入一個 JavaScript 對象字面量。記住,指令函數可以接受全部合法的 JavaScript 表達式。
<div v-demo="{ color: 'white', text: 'hello!' }"></div>
Vue.directive('demo', function (el, binding) { console.log(binding.value.color) // => "white" console.log(binding.value.text) // => "hello!" })
就差很少這樣吧,想看個實例的話就看一下個人另一篇筆記《Vue 自定義指令實現點擊元素外觸發事件》吧