【Vue】条件渲染&列表渲染来啦(下)

简介: 【Vue】条件渲染&列表渲染来啦(下)

官网的介绍

image-20230821000956765

索引

可以通过第二个参数获得索引值

<div v-for="(item, index) in list"></div>

上面的key也可以根据索引来定义

<div v-for="(item, index) in list"></div>

这里可能会有问题,能用index作为key吗?也可以,但是不推荐!

比如下面案例

<li v-for="(item, index) in list" :key="index">
  {{ item }}
</li>

使用 index 作为 key 存在以下问题:

  • 列表重新排序时,元素的 key 会变化,导致状态混乱(比如新添加一个索引为0索引的小索奇,它就替代了初始索引为0的张三,与原来进行对比,发现张三被小索奇怼跑了,这不闹的吗?)
  • 不能准确判断变化的原因是索引变还是数据变
  • 删除元素时,产生的新索引不会跟踪到原元素

正确写法,还是建议绑定到item.id身上,使用每一项数据中稳定且唯一的标识作为 key!

注意以面试题形式存在

image-20230821002410628

拓展Diff算法

key是虚拟DOM对象的标识,当数据变化时,Vue就会根据新数据生成新的虚拟DOM

diff 算法是 Vue 和 React 等虚拟 DOM 框架实现高效 DOM 更新的关键算法它可以增量更新视图,避免重新渲染整个 DOM 树

diff算法的基本原理是:

  1. 将当前虚拟 DOM 和上一次虚拟 DOM 进行对比,找出变化的内容(没有变化的直接就复用了)
  2. 如果在旧虚拟节点中未找到与新虚拟节点相同的key,那么直接创建新的虚拟DOM,进行渲染,如果key同,那么就对比内容
  3. 不直接操作 DOM,而是将变化记录到一个JS 对象中
  4. 将这些变化一次性更新到实际的 DOM树上

简单示例

diff算法对比会发现,只需要将 B 换成 C 即可,无需重新渲染整个 UL这样避免了不必要的 DOM 操作

<!-- 上次虚拟DOM --> 
<ul>
  <li>A</li>
  <li>B</li>
</ul>
<!-- 当前虚拟DOM -->
<ul>
  <li>A</li>
  <li>C</li>  
</ul>

Vue 和 React 都使用类似的 diff 算法实现最小化更新实际 DOM 的目的,这带来非常高的性能优势

image-20230821005540298

数组更新检测

Vue包含一系列观察数组变异方法来响应式更新视图

像push、pop、splice等方法

列表过滤

用两组代码分别实现过滤效果

watch实现

    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:'男'}
     ],
     //存放过滤后的新数组
     filPerons:[]
    },
    watch:{
     keyWord:{
      immediate:true,
      handler(val){
       this.filPerons = this.persons.filter((p)=>{
      // 返回一个布尔值
        return p.name.indexOf(val) !== -1
       })
      }
     }
    }
   })

computed实现

 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:{
     filPerons(){
     // 计算属性必备return 
      return this.persons.filter((p)=>{
      // 返回一个布尔值,计算属性没有newValue属性,但可以通过用户输入的值来拿
       return p.name.indexOf(this.keyWord) !== -1
      })
     }
    }
   })

初始时计算属性会默认调用get,当依赖的数据变化时,计算属性也会自动调用~从而实现过滤

当computed和watch都能实现时,优先考虑computed

拓展filter

filter方法的作用是:

  • 它接收一个函数作为参数,这个函数会逐个处理数组中的每个元素
  • 函数返回一个布尔值,true表示保留该元素,false表示过滤掉该元素
  • filter会返回一个新数组,包含执行函数返回true的元素
  • 下面示例中的name代表callback函数的参数,表示当前正在遍历到的数组元素
const names = ['王美丽', '李小福', '张快乐', '赵细腻', '吉祥如意', '康健壮'];
const longNames = names.filter(name => name.length > 3);
const loudLongNames = longNames.map(name => name.toUpperCase()); 
console.log(loudLongNames);
// 输出:['李小福', '张快乐', '赵细腻', '吉祥如意']

这里我们过滤出了长度大于3个字的中文名字,然后把它们转换成大写,这里仅仅为了多用一个方法~

filter 最典型的用途就是过滤数组,接受判断条件并返回过滤后的新数组,

列表排序

案例:实现过滤+排序

  <div id="root">
    <h2>人员列表</h2>
    <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="(p,index) of filPerons" :key="p.id">
        {{p.name}}-{{p.age}}-{{p.sex}}
        <input type="text">
      </li>
    </ul>
  </div>
  <script type="text/JS">
    Vue.config.productionTip = false
    new Vue({
      el:'#root',
      data:{
        keyWord:'',
        sortType:0, //0原顺序 1降序 2升序
        persons:[
          {id:'001',name:'马冬梅',age:30,sex:'女'},
          {id:'002',name:'周冬雨',age:31,sex:'女'},
          {id:'003',name:'周杰伦',age:18,sex:'男'},
          {id:'004',name:'温兆伦',age:19,sex:'男'}
        ]
      },
      computed:{
        filPerons(){
          const arr = this.persons.filter((p)=>{
            return p.name.indexOf(this.keyWord) !== -1
          })
          //判断一下是否需要排序
          if(this.sortType){
            arr.sort((p1,p2)=>{
              return this.sortType === 1 ? p2.age-p1.age : p1.age-p2.age
            })
          }
          return arr
        }
      }
    }) 
  </script>

image.png

拓展

Arrays.sort()

const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
// output: Array ["Dec", "Feb", "Jan", "March"]
const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);
// output: Array [1, 100000, 21, 30, 4]

如果提供了 比较函数compareFn,所有非 undefined 的数组元素都会按照比较函数的返回值进行排序,所有的 undefined 元素都会被排序到数组的末尾,并且不调用 compareFn

image-20230822221418048

简单案例

 let arr = [66,99,88]
          arr.sort((a,b)=>{
           // 前-后就是升序,相反则降序
              return a-b
          })
  console.log(arr)
// [66, 88, 99]

如果对你有用,请点个免费的爱心叭~

相关文章
|
5天前
|
缓存 JavaScript 前端开发
vue学习第四章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中计算属性的基本与复杂使用、setter/getter、与methods的对比及与侦听器的总结。如果你觉得有用,请关注我,将持续更新更多优质内容!🎉🎉🎉
vue学习第四章
|
5天前
|
JavaScript 前端开发
vue学习第九章(v-model)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript与Vue的大一学生,自学前端2年半,正向全栈进发。此篇介绍v-model在不同表单元素中的应用及修饰符的使用,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
vue学习第九章(v-model)
|
5天前
|
JavaScript 前端开发 开发者
vue学习第十章(组件开发)
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文深入讲解Vue组件的基本使用、全局与局部组件、父子组件通信及数据传递等内容,适合前端开发者学习参考。持续更新中,期待您的关注!🎉🎉🎉
vue学习第十章(组件开发)
|
10天前
|
JavaScript 前端开发 UED
vue学习第二章
欢迎来到我的博客!我是一名自学了2年半前端的大一学生,熟悉JavaScript与Vue,目前正在向全栈方向发展。如果你从我的博客中有所收获,欢迎关注我,我将持续更新更多优质文章。你的支持是我最大的动力!🎉🎉🎉
|
10天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。自学前端2年半,熟悉JavaScript与Vue,正向全栈方向发展。博客内容涵盖Vue基础、列表展示及计数器案例等,希望能对你有所帮助。关注我,持续更新中!🎉🎉🎉
|
10天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
11天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
11天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
11天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。
|
12天前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。