【Vue 快速入门系列】列表的基本使用

简介: 【Vue 快速入门系列】列表的基本使用

前言


本篇文章讲述Vue中最基本的列表使用,如何迭代列表取值,如何对列表进行过滤、排序等。


列表的基本使用


在Vue中使用列表的时候灰常简单,只需要将Vue属性内的列表数据与dom标签进行绑定即可,使用固定的指令v-for可以迭代列表并渲染出包含数据的dom元素。以下是v-for指令的基本用法:

v-for的用法:


   用于展示列表数据
   语法:v-for="(p.index) in[of] xxx" :key="..."
   这里的xxx可以是数组、对象、字符串、指定的循环次数
   这个key的作用官方是这么解释的
   key属性主要用在Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes;
   如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法;
   而使用key时,它会基于key的变化重新排列元素顺序,并且会移除/销毁key不存在的元素;
   后面会针对性分析key的用处与原理,以及vue的diff算法。


效果如下:

9d8ff94a8dbe41ca8851ad6ee2f619be.png


代码:


<!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>
    <script type="text/javascript" src="../js/vue.js"></script>
    <style>
        li{
            font-size: 25px;
        }
    </style>
</head>
<body>
    <div id="demo">
        <!-- 遍历数组 -->
        <ul>
            <li v-for="p in persons" :key="p.id">
                {{p.id}}--{{p.name}}--{{p.age}}
            </li>
        </ul>
        <!-- 遍历对象 -->
        <ul>
            <li v-for="(k,v) in school">
                {{v}}:{{k}}
            </li>
        </ul>
        <!-- 遍历字符串 -->
        <ul>
            <li v-for="(p,index) in s">
                {{index}}:{{p}}
            </li>
        </ul>
        <!-- 遍历指定次数 -->
        <ul>
            <li v-for="(p,index) of n">Hello{{p}}:{{index}}</li>
        </ul>
    </div>
</body>
<script>
    let vm=new Vue({
        el:"#demo",
        data:{
            // 准备工作数组
            persons:[
                {id:"001",name:"张三",age:40},
                {id:"002",name:"张四",age:44},
                {id:"003",name:"张五",age:45},
                {id:"004",name:"李三",age:45},
                {id:"005",name:"李四",age:40},
                {id:"006",name:"李五",age:44},
                {id:"007",name:"王三",age:45},
                {id:"008",name:"王四",age:45},
                {id:"009",name:"王五",age:45}
            ],
            //准备工作对象
            school:{
                name:"南阳理工学院",
                cls:"工科",
                include:"15个教学院"
            },
            // 准备工作字符串
            s:"Hello",
            // 准备工作循环次数 
            n:5
        }
    })
</script>
</html>


Key的原理


先来看一个面试题:react、vue中的key有什么作用?(key的内部原理)


1. 虚拟DOM中key的作用:
    key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 
    随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
