前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >23 列表渲染与“就地复用”原则

23 列表渲染与“就地复用”原则

作者头像
LIYI
发布2020-02-13 11:59:03
2.2K0
发布2020-02-13 11:59:03
举报
文章被收录于专栏:艺述论专栏艺述论专栏
代码语言:javascript
复制
目录

遍历数组
遍历对象
使用值范围
组件的“就地复用”原则
源码

遍历数组

代码语言:javascript
复制
<!-- 一般遍历数组 -->
<li v-for="item in items">{{ item.message }}</li>
<!-- 使用数组中的索引 -->
<li v-for="(item,index) in items">{{index}} {{ item.message }}</li>

遍历一个数组时,第二个参数是当起项的零起索引值,一般用这个参数做为key。

除了使用for in,还可以使用for of。以of代替in,在数组遍历与对象遍历中是通用的。

代码语言:javascript
复制
<!-- 使用 of -->
<li v-for="(item,index) of items">{{index}} {{ item.message }}</li>

遍历对象

代码语言:javascript
复制
<!-- 遍历对象 -->
<li v-for="(value,name,index) of object">{{ index }}. {{ name }}: {{ value }}</li>

如果是遍历对象,除了当前项的值、键名(相当于数组的索引),还有一个当前项在遍历列表所处的位置,也是零起步计算。

使用值范围

代码语言:javascript
复制
<!-- 使用值范围 -->
<div>
  <span v-for="n in 10">{{ n }} </span>
</div>

这纯粹是一个语法糖了,当被遍历的对象是一个数字时,相当于重复渲染n遍。

组件的“就地复用”原则

官档上有这么一段语:

代码语言:javascript
复制
当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。

这种方式只适用于列表渲染不依赖子组件状态,或临时 DOM 状态变化。

这一段不太好理解,特别是最后一句。什么叫不依赖于子组件状态,何为临时DOM状态变化?

有开发者为此写了一个测试示例:

代码语言:javascript
复制
<h3>采用就地复用策略(vuejs默认情况)</h3>
<div v-for="(p, i) in persons">
  {{p.name}}
  <input type="text" />
  <button @click="down(i)" v-if="i != persons.length - 1">下移</button>
</div>

<h3>不采用就地复用策略(设置key)</h3>
<div v-for="(p, i) in persons" :key="p.id">
  {{p.name}}
  <input type="text" />
  <button @click="down(i)" v-if="i != persons.length - 1">下移</button>
</div>
data: () => ({
    persons: [
      { id: 1, name: "AJ" },
      { id: 2, name: "Dandan" },
      { id: 3, name: "Yoko" }
    ],
  }),
methods: {
    down: function(i) {
      if (i == this.persons.length - 1) return;
      var listClone = this.persons.slice();
      var one = listClone[i];
      listClone[i] = listClone[i + 1];
      listClone[i + 1] = one;
      this.persons = listClone;
    }
  }

运行效果:

如果没给列表项添加key,当在输入框输入内容后,单向向下移动,组件移动,数据不移动;如果设置了key,组件与数据同时移动。

以前讲过,这是由于vue源码中判断一个虚拟DOM节点是否可复用,取决于tag与key两个条件,两个都相同,得以复用;两个都不同,不复用。

有同学问,“为什么patchVnode没有覆盖之前节点的value属性呀?”,这是value属性是运行时添加的,不属于data数据源的一部分,在vue实例解析时,value属性没有参与。

为了验证这个想法,我们将源码稍修改一下,不添加key,但是给value加一个默认值:

代码语言:javascript
复制
<div v-for="(p, i) in persons">
  {{p.name}}
  <input :value="p.name" type="text" />
  <button @click="down(i)" v-if="i != persons.length - 1">下移</button>
</div>

这时候再运行,组件下移,数据也下移了:

细心的同学会发现,当随便输入一个数字、改变输入框内容后,单击向下移动,内容又恢复了。

这是由于我们用的是:value="p.name"单向绑定,使用v-model="p.name"代替就可以了。

像使用:value单向绑定的input value就属于运行时的临时DOM状态。这是官档那段话最后一句的所指。

源码

https://git.code.tencent.com/shiqiaomarong/vue-go-rapiddev-example/tags/v202001192

vue-and-go-example/simple-vue-project/src/AboutListRender.vue

参考链接

  • https://www.zhihu.com/question/61078310/answer/361261031
  • https://cn.vuejs.org/v2/guide/list.html

相关阅读

  • 1 如何选择一个 vue ui 框架?
  • 2 梳理 50 年人机交互界面发展史,得出这个规律,开发框架的选择不再迷茫
  • 3 vue 开发常用工具及配置一
  • 4 vue 开发常用工具及配置二
  • 5 vue 开发常用工具及配置三
  • 6 vue 开发常用工具及配置四:推荐一个 mock 工具
  • 7 vue 开发常用工具及配置五:hash 与缓存控制
  • 8 vue 开发常用工具及配置六:认识各种 loader
  • 9 vue 开发常用工具及配置七:处理资源加载问题
  • 10 vue 开发常用工具及配置八:scoped CSS 模块化
  • 11 css 基本功:引入方式及选择器相关
  • 12 手写配置启动一个 vue2 项目
  • 13 声明式渲染与 data 函数
  • 14 上线后不想让人看到源码怎么做?
  • 15 v-if 条件渲染与 v-for 列表渲染
  • 16 处理表单数据与父子组件之间的数据交换
  • 17 vue 组件化基础
  • 18 vue 实例及其双向绑定的实现原理
  • 19 vue 模板语法及简要实现原理
  • 20 vue计算属性和侦听器
  • 21 vue 组件中 Class 的绑定
  • 22 内联样式的绑定
  • 23 列表渲染与“就地复用”原则
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 艺述论 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 遍历数组
  • 遍历对象
  • 使用值范围
  • 组件的“就地复用”原则
  • 源码
  • 参考链接
  • 相关阅读
相关产品与服务
腾讯云小微
腾讯云小微,是一套腾讯云的智能服务系统,也是一个智能服务开放平台,接入小微的硬件可以快速具备听觉和视觉感知能力,帮助智能硬件厂商实现语音人机互动和音视频服务能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档