Vue.js (3) - 指令 (Directives) 與過濾器 (Filters)

Vue.js

Vue.js 提供好用的指令讓你能控制資料的顯示,過濾器則能讓你格式化將要輸出的文字。

指令 (Directives)

Vue 提供一系列 v- 開頭的特殊屬性,這些特殊屬性稱為指令 (Directives)。指令的值是單一 JavaScript 表達式 (v-for 例外)。每當指令的表達式中的值發生改變,該指令就會把結果反應到 DOM 上。

資料綁定指令

v-text
接受一個字串值 string,會更新被指定元素的 textContent。功能類似使用雙括號 {{ }} 的插值方式,差別在於 v-text 只能更新該元素的整個內容,如果只有部份內容要被更新,必須使用雙括號 {{ }} 的表式法。
使用範例:
HTML<div id="app">
  <span>{{ text }}</span>
  <span v-text="text"></span>
</div>
這兩個用法的結果是相同的,但比較建議使用雙括號的表示法,而如果你只想改變範例中 <span> 的部份內容,也只能用雙括號表示法。
v-html
接受一個字串值 string,會更新被指定元素的 innerHTML。資料會以原生的 HTML 被插入,而且 Vue 不會對其編譯。
!注意!接受任意的 HTML 會有被 XSS 攻擊的風險,只在能夠信任的內容上使用這個指令。
使用範例:
HTML<div v-html="html"></div>

條件控制指令

v-show
依表達式的布林值來切換元素的 CSS display 屬性。
使用 v-show 的元素,在第一次建立 DOM 時就會被保留,之後它的顯示或消失就只是改變 CSS display 屬性,來達到看得見或看不見的效果。
使用範例:
HTML<div id="app">
  <p v-show="show">Hi</p>
</div>

<script>
var app = new Vue({
  el: '#app',
  data: {
    show: true
  }
})
//每0.5秒改變 show 的布林值
setInterval(function(){
  app.show = !app.show
}, 500)
</script>
v-if
依表達式的布林值來決定是否描繪元素。true 時會建立元素及資料綁定,false 時則銷毀該元素及任何已綁定的資料。
使用範例:
HTML<div id="app">
  <p v-if="seen">{{ message }}</p>
</div>

<script>
  var app = new Vue({
    el: '#app',
    data: {
      seen: true,
      message: '這段訊息將在 3 秒後消失'
    }
  })
  // 3秒計時器
  setTimeout(function(){
    app.seen = false
  }, 3000)
</script>
如果有不只一個元素需要受到條件控制,可以使用 <template> 樣板元素來群組它們:
HTML<template v-if="seen">
  <h2>AAA</h2>
  <p>{{ message }}</p>
</template>
只有當 true 的時候,在 <template> 中的內容才會被顯示。
v-show 和 v-if 的差別
首先,v-show 不能用在 <template> 元素。

v-if 被執行的時候,會實際的建立元件,如果該元件已經存在,則會銷毀並重建,包括它的子元件及事件偵聽器等等。另外,它只有在條件為 true 時才會建立,也就說,如果一開始的值為 false,則它什麼也不做,這樣的好處是可以達成延遲載入(lazy loading)。

v-show 則不管條件真假,一定會被建立,然後再以條件做顯示的設定,而且顯示與否是透過 CSS 的 display 屬性來控制。

兩者該怎麼選擇呢?v-show 只有在第一次建立的時候花費運算時間,v-if 則在每次條件成立的時候花費運算時間,因此,如果會頻繁切換,使用 v-show 會比較好,相反的如果控制條件不太會改變,則使用 v-if。例如前面的例子,因為要每 0.5 秒切換一次顯示,用 v-show 就會比用 v-if 來的好。

另外,如果你的條件控制比較複雜,也只能使用 v-if,因為它還可以接續 v-else 等指令。
v-else
這個指令不需要表達式。但限制是,必須接續在 v-ifv-else-if 指令所屬的元素後面。
使用範例:
HTML<p v-if="seen">訊息A</p>
<p v-else>訊息B</p>
以上兩個元素只有其中一個會顯示。

v-else-if

這是 2.1.0 版新增的指令。
這個指令不需要表達式。但限制是,必須接續在 v-ifv-else-if 指令所屬的元素後面。
使用範例:
HTML<div id="app">
  <p v-if="fruit === 'Apple'">蘋果</p>
  <p v-else-if="fruit === 'Banana'">香焦</p>
  <p v-else-if="fruit === 'Cherry'">櫻桃</p>
  <p v-else>都不是</p>
</div>

<script>
var app = new Vue({
  el: '#app',
  data: {
    fruit: 'Apple'
  }
})
</script>

循環控制指令

v-for
這個指令依資料的數量來重覆描繪元素。它必須使用特定語法 別名 in 表達式,表達式可以是
  • 陣列 (Array)
  • 物件 (Object)
  • 整數 (number)
  • 字串 (string)

● 陣列循環 (Array)
使用範例:
HTML<div id="app">
  <ul>
    <li v-for="fruit in fruits">
      {{ fruit }}
    </li>
  </ul>
</div>

<script>
var app = new Vue({
  el: '#app',
  data: {
    fruits: ['Apple', 'Banana', 'Cherry']
  }
})
</script>
JavaScript 的陣列可以用 [] 來簡寫,所以這裡我們指定了一個有 3 個水果的 fruits 陣列。v-for 會將 fruits 陣列一個一個取出並以別名 fruit 暫存該值,接著將值放入指定的位置。v-for 會重覆建立所屬的元素,直到循環結束。

