vue 自定義指令的魅力

【第1103期】vue 自定義指令的魅力

點點 前端早讀課 2017-11-08

前言css

不少事情不能作過多的計劃,由於計劃趕不上變化。今日早讀文章由富途@點點翻譯分享。html

正文從這開始~前端

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

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

什麼是指令?vue-cli

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

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

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

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

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

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

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

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

<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>

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

  • bind-只調用一次,指令第一次綁定到元素時調用。

  • insert-被綁定元素插入父節點時調用。

  • update-所在組件的 VNode 更新時調用,可是可能發生在其子元素的 VNode 更新以前。

  • componentUpdated-所在組件的 VNode 及其子元素的 VNode 所有更新時調用。

  • unbind-只調用一次,指令與元素解綁時調用。

 


 

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

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

  • el 指令所綁定的元素,能夠用來直接操做 DOM 。

  • binding 一個對象,包含如下屬性:name,value,oldValue,expression,arg和modifiers。

  • vnode Vue 編譯生成的虛擬節點。

binding和vnode都是隻讀。

建立一個自定義指令

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

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>

假設咱們想要區分偏離的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';
   }
})

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

<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';
   }
})

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

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>

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

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

最後,你可能還會看:

【第970期】聊聊vue組件開發的「邊界把握」和「狀態驅動」

【第917期】Vue框架引入JS庫的正確姿式

 

關於本文

譯者:@點點

譯文:https://futu.im/posts/2017-10-31-vue-cutom-directive/

做者:@SARAH DRASNER

原文:https://css-tricks.com/power-custom-directives-vue/

 

相關文章
相關標籤/搜索