天天看點

vue.js學習筆記(Directives)

原文位址為: vue.js學習筆記(Directives)

vue.js學習筆記(Directives)

  想必喜歡前端開發的小夥伴們都或多或少接觸過MVVM這個概念,說起MVVM,第一時間想到的便是angularjs,knockoutjs等已經被廣泛運用的MVVM架構,之前我也沒有在這方面有很多了解,最近在做項目的過程中接觸了Vue.js,這是一個小巧精緻,性能優異的MVVM架構,可以說對初學者是比較容易入門的,該架構的英文文檔寫得很好,但是中文版通路還不太穩定,翻譯也有待改進,是以自己一遍學習,一遍記錄自己的思考,與各位共享學習的經驗。  

  第一篇主要是想談談vue.js中的Directives即指令,在vue.js中指令就是一個通知庫進行某些具體的dom操作的密碼,在html中表現為如下形式:

<element
prefix-directiveId="[argument:] expression [| filters...]">
</element>      

Directives分為1.Reactive Directives、2.Literal Directives、3.Empty Directives,下面結合具體的api闡述他們的作用:

1.Reactive Directives(響應式指令)

Reactive Directives可以綁定在Vue執行個體或者在Vue執行個體上下文中求值的表達式上,當綁定的對象發生改變時,指令中的update()會在下一個系統機關時間發生異步響應,我們來看看具體的用法:

v-text:更新元素的textContent,事實上在html中{{mustache}}形式的插入值也會被編譯為針對一個textNode的v-text指令。

v-html:更新元素的innerHTML,由于可能插入惡意代碼,使用時要注意保證來源安全。

v-show:根據綁定值的true或false來決定所在元素在網頁中正常顯示還是顯示為空。

v-class:這個指令有一個可選參數,無參數時将綁定值(一般為class名)添加到所在元素的classlist當中,并且一旦檢測綁定值有改動,便随之改變classlist裡對應的class;提供參數時參數的true或false将決定綁定值(class)是否被添加到所在元素的classlist中,示例如下:

<span v-class="
  red    : hasError,
  bold   : isImportant,
  hidden : isHidden
"></span>      

v-attr:更新所在元素的某些屬性(由參數表示)。

<canvas v-attr="width:w, height:h"></canvas>      

v-style:更新所在元素的樣式,會智能添加浏覽器供應商字首,友善我們書寫樣式。這個指令有一個可選參數,無參數時,若綁定值為String則将綁定值設定為元素的style.cssText,若綁定值為Object則将Object中的樣式鍵值對放入元素的style object當中;

<div v-style="myStyles"></div>      
// myStyles can either be a String:
"color:red; font-weight:bold;"
// or an Object:
{
  color: 'red',
// both camelCase and dash-case works
  fontWeight: 'bold',
'font-size': '2em'
}      

提供參數時,參數指明了css屬性的對應值:

<div v-style="
  top: top + 'px',
  left: left + 'px',
  background-color: 'rgb(0,0,' + bg + ')'
"></div>      

v-on:為元素添加并更新事件監聽器,參數可以是一個處理函數或者一個函數語句。

<div id="demo">
<a v-on="click: onClick">Trigger a handler</a>
<a v-on="click: n++">Trigger an expression</a>
</div>      

我們可以為處理函數提供參數,其中this指的是目前的ViewModel,如下例中通過傳入this參數改變元素的text值:

<ul id="list">
<li v-repeat="items" v-on="click: toggle(this)">{{text}}</li>
</ul>      
new Vue({
  el: '#list',
  data: {
    items: [
      { text: 'one', done: true },
      { text: 'two', done: false }
    ]
  },
  methods: {
    toggle: function (item) {
      item.done = !item.done
    }
  }
})      

我們還可以傳入$event表示觸發處理函數的DOM事件,如下例傳入$event阻止事件冒泡:

<button v-on="click: submit('hello!', $event)">Submit</button>      
/* ... */
{
  methods: {
    submit: function (msg, e) {
      e.stopPropagation()
    }
  }
}
/* ... */      

在監聽鍵盤事件時由于要判斷按鍵值,可以結合filter寫成如下兩種形式:

<!-- only call vm.submit() when the keyCode is 13 -->
<input v-on="keyup:submit | key 13">      
<!-- same as above -->
<input v-on="keyup:submit | key enter">      

當ViewModel銷毀時,v-on綁定的事件會自動消除,我們不必親自去清理這些綁定事件,這也防止了記憶體的洩露。

