天天看點

Vue 基礎自查——條件渲染和清單渲染

  1. v-if

    v-show

    的差別是什麼?
  2. v-if

    v-for

    為什麼不能一起用?
  3. v-for

    中的

    key

    有什麼作用?

1 v-if 和 v-show

1.1 作用

都用來控制元素的顯示和隐藏

1.2 控制元素顯隐的方式

v-if

控制虛拟

DOM

樹上元素的建立和銷毀,

Vue

的響應系統會根據虛拟

DOM

樹對實際

DOM

進行更新,進而間接控制實際

DOM

上元素的顯隐

v-show

通過給元素添加樣式

display:none

來讓元素隐藏

1.3 初始渲染對比

v-if

是惰性的,如果初始渲染條件為

false

,什麼都不做;隻有條件為

true

,才會開始編譯

v-show

不管初始渲染條件如何,元素始終被編譯并保留,之後根據條件通過

CSS

切換

1.4 切換消耗對比

如果頻繁切換顯示與隐藏,

v-if

會頻繁建立、銷毀元素,而

v-show

隻是切換樣式

v-if

的切換消耗更高

1.5 使用場景對比

如果元素的顯示隐藏在一開始就定下來不會再變了,使用

v-if

如果元素需要頻繁切換顯隐,使用

v-show

1.6 其他

  • v-if

    可以搭配

    template

    使用,

    v-show

    不可以
  • v-if

    v-else

    v-show

    無特殊文法

2 v-if 和 v-for

2.1 v-if 和 v-for 不能同時用的原因

為什麼不能把

v-if

v-for

同時用在同一個元素上?

當 Vue 處理指令的時候,

v-for

的優先級比

v-if

高,是以這個模闆:

<ul>
  <li v-for="item in list" v-if="item.isActive" :key="item.id">
    {{item.name}}
  </li>
</ul>
           

會經過如下運算:

this.list.map(function(item) {
  if (item.isActive) {
    return item.name
  }
})
           

我們每次重新渲染的時候都要周遊整個清單,即使

isActive

true

item

很少,這會帶來性能方面的極大浪費,是以兩者不能同時用在同一個元素上

2.2 v-if 和 v-for 一起用的解決方案

1、如果想控制整個清單的顯隐,可以将

v-if

移動到容器元素上,比如:

<body>
  <div id="example">
    <ul v-if="listShow">
      <li v-for="item in activeItems" :key="item.id">{{item.name}}</li>
    </ul>
  </div>
</body>
<script>
  const vm = new Vue({
    el: "#example",
    data: {
      list: [
        { id: 1, name: "路飛", isActive: true },
        { id: 2, name: "索隆", isActive: false },
        { id: 3, name: "山治", isActive: true },
      ],
      listShow: false,
    }
  });
</script>
           

2、如果想過濾清單中的項目,可以使用計算屬性(

computed

)傳回過濾後的清單,比如:

<body>
  <div id="example">
    <ul>
      <li v-for="item in activeItems" :key="item.id">{{item.name}}</li>
    </ul>
  </div>
</body>
<script>
  const vm = new Vue({
    el: "#example",
    data: {
      list: [
        { id: 1, name: "路飛", isActive: true },
        { id: 2, name: "索隆", isActive: false },
        { id: 3, name: "山治", isActive: true },
      ],
    },
    computed: {
      activeItems: function () {
        return this.list.filter((item) => item.isActive);
      },
    },
  });
</script>
           

3 清單渲染的 key 有什麼用

在使用

v-for

進行清單渲染時,必須給元素添加一個

key

屬性,并且這個

key

必須是唯一辨別

<ul>
	<li v-for="item in list" :key="item.id">{{item.name}}</li>
</ul>
           

我們知道,Vue 在更新元素時,不會直接操作真實DOM(渲染真實DOM開銷是很大的),而是根據新資料生成新的虛拟 DOM,然後對新舊虛拟DOM進行差異對比,根據對比結果進行DOM操作來更新視圖

清單渲染時,如果有

key

屬性,由于它是唯一辨別,在對比兩個新舊節點時若

key

不同也就沒有深入對比的必要了。

為什麼不能用

index

作為

key

?因為

index

是不穩定可變的,比如删除了清單第一個元素,會導緻後面的元素

index

發生變化,進而導緻

key

發生變化。這時,Vue 在對比新舊節點時,遇到

key

相同的節點,就會進行深入對比,發現節點内容發生了變化,就會去建立新的真實DOM用來替換原來的真實DOM。原本隻需要删除真實DOM中第一個元素的操作,會變成建立、替換後續所有真實DOM,造成性能的極大浪費