指令(2):自定義指令

簡介

自定義指令就像一個迷你的函數,把你自定義的功能塞進這個迷你函數裏,在頁面上快速的調用,增長用戶體驗。javascript

Vue.directive('dyColor',{
    bind:function(el){
        el.onclick = () => {
            el.style.backgroundColor = '#' + Math.random().toString().slice(2,8)
        } 
    }
})
new Vue({
    el: '#app-1'
})
<div id="app-1">
    <div class="box bg-fw" v-dy-color>
        <h1>Lorem</h1>
        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Repellat beatae neque, quo, hic molestiae accusamus maxime cupiditate impedit quia labore aspernatur doloribus necessitatibus! Odio, quod eaque consectetur dolor asperiores id.</p>
    </div>
</div>

clipboard.png

上面這個簡單示例中,使用Vue.directive('name',hooks)定義一個指令,在頁面上加上前綴v-使用。
bind()爲一個鉤子函數,也有其餘幾種鉤子,在鉤子中完成一些自定義功能,鉤子上有幾個規定的參數,上面el就是一個,鉤子及參數後面分析。java

鉤子函數

總共有五種HookbindinsertedupdatecomponentUpdatedunbindnode

  • bind: 在指令綁定到元素上時調用。
  • inserted: 在被綁元素插入到父節點時調用一次(父節點是否插入文檔無所謂)
  • unbind: 指令與元素解綁時調用一次。

inserted是新版新加的,這個時機發生在bind以後,增長點靈活度,就目前爲止沒發現有什麼用。express

  • update:在被綁元素被修改時,修改內容未被插入時調用
  • componentUpdated: 在被綁元素被修改並把修改內容插入後調用

官網這裏是外星人寫的,看不清,我暫時就這麼理解了,這兩個也是基於老版本update修改的。把一個時間分紅兩部分而已。由於el引用的一個是修改前、一個是修改後的內容,仍是有點用。app

Vue.directive('test', {
    bind:function(el){
        el.onclick = () => {
            el.style.backgroundColor = '#' + Math.random().toString().slice(2,8)
        } 
        $(el).find('#info_update').append('<li><span class="emblem">'  + (el.parentNode?'有父元素':'無父元素') +'</span></li
        console.log(el.parentNode)
        console.log('bind')
    },
    inserted: function (el) {
        $(el).find('#info_update').append('<li><span class="emblem">'  + (el.parentNode?'有父元素':'無父元素') +'</span></li
        console.log('inserted')
    },
    update: function (el) {
        $(el).find('#info_update').append('<li><span class="emblem">'  + $(el).find('h3').text() +'</span></li>')
        console.log('update')
    },
    componentUpdated: function (el) {
        $(el).find('#info_update').append('<li><span class="emblem">'  + $(el).find('h3').text() +'</span></li>')
        console.log('componentUpdated')
    },
    unbind: function (el) {
        console.log('unbind')
    }
})
new Vue({
    el:'#app-2',
    data:function(){
        return {
            msg:'test directive',
            show:true
        }
    },
    methods:{
        updateData:function(){
            this.msg = 'hello'
        }
        
    }
})
<script>
.emblem {
    background-color: #f46;
    color: #fff;
    padding: 2px 4px;
    font-size: 14px;
    line-height: 15px;
    height: 15px;
    border-radius: 4px;
    margin-top:5px;
    display: inline-block;
}
</script>
<div id="app-2">
    <button @click="updateData" class="btn btn-warn btn-sm">update</button>
    <button @click="show = !show" class="btn btn-warn btn-sm">bind&Insert</button>
    <button @click="show = !show" class="btn btn-warn btn-sm">unbind</button>
    <div class="box" v-if="show" v-test>
        <h3>{{msg}}</h3>
        <p id="info_update">
        </p>
        <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Reprehenderit ad aut cupiditate.</p>
    </div>
</div>

clipboard.png

插入被綁元素時,能夠看到bind階段的被綁元素沒有父元素,而inserted階段是有的;而update階段使用的是修改前的數據,componentUpdated階段是使用後的數據,點擊解綁按鈕就是移除被綁元素,天然指令也和元素解綁了。dom

鉤子函數參數

由於這幾個參數,直接致使Vue靈活度*2,就像定義一個組件那樣,自定義指令由於參數的開放性會有無限種可能。函數

  • el:指令所綁定的元素,能夠用來直接操做DOM
  • binding:一個對象,包含與指令自己相關的一些屬性:ui

    • name:指令名,不包括v-前綴
    • value:指令的綁定值,如例v-hello = "1 + 1"中,綁定值爲2
    • expression:字符串形式的指令表達式。例如v-hello = "1 + 1"中,表達式爲"1 + 1"
    • oldValue:指令綁定的前一個值,僅在update和componentUpdated鉤子中可用,不管值是否改變均可用
    • arg:傳給指令的參數,可選。例如v-hello:message中,參數爲"message"
    • modifiers:一個包含修飾符的對象。例如v-hello.foo.bar中,修飾符對象爲{foo:true, bar:true}
  • vnode:Vue編譯生成的虛擬節點。能夠當作el的底層表現,咱們就能夠經過它進一步去操做被綁元素
  • oldVnode: 修改前的VNODE,僅在update和componentUpdated兩個鉤子函數中可用

一個有意義的示例不可能覆蓋它們,在這裏只能作個觀察,後面寫插件時儘可能使用它們。this

相關文章
相關標籤/搜索