iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 11
0
自我挑戰組

每天來點 Vue.js 吧系列 第 11

Vue Conditional Rendering 條件渲染

tags: Vuejs

v-if

v-if 指令可以決定是否渲染元素,該元素只有在填入的 expressiontruthy 時會渲染。

下方為簡單範例,當 type 被切換時,畫面重新渲染,v-if expressionfalsy 的元素將被銷毀,反之為 truthy 的元素將被建立:

const vm = new Vue({
  name: "vm",
  el: '#app',
  template: `
    <div id="app">
        <p v-if="type === 'A'">渲染這個 ⏰</p>
        <p v-else-if="type === 'B'">渲染那個 ⏱</p>
        <p v-else="type === 'C'">渲染最後 ⏲</p>
    </div>
  `,
  data: {
      type: 'B'
  },
});

更改 type 影響 expression 結果,下圖可以看到如下重新渲染過程:

可與 v-elsev-else-if 連用 ✐

如同 ifelsev-if 可以與指令 v-elsev-else-if 連用。

  • v-else-if 前一個 兄弟元素 需要為 v-ifv-else-if
  • v-else 前一個 兄弟元素 需要為 v-ifv-else-if
const vm = new Vue({
  name: "vm",
  el: '#app',
  template: `
    <div id="app">
        <p v-if="type === 'A'">渲染這個 ⏰</p>
        <p v-else-if="type === 'B'">渲染那個 ⏱</p>
        <p v-else="type === 'C'">渲染最後 ⏲</p>
    </div>
  `,
  data: {
      type: 'B'
  },
});

可以使用在 <template>,條件渲染多個內容 ✐

若要同時條件渲染多個元素,可以使用 <template> 包裹。

const vm = new Vue({
  name: "vm",
  el: "#app",
  template: `
    <div id="app">
        <template v-if="loginType === 'username'">
            <label>Username</label>
            <input placeholder="Enter your username" >
        </template>
        <template v-else>
            <label>Email</label>
            <input placeholder="Enter your email address">
        </template>
        <button @click="change">BTN</button>
    </div>
  `,
  data: {
    loginType: "username",
  },
  methods: {
    change() {
      this.loginType = "other";
    },
  },
});

可以使用 key 管理複用元素 ✐

Vue 會高效的渲染元素,通常會 復用 既有元素並且 重新渲染 部分 相異之處 而非 從頭渲染,這帶給我們更為高效的渲染速度,但是在部分情況下,也會帶來問題。渲染 input 時,由於並非從頭渲染,而是替換掉了 placeholder,在切換時 value 仍然存留,會帶來以下問題:

我們可以看到由於渲染時並非重新渲染的整個 input 而是替換了 placeholder,於是用戶輸入的 value 仍存在。

此時可以使用 key 來解決該問題,表達元素是 完全獨立 的,Vue 遇到 key 時會基於 key 變化重新排列元素順序,並且移除 key 不存在的元素。

更改後加上 key 的代碼:

const vm = new Vue({
  name: "vm",
  el: "#app",
  template: `
    <div id="app">
        <template v-if="loginType === 'username'">
            <label>Username</label>
            <input placeholder="Enter your username" key="user">
        </template>
        <template v-else>
            <label>Email</label>
            <input placeholder="Enter your email address"  key="email">
        </template>
        <button @click="change">BTN</button>
    </div>
  `,
  data: {
    loginType: "username",
  },
  methods: {
    change() {
      this.loginType = "other";
    },
  },
});

可以看到 input 綁上 key 後,被整個重新渲染,剛剛的問題也迎刃而解。

v-show ✐

同樣是條件,v-show 是使用 display:none 決定元素是否顯示在畫面中,元素始終會被渲染。

const vm = new Vue({
  name: "vm",
  el: "#app",
  template: `
      <div id="app">
        <label v-show="value">A</label>
        <label v-show="!value">B</label>
        <button @click="change">BTN</button>
      </div>
    `,
  data: {
    value: false,
  },
  methods: {
    change() {
      this.value = !this.value;
    },
  },
});

透過切換 displayv-show 得以達到切換元素顯現的效果。

結論 ✐

同為條件渲染,v-ifv-show 差別總結如下:

  • v-if 所條件渲染的元素會隨 expression 渲染、銷毀,並且確保相關的事件監聽器、子組件被適當地銷毀、重建,總結來說 v-if 有更高的切換開銷,每切換一次就要重新渲染,不適用於頻繁切換的元素。
  • v-show 所條件渲染的元素總是渲染,使用 CSS 進行切換。v-show初始渲染成本較高,但是切換時開銷不高,適用於頻繁切換顯示的元素。

以上為此次內容,感謝看到這裡的你,我們明天見。


若是文中有任何錯誤、錯字、想討論的內容,歡迎各位大大不吝鞭笞指正、交流分享,筆者不慎感激 ✦ ✦ ✦

▶︎ 筆者 github:https://github.com/YUN-RU-TSENG
▶︎ 老王賣瓜之筆者另一篇鐵人:每天來點 CSS Specification

▶︎ 倘若不斷向深處扎根,似乎就能茁壯成長 - RM


參考資料:

  1. Vuejs.org 2.x
  2. Vue.js: 條件渲染 v-if、v-show | Summer。桑莫。夏天

上一篇
Vue Class Bindings
下一篇
Vue 事件處理
系列文
每天來點 Vue.js 吧30

尚未有邦友留言

立即登入留言