[Vue]列表渲染(二)

简介: [Vue]列表渲染(二)

6.3 可以对数组数据进行唯一标识的作为key

6.3.1 示例

在提供的数据数组中,每个对象的 id 可以对该对象进行唯一标识,所以可以使用 id 作为key。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="root">
    <button @click="addPerson">添加</button>
    <ul>
      <li v-for="(person, index) in persons" :key="person.id">
        {{index}}: {{person.name}} -- {{person.age}}
        <input type="text">
      </li>
    </ul>
  </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
  const vm = new Vue({
    el: '#root',
    data: {
      persons: [
        {id: 101, name: 'ZS', age: 18},
        {id: 102, name: 'LS', age: 19},
        {id: 103, name: 'WW', age: 20}
      ]
    },
    methods: {
      addPerson() {
        this.persons.unshift({id: 104, name: 'TOM', age: 21})
      }
    },
  })
</script>
</html>

提供观察结果发现,新的人员信息和新的输入框在加入页面显示后,没有出现不匹配的问题。

6.3.2 解释

6.4 key的作用

  1. 虚拟DOM中key的作用:
  • key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
  • (1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
  • ①.若虚拟DOM中内容没变, 直接使用之前的真实DOM!
  • ②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
  • (2).旧虚拟DOM中未找到与新虚拟DOM相同的key
  • 创建新的真实DOM,随后渲染到到页面。

6.5 用index作为key可能会引发的问题

  1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:
  • 会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。
  1. 如果结构中还包含输入类的DOM:
  • 会产生错误DOM更新 ==> 界面有问题。

如果不对数据进行破坏顺序操作,则使用index作为key不会引发问题。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="root">
    <button @click="addPerson">添加</button>
    <ul>
      <li v-for="(person, index) in persons" :key="idnex">
        {{index}}: {{person.name}} -- {{person.age}}
        <input type="text">
      </li>
    </ul>
  </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script>
  const vm = new Vue({
    el: '#root',
    data: {
      persons: [
        {id: 101, name: 'ZS', age: 18},
        {id: 102, name: 'LS', age: 19},
        {id: 103, name: 'WW', age: 20}
      ]
    },
    methods: {
      addPerson() {
        this.persons.push({id: 104, name: 'TOM', age: 21})
      }
    },
  })
</script>
</html>

6.6 开发中如何选择key

  1. 最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。
  2. 如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的

7. 列表过滤

7.1 监视属性实现

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="root">
      <!-- 使用 v-model 进行双向绑定 获取用户的输入 -->
      <input type="text" placeholder="请输入姓名..." v-model="keyWord" />
      <ul>
        <li v-for="(person, index) in filterPerson" :key="person.id">{{index}}: {{person.name}} -- {{person.age}} -- {{person.sex}}</li>
      </ul>
    </div>
  </body>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
  <script>
    const vm = new Vue({
      el: '#root',
      data: {
        // 保存用户的输入
        keyWord: '',
        persons: [
          { id: '001', name: '马冬梅', age: 19, sex: '女' },
          { id: '002', name: '周冬雨', age: 20, sex: '女' },
          { id: '003', name: '周杰伦', age: 21, sex: '男' },
          { id: '004', name: '温兆伦', age: 22, sex: '男' },
        ],
        // 用于保存过滤后的数组
        filterPerson: [],
      },
      watch: {
        // 监视用户的输入
        keyWord: {
          // 初始化时立即执行一次,
          // 初始用户没有输入,使用空字符串进行过滤,所有的数组元素都保留
          // 显示数组中的全部元素
          immediate: true,
          handler(newVal) {
            // 对数组进行过滤,并将过滤后的结果保存到filterPerson中
            this.filterPerson = this.persons.filter((person) => {
              // 查询姓名中是否包含用户输入的字符串
              // 空字符串会返回0
              // 包含输入的字符串则返回对应的索引
              // 不包含返回-1
              return person.name.indexOf(newVal) !== -1
            })
          },
        },
      },
    })
  </script>
</html>

7.2 计算属性实现

计算属性与监视属性都能实现的功能,优先使用计算属性。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="root">
      <!-- 使用 v-model 进行双向绑定 获取用户的输入 -->
      <input type="text" placeholder="请输入姓名..." v-model="keyWord" />
      <ul>
        <li v-for="(person, index) in filterPerson" :key="person.id">{{index}}: {{person.name}} -- {{person.age}} -- {{person.sex}}</li>
      </ul>
    </div>
  </body>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
  <script>
    const vm = new Vue({
      el: '#root',
      data: {
        // 保存用户的输入
        keyWord: '',
        persons: [
          { id: '001', name: '马冬梅', age: 19, sex: '女' },
          { id: '002', name: '周冬雨', age: 20, sex: '女' },
          { id: '003', name: '周杰伦', age: 21, sex: '男' },
          { id: '004', name: '温兆伦', age: 22, sex: '男' },
        ]
      },
      computed: {
        // 由于页面中使用到了该计算属性,所以页面初始化时会调用一次
        // 由于该计算属性使用了keyWord,所以当keyWord变化时,也会自动调用该计算属性
        filterPerson() {
          // 对数组进行过滤
          return this.persons.filter((person)=>{
            // 判断姓名是否包含用户的输入
            return person.name.indexOf(this.keyWord) !== -1
          })
        }
      }
    })
  </script>
</html>

8. 列表排序

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="root">
      <!-- 使用 v-model 进行双向绑定 获取用户的输入 -->
      <input type="text" placeholder="请输入姓名..." v-model="keyWord" />
      <button @click="sortType = 2">年龄升序</button>
      <button @click="sortType = 1">年龄降序</button>
      <button @click="sortType = 0">原顺序</button>
      <ul>
        <li v-for="(person, index) in filterPerson" :key="person.id">{{index}}: {{person.name}} -- {{person.age}} -- {{person.sex}}</li>
      </ul>
    </div>
  </body>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
  <script>
    const vm = new Vue({
      el: '#root',
      data: {
        // 保存用户的输入
        keyWord: '',
        // 数据显示的顺序
        // 默认为0(原顺序) 1降序 2升序
        sortType: 0,
        persons: [
          { id: '001', name: '马冬梅', age: 19, sex: '女' },
          { id: '002', name: '周冬雨', age: 20, sex: '女' },
          { id: '003', name: '周杰伦', age: 21, sex: '男' },
          { id: '004', name: '温兆伦', age: 22, sex: '男' },
        ],
      },
      computed: {
        filterPerson() {
          // 保存过滤后的数据
          const personArr = this.persons.filter((person) => {
            return person.name.indexOf(this.keyWord) !== -1
          })
          // 对过滤后的数据进行排序
          // 如果需要的数组顺序不为原顺序,则进行排序
          if (this.sortType) {
            // 排序
            personArr.sort((p1, p2) => {
              // 判断是要降序还是升序
              return this.sortType === 1 ? p2.age - p1.age : p1.age - p2.age
            })
          }
          // 然后数组
          return personArr
        },
      },
    })
  </script>
</html>



相关文章
|
17小时前
|
JavaScript 前端开发 测试技术
使用 Vue CLI 脚手架生成 Vue 项目
通过 Vue CLI 创建 Vue 项目可以极大地提高开发效率。它不仅提供了一整套标准化的项目结构,还集成了常用的开发工具和配置,使得开发者可以专注于业务逻辑的实现,而不需要花费大量时间在项目配置上。
53 7
使用 Vue CLI 脚手架生成 Vue 项目
|
2天前
|
JavaScript 算法
“Error: error:0308010C:digital envelope routines::unsupported”启动vue项目遇到一个错误【已解决
“Error: error:0308010C:digital envelope routines::unsupported”启动vue项目遇到一个错误【已解决
8 1
|
2天前
|
JavaScript
error Component name “Login“ should always be multi-word vue/multi-word-component-names【已解决】
error Component name “Login“ should always be multi-word vue/multi-word-component-names【已解决】
6 1
|
2天前
|
JavaScript
vue知识点
vue知识点
10 3
|
3天前
|
JavaScript 前端开发 Java
【vue实战项目】通用管理系统:作业列表
【vue实战项目】通用管理系统:作业列表
16 0
|
JavaScript 测试技术 容器
Vue2+VueRouter2+webpack 构建项目
1). 安装Node环境和npm包管理工具 检测版本 node -v npm -v 图1.png 2). 安装vue-cli(vue脚手架) npm install -g vue-cli --registry=https://registry.
1001 0
|
9天前
|
JavaScript 前端开发 开发者
vue3+ts配置跨域报错问题解决:> newpro2@0.1.0 serve > vue-cli-service serve ERROR Invalid options in vue.
【6月更文挑战第3天】在 Vue CLI 项目中遇到 &quot;ERROR Invalid options in vue.config.js: ‘server’ is not allowed&quot; 错误是因为尝试在 `vue.config.js` 中使用不被支持的 `server` 选项。正确配置开发服务器(如代理)应使用 `devServer` 对象,例如设置代理到 `http://xxx.com/`: ```javascript module.exports = { devServer: {
24 1
|
3天前
|
JavaScript API
【vue实战项目】通用管理系统:信息列表,信息的编辑和删除
【vue实战项目】通用管理系统:信息列表,信息的编辑和删除
20 2
|
3天前
|
JavaScript API
【vue实战项目】通用管理系统:信息列表,信息录入
【vue实战项目】通用管理系统:信息列表,信息录入
10 3
|
3天前
|
JavaScript 前端开发 API
【vue实战项目】通用管理系统:学生列表
【vue实战项目】通用管理系统:学生列表
14 2