2.对比规则:
    (1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
      ①.若虚拟DOM中内容没变, 直接使用之前的真实DOM!
      ②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
    (2).旧虚拟DOM中未找到与新虚拟DOM相同的key
      创建新的真实DOM,随后渲染到到页面。
3. 用index作为key可能会引发的问题:
    1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:
            会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。
    2. 如果结构中还包含输入类的DOM:
            会产生错误DOM更新 ==> 界面有问题。
4. 开发中如何选择key?:
    1.最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
    2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,
      使用index作为key是没有问题的。


列表过滤


列表过滤实际是一个模糊搜索得过程,通过filter过滤器将需要的数据筛选出来
过滤方式有两种:
  数据监视:
    通过监视搜索框内的数据是否变化,一旦有了变化立即进行筛选
  计算属性:
    将要展示得内容作为计算属性,进行筛选,当搜索框的数据有变化时就对要展示得内容进行计算


过滤之前:5c440086e62544448e1c55d1fcf9151b.png


过滤之后:

6e342d9a0f0a4c5d90217ebb241f44db.png

原理:
监视搜索框绑定的属性,当属性值发生变化之后就对展示的列表进行过滤,列表是Vue的属性,所以改变之后会重新渲染页面。


源代码:


<!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>
    <script type="text/javascript" src="../js/vue.js"></script>
    <style>
        table{
            width: 100%;
        }
    </style>
  </head>
  <body>
    <div id="demo">
      搜索:<input type="text" v-model="searched" />
      <table border="true">
        <tr>
          <th>学号</th>
          <th>姓名</th>
          <th>年龄</th>
        </tr>
        <tr v-for="p in templs">
          <th>{{p.id}}</th>
          <th>{{p.name}}</th>
          <th>{{p.age}}</th>
        </tr>
      </table>
    </div>
  </body>
  <script>
    let vm = new Vue({
      el: "#demo",
      data: {
        searched: "",
        persons: [
          { id: "001", name: "张三", age: 40 },
          { id: "002", name: "张四", age: 44 },
          { id: "003", name: "张五", age: 45 },
          { id: "004", name: "李三", age: 45 },
          { id: "005", name: "李四", age: 40 },
          { id: "006", name: "李五", age: 44 },
          { id: "007", name: "王三", age: 45 },
          { id: "008", name: "王四", age: 45 },
          { id: "009", name: "王五", age: 45 },
        ]
      },
      //  使用watch监视属性进行实现   
      /*watch:{
        //   这里是个编程小技巧,""空字符串被包含在所由字符串内
        //   如果一个字符串为abc那么a与空字符得索引都为0
        //   可以使用indexOf进行位置得判定
          searched:{
            immediate:true,
            handler(val){
              this.templs=this.persons.filter((p)=>{
                  return (p.name.indexOf(val)!=-1)
              })
            }
          }
      }*/
      //使用计算属性进行实现
      computed:{
          templs(){
              return this.persons.filter((p)=>{
                  return p.name.indexOf(this.searched)!=-1
              })
          }
      }
    });
  </script>
</html>


列表排序


原序:


3a1e768010ee47a094e483358a1bdf2a.png


降序:


f8554ef1daed48f8b98e0ee7f9b5d29e.png


升序:


052f94016bde4d1786820c43cb3329a5.png


除了点击按钮,也实现了先筛选再排序与先排序再筛选,具体的实现算法如下:


<!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>
    <script type="text/javascript" src="../js/vue.js"></script>
    <style>
        table{
            width: 100%;
        }
    </style>
    <!-- 
      加入排序功能,排序与过滤其实需要一块操作
     -->
  </head>
  <body>
    <div id="demo">
      搜索:<input type="text" v-model="searched" />
      <button @click="nammol">点我原序</button>
      <button @click="esc">点我升序</button>
      <button @click="cesc">点我降序</button>
      <table border="true">
        <tr>
          <th>学号</th>
          <th>姓名</th>
          <th>年龄</th>
        </tr>
        <tr v-for="p in templs">
          <th>{{p.id}}</th>
          <th>{{p.name}}</th>
          <th>{{p.age}}</th>
        </tr>
      </table>
    </div>
  </body>
  <script>
    let vm = new Vue({
      el: "#demo",
      data: {
        searched: "",
        persons: [
          { id: "001", name: "张三", age: 40 },
          { id: "002", name: "张四", age: 44 },
          { id: "003", name: "张五", age: 45 },
          { id: "004", name: "李三", age: 45 },
          { id: "005", name: "李四", age: 40 },
          { id: "006", name: "李五", age: 44 },
          { id: "007", name: "王三", age: 45 },
          { id: "008", name: "王四", age: 45 },
          { id: "009", name: "王五", age: 45 },
        ],
        tag:0,  //0原顺序 1升序 2降序
        templs:[]
      },
      methods: {
        nammol() {
          this.tag=0
        },
        esc(){
          this.tag=1
        },
        cesc(){
          this.tag=2
        }
      },
      //  使用watch监视属性进行实现数据的筛选及排序
      watch:{
          // 如果只监测一个search属性得话,没有办法在点击排序的时候进行排序
          searched:{
          //页面初次装载完毕执行一次。
            immediate:true,
            handler(val){
              this.templs=this.persons.filter((p)=>{
                  return (p.name.indexOf(val)!=-1)
              })
              if (this.tag){
                this.templs.sort((v1,v2)=>{
                  return this.tag===1?v2.age-v1.age:v1.age-v2.age
                })
              }
            }
          },
          //针对已经过滤出来的数据进行排序,如果是原序输出就重新筛选一遍(如果不写这个当tag做出改变的时候并不会有dom响应)
          tag:{
            handler(){
              if (this.tag){
                this.templs.sort((v1,v2)=>{
                  return this.tag===1?v2.age-v1.age:v1.age-v2.age
                })
              }
              else{
                this.templs=this.persons.filter((p)=>{
                  return (p.name.indexOf(this.searched)!=-1)
              })
              }
            }
          }
      }
      //使用计算属性进行实现
      // computed:{
      //     templs(){
      //         const temp= this.persons.filter((p)=>{
      //             return p.name.indexOf(this.searched)!=-1
      //         })
      //         if (this.tag){
      //           temp.sort((v1,v2)=>{
      //             return this.tag===1?v2.age-v1.age:v1.age-v2.age
      //           })
      //         }
      //         return temp
      //     }
      // }
    });
  </script>
</html>



相关文章
|
3天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
4天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
4天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
4天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。
|
3天前
|
JavaScript 前端开发 UED
vue学习第二章
欢迎来到我的博客!我是一名自学了2年半前端的大一学生,熟悉JavaScript与Vue,目前正在向全栈方向发展。如果你从我的博客中有所收获,欢迎关注我,我将持续更新更多优质文章。你的支持是我最大的动力!🎉🎉🎉
|
5天前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。
|
3天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。自学前端2年半,熟悉JavaScript与Vue,正向全栈方向发展。博客内容涵盖Vue基础、列表展示及计数器案例等,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
|
JavaScript
快速入门vue,爆肝一万多字,“建议收藏”,用到省的百度了(含实战案例)
快速入门vue,爆肝一万多字,“建议收藏”,用到省的百度了(含实战案例)
121 0
|
5天前
|
存储 JavaScript
Vue 组件间如何通信
Vue组件间通信是指在Vue应用中,不同组件之间传递数据和事件的方法。常用的方式有:props、自定义事件、$emit、$attrs、$refs、provide/inject、Vuex等。掌握这些方法可以实现父子组件、兄弟组件及跨级组件间的高效通信。
|
10天前
|
JavaScript
Vue基础知识总结 4:vue组件化开发
Vue基础知识总结 4:vue组件化开发