某些時候,你會需要索引值,你可以在別名中指定第 2 個名稱來取得索引值,但要用括號將別名包起來:
HTML<li v-for="(fruit, index) in fruits">
  {{ index }} - {{ fruit }}
</li>

● 物件循環 (Object)
使用範例:
HTML<div id="app">
  <ul>
    <li v-for="value in fruit">
      {{ value }}
    </li>
  </ul>
</div>

<script>
var app = new Vue({
  el: '#app',
  data: {
    fruit: {
      name: 'Apple',
      price: 50,
      expireDate: '2017-03-30'
    }
  }
})
</script>
結果看起來像這樣:
Output* Apple
* 50
* 2017-03-30 
物件是以 key: value 的方式儲存資料,v-for 也提供第 2 個別名來取得 key
HTML<div id="app">
  <ul>
    <li v-for="(value, key) in fruit">
      {{ key.charAt(0).toUpperCase() + key.substr(1) }}: {{ value }}
    </li>
  </ul>
</div>
現在看起來像這樣:
Output* Name: Apple
* Price: 50
* ExpireDate: 2017-03-30 
如果要取得索引值的話,可以使用第 3 個別名:
HTML<div id="app">
  <ul>
    <li v-for="(value, key, index) in fruit">
      {{ index }} - {{ key.charAt(0).toUpperCase() + key.substr(1) }}: {{ value }}
    </li>
  </ul>
</div>
這裡要注意,物件的屬性是無序的,它是以 Object.keys() 來循環整個物件內的屬性,所以有可能順序不是你所希望的那樣。

● 整數循環 (number)
v-for 提供一個方便的功能可以讓你產生一段連續的整數:
HTML<div id="app">
  <span v-for="n in 5">
    {{ n }}
  </span>
</div>
瀏覽器看到的結果:
HTML<div id="app">
  <span>1</span>
  <span>2</span>
  <span>3</span>
  <span>4</span>
  <span>5</span>
</div>

● 字串循環 (string)
字串是由一串字元所組成,所以字串循環取將會取得一個一個的字元:
HTML<div id="app">
  <span v-for="char in 'Apple'">{{ char }}-</span>
</div>
輸出的結果:
OutputA-p-p-l-e-

事件指令

v-on
事件指令可以用來偵聽按鈕 <a><button> 等元素、滑鼠或鍵盤被按下時的事件處理。事件的詳細使用方法會在之後用一個章節做介紹。

屬性綁定指令

v-bind
接受任何單一的表達式。
v-bind 可以用 : 來縮寫。
使用範例:
HTML<!-- 綁定一個屬性 -->
<a v-bind:href="url">link</a>

<!-- 綁定一個屬性,使用縮寫 -->
<a :href="url">link</a>

表單元件雙向綁定指令

v-model
v-model可以讓你做資料的雙向綁定,它只能用在表單元素及 Vue 元件 (Component)上,之後會有一個章節專門介紹。

其他指令

v-pre
不需要表達式。這個指令會讓編譯過程忽略該元素,如同 HTML 中的 <pre>可以用來顯示原始的雙括號。
使用範例:
HTML<span v-pre>{{ 這段內容不會被編譯 }}</span>
v-cloak
不需要表達式。這個指令會保持在元素上,直到實體結束編譯。這個功能可以搭配 CSS 的 display 屬性,讓編譯前的內容不要顯示,這樣就不會先看到一堆編譯前的雙括號 {{ }} 內容。
使用範例:
CSS[v-cloak] {
  display: none;
}
HTML<div id="app" v-cloak>
  {{ message }}
</div>
v-once
不要需要表達式。強制該元素只被建立一次,包括它的子元素都會在建立之後被視為靜態內容。如果該元素不需要重覆建立,這樣做可以優化更新效能。
使用範例:
HTML<span v-once>{{ message }}</span>

過濾器 (Filters)

Vue.js 可以讓你使用過濾器,通常用來對文字資料的格式化。過濾器可以用在雙括號 {{ }}v-bind 的表達式中。過濾器必須寫在表達式的尾部,並且由管道 | 符號串接。
使用範例:
HTML<div id="app">
  {{ message | toUpperCase | abbreviation }}
</div>

<script>
new Vue({
  el: '#app',

  data: {
   message: 'This is a test text.'
  },

  filters: {
    toUpperCase: function(text) {
     return text.toUpperCase()
    },

    abbreviation: function(text) {
      var chars = ''
      text.split(' ')
          .forEach(function(el) {
            chars += el.charAt(0) + '.'
          })
      return chars
    }
  }
})
</script>
執行結果會將 message 的內容大寫後取第一個字元當成縮寫:
OutputT.I.A.T.T.
之前我們已經用了很久的 eldata 屬性,現在又學到一個新的 filters,它的屬性值都是函式,這個範例中,我們建了兩個函式:toUpperCaseabbreviation。之後我們就能在 {{ }} 中用 | 來串接這些過濾器。
本文網址:http://blog.tonycube.com/2017/03/vuejs-3-directives-filters.html
Tony Blog 撰寫,請勿全文複製,轉載時請註明出處及連結,謝謝 😀

我要留言

留言小提醒:
1.回覆時間通常在晚上,如果太忙可能要等幾天。
2.請先瀏覽一下其他人的留言,也許有人問過同樣的問題。
3.程式碼請先將它編碼後再貼上。(線上編碼:http://bit.ly/1DL6yog)
4.文字請加上標點符號及斷行,難以閱讀者恕難回覆。
5.感謝您的留言,您的問題也可能幫助到其他有相同問題的人。