专栏首页程序员LIYI23 列表渲染与“就地复用”原则

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

目录

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

遍历数组

<!-- 一般遍历数组 -->
<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,在数组遍历与对象遍历中是通用的。

<!-- 使用 of -->
<li v-for="(item,index) of items">{{index}} {{ item.message }}</li>

遍历对象

<!-- 遍历对象 -->
<li v-for="(value,name,index) of object">{{ index }}. {{ name }}: {{ value }}</li>

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

使用值范围

<!-- 使用值范围 -->
<div>
  <span v-for="n in 10">{{ n }} </span>
</div>

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

组件的“就地复用”原则

官档上有这么一段语:

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

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

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

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

<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加一个默认值:

<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 列表渲染与“就地复用”原则

本文分享自微信公众号 - 程序员LIYI(CoderLIYI),作者:石桥码农

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-01-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Vue 全家桶、原理及优化简议

    使用过vue的程序员一般这样评价它,“vue.js兼具angular.js和react.js的优点”。Vue.js 是一个JavaScript MVVM(Mod...

    程序员LIYI
  • 石桥码农:Vue3 与 Vue2 在响应机制的实现上有什么差别?

    vue 开发者可能都遇到过这样一个问题:如果模板中数据绑定的是一个数组,我们在 js 代码里面,直接以索引方式改变数组元素的值,有时候视图并不会按照我们的期许更...

    程序员LIYI
  • 12 手写配置启动一个 vue2 项目

    2019年10月5日,vue 团队发布了 Vue3.0 预览版源码,预计到 2020 年第一季度将发布 3.0 正式版。3.0 包涵了许多激动人心的新特性。

    程序员LIYI
  • Dubbo详细介绍与安装使用过程

    随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。

    Java高级攻城狮
  • Dubbo详细介绍与安装使用过程

    1 Dubbo介绍 1.1 dubbox简介 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟...

    MonroeCode
  • Dubbo详细介绍与安装使用过程

    随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。

    MonroeCode
  • 从零开始一起学习SLAM | 不推公式,如何真正理解对极约束?

    版权声明:本文为博主原创文章,未经博主允许不得转载。违者必究。 https://blog.c...

    用户1150922
  • Github表情符(Emoji)

    在Github中可以在 Pull Requests, Issues, 提交消息, Markdown 文件里加入表情符。使用方法 :name_of_emoji:。

    Joel
  • ​【LeeCode 中等 矩阵】面试题 01.07. 旋转矩阵

    给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。

    不太灵光的程序员
  • 2018-12-20 一文读懂UML 类图class diagram

    在UML类图中,常见的有以下几种关系:泛化(Generalization), 实现(Realization),关联(Association),聚合(Aggre...

    Albert陈凯

扫码关注云+社区

领取腾讯云代金券