【譯】vue 自定義指令的魅力

本文同步發表在富途web開發團隊博客 futu.im/article/vue…javascript

在你初次接觸一個新的Javascript框架時,會像第一次進糖果店的孩子同樣。給啥拿啥,而更直接點,有些東西可讓你更容易成爲一個開發者。不可避免的是,咱們在用框架時都會有一個同感,就是總有些場景是框架不能幫咱們完成的。css

Vue框架的漂亮之處在於它的功能很是強大,雖然這個框架的指令不夠面面俱到,但也能在開發上助你一臂之力了,由於建立一個自定義指令是很輕鬆的。html

什麼是指令?

我在Vue.js guide中寫過指令的一篇文章,如今再一塊兒複習下。vue

指令是能夠寫在DOM元素的小命令,他們以v-爲前綴,vue就能識別這是一個指令並保持語法的一致性。若是你須要對HTML進行底層操做的話,這種方式是很是有用的。java

若是你已經用過vue或者angular的話,對於v-if,v-else,v-show等指令就會比較熟悉了,可是我仍是要介紹一些基礎的知識,若是你更想直接看例子,能夠直接看後文就行了。node

如下是使用指令的幾種方法,以及示例,這些例子並不規範,它們只是示例。這裏的example代替了實際的指令。web

v-example - 會實例化一個指令,但這個指令沒有參數。若是不傳參數會比較不靈活,可是這樣就已經操做DOM元素的能力了。vue-cli

v-example="value" - 這樣能夠傳值到指令中,指令會根據value值來操做html。express

<div v-if="stateExample">stateExample爲true時會顯示</div>
複製代碼

v-example="'string'" - 使用字符串做爲表達式。app

<p v-html="'<strong>this is an example of a string in some text<strong> '"></p>
複製代碼

v-example:arg="value" - 這裏能夠傳參數(arg),在下面的例子中,咱們綁定一個class,而後給這個class設置樣式。

<div v-bind:class="someClassObject"></div>
複製代碼

v-example:arg.modifier="value" - 使用修飾符(modifier),下面的例子能夠在click事件上調用preventDefault();

<button v-on:submit.prevent="onSubmit"></button>
複製代碼

瞭解自定義指令

如今對指令有了大概的瞭解後,咱們再來學習下如何建立一個自定義指令。自定義指令的典型例子就是建立一個scroll事件的指令,下面讓咱們一塊兒來看一下。

首先建立一個單純的全局指令(它尚未作任何事情)。

vue.directive('tack');
複製代碼

根據這個指令HTML就是這樣的:

<p v-tack>This element has a directive on it</p>
複製代碼

指令定義函數提供了幾個鉤子函數 (可選):

  1. bind-只調用一次,指令第一次綁定到元素時調用。
  2. insert-被綁定元素插入父節點時調用。
  3. update-所在組件的 VNode 更新時調用,可是可能發生在其子元素的 VNode 更新以前。
  4. componentUpdated-所在組件的 VNode 及其子元素的 VNode 所有更新時調用。
  5. unbind-只調用一次,指令與元素解綁時調用。

hookArguments

我認爲這五個鉤子函數中bindupdate是最有用的。

他們中的每個都有能夠用的el,bindingvnode參數,除了updatecomponentUpdated以外,還會暴露oldVnode,以區分傳遞的舊值和新值。

  • el 指令所綁定的元素,能夠用來直接操做 DOM 。
  • binding 一個對象,包含如下屬性:name,value,oldValue,expression,argmodifiers
  • vnode Vue 編譯生成的虛擬節點。

bindingvnode都是隻讀。

建立一個自定義指令

瞭解了自定義指令概念後,來看下如何使用一個自定義指令,下面用一個例子來實現咱們剛纔所說的:

Vue.directive('tack',{
    bind(el,binding,vnode){
        el.style.position = 'fixed'
    }
})
複製代碼

相對應的HTML就是:

<p v-tack>I will now be tacked onto the page</p>
複製代碼

這樣就能夠了,可是還不夠靈活。若是能接受參數以便後續更新它的表現或者進行復用的話就會更加靈活。讓咱們看下如何實現讓這個元素離頁面頂部有必定的距離:

Vue.directive('tack',{
    bind(el,binding,vnode){
        el.style.position = 'fixed';
        el.style.top = binding.value + 'px';
    }
})
複製代碼
<div id="app">
    <p>向下滾動頁面</p>
    <p v-tack="70">我固定在離頂部70px的地方</p>
</div>
複製代碼

完成後的CodePen展現:(如沒法展現效果,點擊連接查看)

假設咱們想要區分偏離的70px是在頂部仍是左側,能夠經過傳遞一個參數來實現:

<p v-tack:left="70">如今我會在距離左側70px的地方</p>
複製代碼
Vue.directive('tack',{
    bind(el,binding,vnode){
        el.style.position = 'fixed';
        const s = (binding.arg == 'left'?'left':top);
        el.style[s] = binding.value + 'px';
    }
})
複製代碼

完成後的CodePen展現:(如沒法展現效果,點擊連接查看)

你也能夠使用多個值,像自帶指令同樣用:

<p v-tack="{top:'40',left:'100'}">我固定在離頂部40px、左側100px的地方</p>
複製代碼

而後這兩個值將會在指令上同時生效:

Vue.directive('tack',{
    bind(el,binding,vnode){
        el.style.position = 'fixed';
        el.style.top = binding.value.top+'px';
        el.style.left = binding.value.left+'px';
    }
})
複製代碼

完成後的CodePen展現:(如沒法展現效果,點擊連接查看)

咱們還能夠編寫更復雜的東西,咱們能夠根據自定義指令來建立和修改方法。這裏,咱們簡單建立一個滾動動畫小例子:

Vue.directive('scroll',{
    inserted:function(el,binding){
        let f = function(evt){
            if(binding.value(evt,el)){
                 window.removeEventListener('scroll',f);
            }
        }
        window.addEventListener('scroll',f);
    }
});

//main app

new Vue({
    el:'#app',
    methods:{
        handleScroll:function(evt,el){
            if(window.scrollY>50){
                TweenMax.to(el,1.5,{
                    y:-10,
                    opacity:1,
                    ease:sine.easeOut
                })
            }
            return window.scrollY>100;
        }
    }
});
複製代碼
<div class="box" v-scroll="handleScroll">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. A atque amet harum aut ab veritatis earum porro praesentium ut corporis. Quasi provident dolorem officia iure fugiat, eius mollitia sequi quisquam.</p>
</div>
複製代碼

完成後的CodePen展現:(如沒法展現效果,點擊連接查看)

以上都是很簡單的代碼來實現效果,在實際的開發中,你能夠建立更高級靈活的自定義指令。

在一個實際構建過程當中,我會將指令代碼放在main.js中,這個文件位於src目錄下(若是你使用的是vue-cli這樣的工具的話),這樣App.vue及以.vue後綴名的文件均可以引入使用。你固然也能夠使用其餘的方式,但這是我認爲在實現整個App過程當中最靈活的方式。

若是你想了解有關Vue框架的更多知識,請查看guide.

原文:The Power of Custom Directives in Vue

做者:SARAH DRASNER

譯者:Diandian

相關文章
相關標籤/搜索