从入门到项目实战 - Vue 列表渲染

简介: 从入门到项目实战 - Vue 列表渲染


Vue 列表渲染



1. 列表渲染基础

1.1 什么是列表渲染

列表渲染是一种将一个数组、字符串、对象、数字以一定的方式展开成多个项目渲染到页面上的方式。

1.2 基本用法举例

1.2.1 数组

<ol>
  <li v-for="(item, index) in ['A', 'B', 'C']">item = {{ item }}, and index = {{ index }}</li>
</ol>

其渲染效果为:

注意:

  • 使用 v-for ... inv-for ... of 都可以,它们没有区别。(后文不在赘述)

1.2.2 数字

v-for 可以直接接受一个整数值,这相当于接受一个从 1 开始到该整数的数组。例如:

<ol>
  <li v-for="(number, index) in 3">number = {{number}}, and index = {{index}}</li>
</ol>

其渲染效果为:

注意:

  • index 和 所遍历项的数字在值上看,总是index比遍历项少1,因为 index 是从 0 开始计算而遍历项是从1开始算的。

1.2.3 字符串

v-for 指令可以遍历一个字符串。例如:

<ol>
  <li v-for="(item, index) of str">item = {{ item }}, and index = {{ index }}</li>
</ol>

其渲染效果为:

1.2.4 对象

v-for 指令在遍历一个对象时,将使用 JavaScript 对象的 属性名(键)作为遍历时的 index,使用 与该 属性名 对应的 作为遍历项,例如:

<ol>
  <li v-for="(item, index) of { J: 'ack', B: 'ush', A: 'lice' }">index = {{ index }}, and item = {{ item }}</li>
</ol>

其渲染效果为:

1.2.5 集合(Set)

集合(Set)是 ECMA Script 6 中定义的一个存储任何类型的唯一值的类型,它最常用于对一个数组进行去重。比如:

const s = new Set(["张三", "李四", "王五", "李四", "王五"])
console.log(s);
console.log([...s]);

Out[]:

{ "Set(3)": [ "张三", "李四", "王五" ] }
[ "张三", "李四", "王五" ]

使用 v-for 遍历一个集合的例子如下:

const s = new Set(["张三", "李四", "王五", "李四", "王五"])
<ol>
  <li v-for="(item, index) of s">item = {{ item }}, and index = {{ index }}</li>
</ol>

其渲染效果为:

1.2.6 映射(Map)

提示: 在编程语言中的 Map 含义不是地图,而是映射,这也是该单词最原始的含义。

映射(Map)是 ECMA Script 6 中定义的一个用于存储键值对的类型,任何值(对象或者基本类型)都可以作为一个键或一个值。虽映射像对象那样,具有键值对的使用形式,使用 v-for 遍历一个 映射 与遍历一个数组的不同之处在于,遍历映射时将以从 0 开始的整数索引值作为 index,使用 [key, word] 形式的数组作为遍历项。例如:

const m = new Map()
m.set('张', '三');
m.set('李', '四');
m.set('王', '五');
<ol>
  <li v-for="(item, index) of m">item = {{ item }}, and index = {{ index }}</li>
</ol>

其渲染效果为:

2. 数组渲染进阶

2.1 列表渲染中的 key 属性

2.1.1 key 属性于虚拟DOM 的更新规则

key 是 vue 中虚拟 DOM 所使用的对象标识,当数据发生变化时,Vue 会根据 新数据 生成 新的 虚拟 DOM,然后对从上到下从外到内从左到右对虚拟DOM进行扫描,对于某一个虚拟DOM,新的虚拟 DOM 与 旧的虚拟 DOM 进行差异比较。比较方式为:

  • 先比较新旧虚拟 DOM 的 key 属性:
  • 如果新的虚拟DOM中key 不存在与 旧的虚拟DOM中,则:
    将该新的虚拟 DOM 更新到内存做为新的虚拟DOM,同时渲染到页面为新的真实DOM。
  • 如果新的虚拟DOM的 key 属性值存在于 旧的虚拟DOM 中,则:从前到后比较该虚拟DOM的所有内容(子元素)。
  • 如果内容没变,则:直接使用旧的虚拟DOM。
  • 如果内容改变,则在内容改变处更新虚拟DOM,将将其渲染为新的真实DOM。
  • 对于内容的内容依次方式递归处理。

2.1.2 省略 key 时可能出现的问题

很多时候的确不写 key 属性也能实现我们需要的效果,比如:

const data = ["尔康", "尔泰", "紫薇", "小燕子"];
<ul>
  <li v-for="(item, index) in data">{{ item }}</li>
</ul>

虽然我们没有指定key属性,但是效果依然可以正常渲染:

然而

2.1.3 使用 index 作为 key 可能出现的问题

多数情况下我们的确可以直接使用 index 作为 v-for 遍历所需的 key 使用,例如给定一个三级手风琴目录数据如下:

const menu = [
  { title: "一级目录1", childern: [
      { title: "1-1" },
      { title: "1-2" },
    ]
  },
  { title: "一级目录2" },
  { title: "一级目录3", childern: [
      {
        title: "3-1", childern: [
          { title: "3-1-1" },
          { title: "3-1-2" },
        ]
      },
      { title: "3-2" },
    ]
  }
]

我们对数据逐层进行展开:

