跟我一起学Vue3——条件渲染和列表渲染

965 阅读5分钟

前言

⭐️ 本专栏主要内容为「 Vue3官方文档 」的学习过程 ✍🏼

⭐️ 本专栏适合人群:Vue小白、学完一遍Vue的掘友 👨🏼‍💻

⭐️ 本专栏的阅读顺序和官方文档顺序相同 📖

⭐️ 英雄不问出处,这个专栏一定让你收获满满 🥳!

⭐️ 静心,思考,实操,坚持,巩固,满载而归 🥰!

⭐️ 欢迎各位掘友在评论区交流 🤡

第八章 条件渲染

本章主要内容为v-if、v-show、两者区别和v-if与v-for使用的注意点

v-if

当我们使用v-if时,只有当表达式返回值为turthy时才会被渲染

我们不仅可以在html标签上使用,也可以在template元素上使用

<h1 v-if="awesome">Vue is awesome</h1>
<h1 v-else>Vue is not awesome</h1>

<template v-if="ok">
  <h1>Title</h1>
</template>

这里要注意的是v-if的值是下面data中声明的响应式变量,如果data中没有vue会报一个警告

[Vue warn] Property "ok" was accessed during render but is not defined on instance. 

v-else-if

充当 v-if 的“else-if 块”,并且可以连续使用:

<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>

v-elsev-else-if 指令必须紧跟带v-if或v-else-if的元素后面,否则不会被识别,那么v-else或v-else-if 包含的元素就会显露出来,不管前面v-if是真是假。

v-show

用法和v-if大致一样,但是不同的是,带有v-show的元素会被渲染并保留在DOM中。它不显示的原因是CSS property中使用了 display: none,不会占据页面位置。

重排和重绘:v-show会导致页面重绘,而v-if会导致页面重排,因为v-if如果为假值,不会渲染进DOM树,当变成真值后,会渲染进DOM树,进行DOM操作,从而导致了页面重排,性能损耗很大。

注意: v-show不支持<template>元素,也不支持v-else

v-if vs v-show

v-if 会在切换过程中,将条件块内的事件监听起和子组件适当地销毁和重建

v-if在初始渲染时条件为假,则什么也不做。当条件第一次为真,才会开始渲染条件块。

v-show不管初始条件是什么,元素都会被渲染,之后就只做简单地CSS切换

v-if有更高的切换开销,如重排,而v-show有更高的初始渲染开销。

如果需要非常频繁地切换,则使用 v-show 较好

如果在运行时条件很少改变,则使用 v-if 较好

所以,不能一味地使用 v-if 或 v-show,应该视情况混合使用更佳。

v-if 与 v-for 一起使用

不推荐 同时使用 v-if 和 v-for

当他们处于同一节点时,v-if 的优先级比 v-for 更高,这意味着,v-if 将没有权限访问 v-for 内的变量。

一般我们在两种常见的情况下会倾向于这样做

  • 为了对列表中的项目进行过滤,(比如: v-for="user in users" v-if="user.isActive"),在这种情况下,将users替换为一个计算属性,返回过滤后的列表
  • 为了避免渲染本应该隐藏的列表,将 v-if 移动至容器元素上 (比如 ul、 ol)
<ul>
  <li
    v-for="user in activeUsers"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>
<ul>
  <template v-for="user in users" :key="user.id">
    <li v-if="user.isActive">
      {{ user.name }}
    </li>
  </template>
</ul>

第九章 列表渲染

数组映射

用 v-for 指令基于一个数组渲染一个列表

我们可以使用 item in items 形式的特殊语法, items是数组, item是被迭代的数组元素别名

v-for 可以访问所有父作用域的property。v-for 支持可选的第二个参数,即当前项的索引。

也可以使用 of 替代 in 作为分隔符,更接近 js 迭代器的语法

<li v-for="(value, index) in arr"></li>
<li v-for="(value, index) of arr"></li>

对象映射

用 v-for 指令基于一个对象的property渲染一个列表

第二个参数为 property名称 (键名)

第三个参数为 索引

<li v-for="(value, key, index) in obj"></li>

在遍历对象时,会按Object.keys()的结果遍历,不能保证他在不同的JS引擎下的结果都一致

KEY

Vue 在更新v-for渲染的元素列表时,默认使用“就地更新”的策略。

如果数据项顺序被改变,不会移动DOM元素来匹配数据项的顺序,而是更新每个元素,确保在每个索引位置正确渲染。

只适用于不依赖子组件状态,或临时DOM状态的列表渲染输出

为了让Vue能跟踪每个节点的身份,从而重用和重新排序现有元素,需要为每项提供一个唯一的key attribute

不要使用对象或数组之类的非基本类型值作为 v-for 的key。建议使用字符串或数职类型的值

<div v-for="item in items" :key="item.id"></div>

数组更新检测

变更方法

触发试图更新的变更方法

  • push
  • pop
  • shift
  • unshift
  • splice
  • sort
  • reverse

替换数组

比如 filter() 、concat()和slice(),他们会返回一个新的数组,替换旧数组。

Vue 不会丢弃现有DOM并重新渲染整个列表。

显示过滤/排序后的结果

在不改变原来数组的前提下,显示过滤和排序后的数据,我们可以创建一个计算属性,来返回处理后的数组。

如果在计算属性不适用的情况下,也可以使用一个方法,传入数组,返回一个新的数组

支持使用值的范围

v-for 可以接受整数

<div id="range">
  <span v-for="n in 10" :key="n">{{ n }}</span>
</div>

支持在template中使用

<ul>
  <template v-for="item in items" :key="item.msg">
    <li>{{ item.msg }}</li>
    <li class="divider" role="presentation"></li>
  </template>
</ul>

支持组件上使用

<my-component v-for="item in items" :key="item.id"></my-component>

默认任何数据不会传递到自定义组件内,可以通过 props 将迭代数据传递到自定义组件内

<my-component
  v-for="(item, index) in items"
  :item="item"
  :index="index"
  :key="item.id"
></my-component>

结语

专栏同步代码:Github

掘金社区:跟我一起学Vue3

作者简介:

一个满脑子奇怪知识的小商同学,在校ing,懂点设计,懂点排版,为成为一名优秀的前端工程师而努力。