v-model:為表單元素建立一個雙向綁定,詳細介紹請看這裡

v-if:根據綁定值的true或false來插入或移除元素,如例子中我們将根據test的正确與否決定兩個<p>元素是否插入<template>當中

<template v-if="test">
<p>hello</p>
<p>world</p>
</template>      

v-repeat:為綁定數組或對象中的每一個item建立一個子ViewModel,或者為綁定的數字值建立對應數量的子ViewModel。并根據綁定值的改變随時更新。沒有提供參數時子ViewModel會直接使用綁定數組中的配置設定單元作為它的$data,如果值不是一個對象,則會建立一個資料包裝對象,而值會被設定在别名為

$value

的 key 上。

<ul>
<li v-repeat="users">
    {{name}} {{email}}
</li>
</ul>      

如果提供了參數,我們将建立一個資料包裝對象,将參數作為對象的key,進而通路對象模闆中的屬性:

<ul>
<li v-repeat="user : users">
    {{user.name}} {{user.email}}
</li>
</ul>      

v-with:這個指令隻能結合接下來講到的v-component指令使用,作用是讓子ViewModel可以繼承父ViewModel的資料,我們可以傳入父ViewModel的屬性對象或單個屬性,在子ViewModel中通路:

// parent data looks like this
{
  user: {
    name: 'Foo Bar',
    email: '[email protected]'
  }
}      

繼承對象:

<my-component v-with="user">
<!-- you can access properties without `user.` -->
  {{name}} {{email}}
</my-component>      

繼承單個屬性:

<my-component v-with="myName: user.name, myEmail: user.email">
<!-- you can access properties with the new keys -->
  {{myName}} {{myEmail}}
</my-component>      

v-events:這個指令也隻能結合接下來講到的v-component指令使用,它使得父ViewModel能夠監聽子ViewModel上的事件,我們要注意區分v-on與v-events,v-events監聽的是通過

vm.$emit()

建立的 Vue 元件系統事件,而不是 DOM 事件。我們舉例說明:

<!-- inside parent template -->
<div v-component="child" v-events="change: onChildChange"></div>      

當子ViewModel調用this.$emit('change', …)時會觸發父ViewModel的onChildChange()方法,并且把emit函數中附加的參數傳給onChildChange()方法。

2.Literal Directives(字面指令)

字面指令并沒有綁定到某一個對象上,字面指令是把它們的參數作為純字元串傳給bind()函數中執行一次,字面指令可以接受{{mustache}}表達式,但是該表達式隻會在編譯階段執行一次,不會綁定資料的改變:

下面看一看具體的api:

v-component:之前提到過,這是使用我們提前聲明并注冊好的元件構造器将目前元素編譯為子ViewModel,進而實作資料繼承,之後的文章會詳細介紹元件系統。

v-ref:在父ViewModel中建立子ViewModel的引用,友善父ViewModel中的$對象通路子元件:

<div id="parent">
<div v-component="user-profile" v-ref="profile"></div>
</div>      
var parent = new Vue({ el: '#parent' })
// 通路子元件
var child = parent.$.profile      

這個指令隻能與

v-component

v-repeat一起使用,與v-repeat一起使用時,其value是與綁定資料數組對應的子元件數組。

v-el:為目前dom元素建立一個引用,供其自身vue執行個體使用,例如<div v-el="hi">可以使得vm.$$.hi通路到該dom元素

v-partial:将目前dom元素中的innerHTML替換為事先注冊的partial,有兩種寫法,{{ mustache}}可以讓dom元素随資料改變而更新:

<!-- content will change based on vm.partialId -->
<div v-partial="{{partialId}}"></div>      

另一種寫法則沒有資料跟随更新的效果:

<div>{{> my-partial}}</div>      

v-transition:為目前dom元素在指定參數值作用時添加動畫效果,後續文章會詳細介紹

3.Empty Directives(字面指令)

v-pre:這個指令是通知編譯器跳過目前dom元素和其所有子元素,這是為了在我們程式設計過程中對無需編譯的元素節省編譯時間

v-cloak:在目前元素編譯完成之前改指令都會存在,我們一般使用這個指令來在元素編譯未完成時隐藏原始的 {{ Mustache }} 模闆,可以在css中這樣寫:

[v-cloak] { display: none }      

轉載請注明本文位址: vue.js學習筆記(Directives)