<ul>
  <li v-for="(menu1, index1) in menu" :key="index1">
    <p>{{ menu1.title }}</p>
    <ul v-if="menu1.childern">
      <li v-for="(menu2, index2) in menu1.childern" :key="index2">
        <p>{{ menu2.title }}</p>
        <ul v-if="menu2.childern">
          <li v-for="(menu3, index3) in menu2.childern" :key="index3">
            <p>{{ menu3.title }}</p>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

其渲染效果为:

在 2.1.1 节中我们知道

2.1.4 开发中如何选择 key

在上面,我们讨论了两种和虚拟DOM有关的问题:

  1. 若列表渲染中存在逆序增减项目等类似 破环原先渲染项顺序 的更新行为:
    将产生没有必要的真实DOM更新,降低页面渲染效率。
  2. 若列表渲染中,渲染项还包含了表单。在破环顺序的曾减项时:
    将导致表单错位等意外情形发生。

在 Vue 中,key 属性是用于给 vue 框架标识虚拟DOM用的。为了避免上述非预期情况的发生,我们应该 使用能够唯一标识每条数据的值作为数据项们的 key 属性值。通过这种方式:

  1. 对于逆序增减等破坏顺序的操作:
    由于 key 属性标明了各条数据的唯一标识,Vue 能够正确识别后面没有改动的DOM,不会对这些不需要改动的 虚拟DOM 对于更新渲染到 真实DOM。
  2. 对于不仅破坏顺序,而且存在表单的情形:
    由于Vue能够正确唯一识别每一条 虚拟DOM 项,一旦虚拟DOM变化,Vue不会去检查包含表单子项的改动。这些表单往往又是有状态的,即当用户在真实DOM的表单上改变了这些表单值时,虚拟DOM却不会改变,Vue也不会知道这些变动。
    通过人为地添加每项地唯一标识 key,Vue不再需要检查子项内容而错误更新,直接更新破坏顺序增减地整项,就避免了这种更新错乱地行为发生。

因此 找到能够唯一标识每条数据的值作为数据项们的 key 属性值 就成了提高渲染效率、避免更新错误地关键。那么采用什么作为列表渲染中数据项地 key 呢?

一般在实际开发中,合格地后端都需要给前端返回一个每条数据的唯一标识,这个标识往往能在 数据库 中唯一的确定该条数据,这样不论什么时候从后端请求跟新的新数据都能够唯一识别这条数据。比如,在一个标识用户信息的数据表中,昵称往往是重复的,用户id是唯一的,那么就可以使用用户id作为key。

2.2 避免同一个元素上与 v-if 联用

目录
相关文章
|
6天前
|
移动开发 JavaScript API
Vue Router 核心原理
Vue Router 是 Vue.js 的官方路由管理器,用于实现单页面应用(SPA)的路由功能。其核心原理包括路由配置、监听浏览器事件和组件渲染等。通过定义路径与组件的映射关系,Vue Router 将用户访问的路径与对应的组件关联,支持哈希和历史模式监听 URL 变化,确保页面导航时正确渲染组件。
|
10天前
|
监控 JavaScript 前端开发
ry-vue-flowable-xg:震撼来袭!这款基于 Vue 和 Flowable 的企业级工程项目管理项目,你绝不能错过
基于 Vue 和 Flowable 的企业级工程项目管理平台,免费开源且高度定制化。它覆盖投标管理、进度控制、财务核算等全流程需求,提供流程设计、部署、监控和任务管理等功能,适用于企业办公、生产制造、金融服务等多个场景,助力企业提升效率与竞争力。
60 12
|
6天前
|
JavaScript 前端开发 开发者
Vue中的class和style绑定
在 Vue 中,class 和 style 绑定是基于数据驱动视图的强大功能。通过 class 绑定,可以动态更新元素的 class 属性,支持对象和数组语法,适用于普通元素和组件。style 绑定则允许以对象或数组形式动态设置内联样式,Vue 会根据数据变化自动更新 DOM。
|
6天前
|
JavaScript 前端开发 数据安全/隐私保护
Vue Router 简介
Vue Router 是 Vue.js 官方的路由管理库,用于构建单页面应用(SPA)。它将不同页面映射到对应组件,支持嵌套路由、路由参数和导航守卫等功能,简化复杂前端应用的开发。主要特性包括路由映射、嵌套路由、路由参数、导航守卫和路由懒加载,提升性能和开发效率。安装命令:`npm install vue-router`。
|
2月前
|
JavaScript
vue使用iconfont图标
vue使用iconfont图标
147 1
|
27天前
|
JavaScript 安全 API
iframe嵌入页面实现免登录思路(以vue为例)
通过上述步骤,可以在Vue.js项目中通过 `iframe`实现不同应用间的免登录功能。利用Token传递和消息传递机制,可以确保安全、高效地在主应用和子应用间共享登录状态。这种方法在实际项目中具有广泛的应用前景,能够显著提升用户体验。
54 8
|
28天前
|
存储 设计模式 JavaScript
Vue 组件化开发:构建高质量应用的核心
本文深入探讨了 Vue.js 组件化开发的核心概念与最佳实践。
74 1
|
3月前
|
JavaScript 前端开发 开发者
vue 数据驱动视图
总之,Vue 数据驱动视图是一种先进的理念和技术,它为前端开发带来了巨大的便利和优势。通过理解和应用这一特性,开发者能够构建出更加动态、高效、用户体验良好的前端应用。在不断发展的前端领域中,数据驱动视图将继续发挥重要作用,推动着应用界面的不断创新和进化。
111 58
|
2月前
|
JavaScript 关系型数据库 MySQL
基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。
|
3月前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
66 1
vue学习第一章

热门文章

最新文章