了解了 Vue 的基本指令以後,接著繼續來了解指令及模板的進階用法吧!
v-once — 單次綁定
v-text
跟 v-once
同時寫在一個 HTML 元素上,如此一來這個元素的內容在第一次寫入完成後,之後就不會再被變動。
雙花括號輸出資料加總
如果 data
中有多個特性的值為數字,可以用雙花括號在 HTML 輸出這些特性作為變數組成的算式,並在畫面上渲染出計算結果;或者也可以將數個字串型別的特性直接在雙花括號中串接,一樣可以渲染出字串連接的結果。
動態操控 disabled 屬性
用 v-bind
綁定 disabled
屬性與 data
特性,當切換對應的 data
值(值為布林)時,就能隨之切換 HTML 的可用狀態。
動態切換 className 的多種寫法
用物件帶值:在 Vue 基礎概述 (下) 講過,也就是在要切換
className
的 HTML 元素上使用v-bind
並且值用物件形式帶入,像下面這樣::class="{'要加入的 className': 判斷式}"
用陣列帶值:在 data 創一個空陣列,在要套用
className
的元素上設定:class="data 陣列名"
,觸發樣式切換的元素(例如 checkbox)加上v-model="data 陣列名"
及value="要切換的 className"
,這樣如果要啟用className
就能透過觸發元素將value
傳進data
裡的陣列,而如果要拿掉className
一樣也是透過觸發元素刪掉該陣列中的value
。
插入行內樣式 (style)
- 用物件帶值:要注意 style 樣式屬性的名稱跟 CSS 不太一樣,style 的樣式屬性採用駝峰式命名法。也可以用參數的方式從 data 傳物件到 style 屬性,這樣做的話可以在物件內放入數個特性(樣式)
1 | <!-- 基本款 --> |
- 用陣列帶值:陣列元素必須以物件方式寫入;或用參數,可以在陣列內放入數個物件參數。
1 | <!-- 基本款 --> |
v-for 使用細節
可以用於疊代 data 中的陣列及物件。
v-for 與 key 屬性
引述自官網:「使用 v-for 渲染的元素列表時,默認使用『就地更新』的策略。如果數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序,而是就地更新每個元素,並且確保它們在每個索引位置正確渲染。」
也就是說,預設狀況下,資料的索引值是固定的,當畫面上資料順序變換時,是將內容進行替換,而不是替換 DOM 元素位置。
如果希望 DOM 元素位置替換呢?在每筆資料上綁定 key 屬性,該屬性必須對應一個唯一值。
參照:官方文件(列表渲染)、如何理解vue的key属性
v-for 跟 filter() 連用
來寫一個可以過濾資料的小範例吧!
- 結構:
- data 資料 -
arrayData
為一個包含多個物件資料的陣列 - 負責輸入的 HTML 元素(例如 input text) - 設定
v-model="filterText"
(等一下過濾arrayData
的條件) - 負責輸出的 HTML 元素 - 設定
v-for="(item,key) in filterArray"
(filterArray
初始狀態為空陣列)
- 在
methods
新增方法:
1 | filterData: function(){ |
⚠️ match()
方法:
用於在字串中檢索指定的值,此方法類似 indexOf()
,不過它回傳的是指定的值而不是索引值。
- 實際運行
v-for 無法運行的狀況
在 methods
方法中用陣列特性及索引去修改 data
資料是無效的,因為 Vue 無法探測普通的新增屬性。
1 | // 無效的修改方式 |
正確修改的方式是用 Vue.set()
新增 data
裡沒有的資料,用這個方式才能讓資料保持響應式,帶動 View 正常更新。
Vue.set()
第一個參數是陣列名,第二個參數是陣列元素索引值,第三個是要新增的內容。
1 | Vue.set(this.arrayData, 0, { |
v-for 用於純數字
在 HTML 元素上使用 v-for="item in 10"
,並在標籤內用雙花括號包住 item
就能渲染出 1 到 10 的數字。
v-for 用於 <template>
在 <template>
使用 v-for
,可以讓內部的子元素以群組的方式一起疊代。
⚠️ HTML <template>
模板結構:
模板結構中的內容在頁面載入時不受渲染,但可以在運行時使用 JavaScript 實例化。
你可以把 <template>
想成文件裡面,被儲存以待稍後使用的內容片段。在頁面載入時,解析器雖然會處理 <template>
元件的內容,但元素本身並不會被渲染。
<template>
內的內容可以用 JavaScript 抓取節點、複製到要插入的 DOM 之下,類似這樣:
1 | <!-- HTML --> |
1 | // JS |
⚠️ 關於 importNode()
importNode()
是 document
物件的方法,功用是把一個節點從另一個文件(document)複製到該文件以便運用。第二個參數(布林值)必填,如果為 true
,會複製 importNode()
的所有子節點。
參考資料:HTML5 <template>
标签元素简介、<template — HTML> | MDN
v-for 與 v-if 連用
當 v-for
與 v-if
同時綁在一個元素上時,v-for
先執行,接著才執行 v-if
。兩者連用可以從迴圈中過濾出符合條件的結果。不過這樣做會導致畫面上雖然只渲染部分資料,但卻必須巡訪過全部資料才能輸出。
因此 Vue 官方建議在 computed
新增方法,使用 filter()
進行條件過濾,此時 v-for
對應的值要改為 item in 方法名
,比較能提升效能。
另外一個提升效能的方法是把 v-if
放在 v-for
的父層元素,如此一來我們不會再對列表中的每個項目檢查條件,取而代之的是,我們只檢查它一次,且不會在條件不成立的時候運算 v-for
。
下篇要講的是 v-if
、compued
與 watch
、表單細節操作、v-on
細節。