• VUE的列表渲染


    这是我关于VUE的列表渲染的学习笔记如下:
    第一步、我们先初步认识https://www.cnblogs.com/buluzombie/p/15617040.html
    我们要实现列表渲染就要借助于v-for指令来实现。
    其使用方法:
    1.这个指令可以遍历数据进行渲染列表进而展示数据。
    2.其使用格式:语法:v-for=“(item, index) in items” :key=“item.message"或者v-for=”(item, index) of items" :key=“item.message”
    3.v-for可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
    代码案例如下:

    <!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>列表渲染(基本使用)</title>
                      <script type="text/javascript" src="../vue_js/vue.js"></script>
                      <style>
                                        li {
                                                          list-style: none;
                                        }
                      </style>
    </head>
    
    <body>
                      <!--用 v-for 把一个数组对应为一组元素-->
                      <div id="root">
                                        <h1>遍历数组</h1>
                                        <ul>
                                                          <li v-for="(c,i) of city" :key="i">
                                                                            {{c}}------{{c.id}}------{{c.cityName}}
                                                          </li>
                                        </ul>
                                        <h1>遍历对象</h1>
                                        <ul>
                                                          <li v-for="(v,k) of person" :key="k">
                                                                            {{v}}-----{{k}}
                                                          </li>
                                        </ul>
                                        <h1>遍历字符串</h1>
                                        <ul>
                                                          <li v-for="(v,k) of str" :key="k">
                                                                            {{v}}-----{{k}}
                                                          </li>
                                        </ul>
                                        <h2>测试遍历指定次数(用得少)</h2>
                                        <ul>
                                                          <li v-for="(number,index) of 5" :key="index">
                                                                            index:{{index}}----value:{{number}}
                                                          </li>
                                        </ul>
                      </div>
                      <script>
                                        Vue.config.productionTip = false
                                        const vm = new Vue({
                                                          el: '#root',
                                                          data: {
                                                                            city: [
                                                                                              { id: '001', cityName: '张三' },
                                                                                              { id: '002', cityName: '李四', },
                                                                                              { id: '003', cityName: '王五', }],
                                                                            person: {
                                                                                              eat: '饭',
                                                                                              eye: '一双眼睛',
                                                                                              ears: '一双耳朵',
                                                                                              face: '一张脸'
                                                                            },
                                                                            str: 'Chinese'
                                                          }
                                        });
                      </script>
    </body>
    
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    第二步、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是没有问题的。

    <!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>key的作用和原理</title>
                      <script type="text/javascript" src="../vue_js/vue.js"></script>
                      <style>
                                        li {
                                                          list-style: none;
                                        }
                      </style>
    </head>
    
    <body>
                      <h1>ul列表</h1>
                      <div id="demo">
                                        <button @click.once="addFruit">向水果列表添加水果</button>
                                        <ul>
                                                          <li v-for="(fruit,index) of fruits" :key="index">
                                                                            {{fruit}}-----{{index}}:<input type="text">
    
                                                          </li>
                                        </ul>
                      </div>
                      <script>
                                        Vue.config.productionTip = false;
                                        const vm = new Vue({
                                                          el: '#demo',
                                                          data: {
                                                                            fruits: ['苹果', '梨子', '香蕉', '橘子', '红枣', '葡萄']
                                                          },
                                                          methods: {
                                                                            addFruit() {
                                                                                              let f = "柚子"
                                                                                              //往前加
                                                                                              this.fruits.unshift(f)
                                                                                              //往后加
                                                                                              //this.fruits.push(f)
                                                                            }
                                                          },
                                        });
                      </script>
    </body>
    
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    没有点击按钮之前的图片:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/aa3adb9ba319487a80f10d72d4d48483.png

    点击按钮之后的图片:
    在这里插入图片描述
    在这里有一个明显的问题,当我们再列表的前面添加数据的时候,输入框里面的内容的位置错乱,本应该再苹果那里,但是点击之后却显示再柚子的位置上。为啥会这样呢?
    列表渲染的更新主要是根据key来更新, key是虚拟DOM对象的标识,VUE会根据VUE数据的变化,产生新的虚拟DOM,接着产生新的真实DOM。新旧虚拟DOM会根据key进行比较。新数据的柚子和旧数据的苹果进行比较,发现不一样,就创建新的DOM,接着比较后面输入框,发现新旧虚拟DOM都有输入框input,所以直接使用旧的真实DOM,所以“苹果----0”就会直接服用旧的真实DOM,还是位于key=0的位置上。
    第三步、列表过滤
    我们可以filter函数的基础上利用watch侦听器实现或者计算属性实现,下面就是都采用了这两种方式实现的:
    一般计算属性可以实现的,watch也可以实现,但是我们一般来说都会采用计算属性,计算属性一般可能更加简单一些。

    <!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>列表过滤</title>
                      <script type="text/javascript" src="../vue_js/vue.js"></script>
    </head>
    
    <body>
    
                      <div id="root">
                                        <h1>使用watch侦听器实现</h1>
                                        <input type="text" placeholder="请输入名字" v-model="keyWord1">
                                        <ul>
                                                          <li v-for="(p,index) of filPerons" :key="index">
                                                                            {{p.name}}-{{p.age}}-{{p.sex}}
                                                          </li>
                                        </ul>
                                        <h1>使用计算属性实现</h1>
                                        <input type="text" placeholder="请输入提示信息" v-model="keyWord2">
                                        <ul>
                                                          <li v-for="(f,index) of filPerons1" :key="index">
                                                                            {{f.name}}-{{f.color}}-{{f.varieties}}
                                                          </li>
                                        </ul>
                      </div>
                      <script>
                                        Vue.config.productionTip = false;
                                        const vm = new Vue({
                                                          el: '#root',
                                                          data: {
                                                                            keyWord1: '',
                                                                            keyWord2: '',
                                                                            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: '男' }
                                                                            ],
                                                                            fuits: [
                                                                                              { id: '001', name: '香蕉', color: '黄色', varieties: '芝麻蕉' },
                                                                                              { id: '002', name: '苹果', color: '青色', varieties: '红将军' },
                                                                                              { id: '003', name: '大枣', color: '红色', varieties: '壶瓶枣' },
                                                                                              { id: '004', name: '梨子', color: '黄色', varieties: '黄金梨' }
                                                                            ],
                                                                            filPerons: [],
                                                          },
                                                          watch: {
                                                                            keyWord1: {
                                                                                              immediate:true,
                                                                                              handler(val) {
                                                                                                                this.filPerons = this.persons.filter((p) => {
                                                                                                                                  return p.name.indexOf(val) !== -1
                                                                                                                })
                                                                                              }
                                                                            }
                                                          },
                                                          computed: {
                                                                            filPerons1: {
                                                                                              get() {
                                                                                                                return this.fuits.filter((p) => {
                                                                                                                                  return p.name.indexOf(this.keyWord2) !== -1
                                                                                                                })
                                                                                              }
                                                                            }
                                                          }
                                        });
    
                      </script>
    </body>
    
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    在这里插入图片描述

    在这里插入图片描述
    第四步、列表排序:
    这里实现列表排序主要是sort实现的以及根据sortType来判断排序的方式,如顺序升序,降序排序,以及原始排序,实现排序方式的代码是“return this.sortType === 1 ? (s2.score - s1.score) : (s1.score - s2.score)”也就是一个三元表达式。

    <!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>列表排序</title>
                      <script type="text/javascript" src="../vue_js/vue.js"></script>
                      <style>
                                        li {
                                                          list-style: none;
                                        }
                      </style>
    </head>
    
    <body>
                      <div id="root">
                                        <input type="text" placeholder="请输入名字" v-model="searchStudent">
                                        <button @click="sortType = 2">分数升序</button>
                                        <button @click="sortType = 1">分数降序</button>
                                        <button @click="sortType = 0">原始顺序</button>
                                        <ul>
                                                          <li v-for="(v,k) of sortStudent" :key="v.id">
                                                                            {{v.studentName}}----{{v.score}}
                                                          </li>
                                        </ul>
                      </div>
                      <script>
                                        Vue.config.productionTip = false;
                                        const vm = new Vue({
                                                          el: '#root',
                                                          data: {
                                                                            searchStudent: '',
                                                                            sortType:0,
                                                                            student: [
                                                                                              { id: '001', studentName: '张三', score: 100 },
                                                                                              { id: '002', studentName: '李四', score: 89 },
                                                                                              { id: '003', studentName: '王五', score: 94 },
                                                                                              { id: '004', studentName: '小明', score: 84 },
                                                                                              { id: '005', studentName: '小刚', score: 99 },
                                                                                              { id: '006', studentName: '小华', score: 67 },
                                                                                              { id: '007', studentName: '小红', score: 81 },
                                                                                              { id: '008', studentName: '小芳', score: 62 },
                                                                                              { id: '009', studentName: '赵虎', score: 97 },
                                                                                              { id: '010', studentName: '张龙', score: 99 },
                                                                                              { id: '011', studentName: '马汉', score: 73 },
                                                                                              { id: '012', studentName: '罗三', score: 92 },
                                                                                              { id: '013', studentName: '刘贝', score: 91 }
                                                                            ]
                                                          },
                                                          computed: {
                                                                            sortStudent() {
                                                                                              console.log(this.sortType);
                                                                                              const studentArr = this.student.filter((s) => {
                                                                                                                return s.studentName.indexOf(this.searchStudent) !== -1;
                                                                                              });
                                                                                              if (this.sortType) {
                                                                                                                studentArr.sort((s1, s2) => {
                                                                                                                                  return this.sortType === 1 ? (s2.score - s1.score) : (s1.score - s2.score)
                                                                                                                });
                                                                                              }
                                                                                              return studentArr;
                                                                            }
    
                                                          }
                                        });
                      </script>
    </body>
    
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    第五步、VUE监测数据变化的原理(来源于:https://www.cnblogs.com/buluzombie/p/15617040.html,大家可以直接到这个网址去看)
    Vue 监视数据的原理:
    1.vue 会监视 data 中所有层次的数据。
    2. 如何监测对象中的数据?
      通过 setter 实现监视,且要在 new Vue 时就传入要监测的数据。(如下图)
      (1)对象中后追加的属性,vue 默认不做响应式处理
      (2)如需给后添加的属性做响应式,请使用如下API:
        Vue.set(target, propertyName/index, value) 或 vm. s e t ( t a r g e t , p r o p e r t y N a m e / i n d e x , v a l u e ) 3. 如何监测数组中的数据?  通过包裹数组更新元素的方法实现,本质就是做了两件事:  ( 1 )调用原生对应的方法对数据进行更新。  ( 2 )重新解析模板,进而更新页面。 4. 在 V u e 修改数组中的某个元素一定要用如下方法:   1. 使用这些 A P I : p u s h ( ) 、 p o p ( ) 、 s h i f t ( ) 、 u n s h i f t ( ) 、 s p l i c e ( ) 、 s o r t ( ) 、 r e v e r s e ( )    2. V u e . s e t ( ) 或 v m . set(target, propertyName/index, value) 3. 如何监测数组中的数据?   通过包裹数组更新元素的方法实现,本质就是做了两件事:   (1)调用原生对应的方法对数据进行更新。   (2)重新解析模板,进而更新页面。 4. 在Vue修改数组中的某个元素一定要用如下方法:   1.使用这些 API: push()、pop()、shift()、unshift()、splice()、sort()、reverse()   2. Vue.set() 或 vm. set(target,propertyName/index,value)3.如何监测数组中的数据?  通过包裹数组更新元素的方法实现,本质就是做了两件事:  (1)调用原生对应的方法对数据进行更新。  (2)重新解析模板,进而更新页面。4.Vue修改数组中的某个元素一定要用如下方法:  1.使用这些APIpush()pop()shift()unshift()splice()sort()reverse()  2.Vue.set()vm.set()
    在这里插入图片描述
    其中的案例代码如下:

    <!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>Vue的总结数据监测</title>
                      <script type="text/javascript" src="../vue_js/vue.js"></script>
                      <style>
                                        #s {
                                                          width: 100px;
                                                          height: 100px;
                                                          background-color: rgb(72, 23, 128);
                                                          text-align: center;
                                                          font-size: 70px;
                                                          color: white;
                                        }
                      </style>
    </head>
    
    <body>
                      <div id="root">
                                        <button @click="num++">点击按钮实现下面的数字加一</button><br>
                                        <div id="s">{{num}}</div><br>
                                        <button @click="myFriend.age++">年龄+1</button>
                                        <button @click="myFriend.sex = '“由于情况特殊,所以该选项位置”' ">修改性别</button> <br />
                                        <button @click.once="addBallGame('冰球')">在球类列表再添加一个其他的球类项目(但是只能增加一次)</button>
                                        <button @click="addFriend">在列表首位添加一个朋友</button> <br />
                                        <button @click="updateFirstFriendName">修改第一个朋友的名字为:张三</button> <br />
                                        <button @click="updateHobby">修改第2个爱好为Basketball</button> <br />
                                        <button @click="removeRugby">过滤掉爱好中的橄榄球</button> <br />
                                        <h2>这是我朋友的年龄,他的名字是{{myFriend.name}},今年是{{myFriend.age}}岁。他的性别是<span
                                                                            v-if="myFriend.sex">{{myFriend.sex}}</span></h2>
                                        <h2>我这个朋友善于球类运动项目,比如下面这些:</h2>
                                        <ul>
                                                          <li v-for="(value,index) of myFriend.habby" :key="index">
                                                                            {{value}}
                                                          </li>
                                        </ul>
                                        <h2>他除了我之外也有很多其他朋友,如下面这些人:</h2>
                                        <ul>
                                                          <li v-for="(hf,index) in myFriend.hisFriends" :key="index">
                                                                            {{hf.name}}----{{hf.age}}------{{hf.sex}}
                                                          </li>
                                        </ul>
                      </div>
                      <script>
                                        Vue.config.productionTip = false; //阻止 vue 在启动时生成生产提示。
                                        const vm = new Vue({
                                                          el: '#root',
                                                          data: {
                                                                            num: 0,
                                                                            myFriend: {
                                                                                              name: '小明',
                                                                                              age: 18,
                                                                                              sex: '男',
                                                                                              habby: ['足球', '篮球', '排球', '羽毛球', '网球', '乒乓球', '橄榄球', '台球'],
                                                                                              hisFriends: [
                                                                                                                { name: '小华', age: 19, sex: '男' },
                                                                                                                { name: '小刚', age: 19, sex: '男' },
                                                                                                                { name: '小芳', age: 17, sex: '女' },
                                                                                                                { name: '小红', age: 20, sex: '女' },
                                                                                                                { name: '小坤', age: 18, sex: '男' }
                                                                                              ]
                                                                            }
                                                          },
                                                          methods: {
                                                                            addBallGame(ball) {
                                                                                              this.myFriend.habby.push(ball);
                                                                            },
                                                                            addFriend() {
                                                                                              this.myFriend.hisFriends.unshift({ name: 'jack', age: 70, sex: '男' })
                                                                            },
                                                                            updateFirstFriendName() {
                                                                                              this.myFriend.hisFriends[0].name = "张三";
                                                                            },
                                                                            updateHobby() {
                                                                                              // this.student.hobby.splice(0,1,'Basketball车')
                                                                                              // Vue.set(this.student.hobby,1,'Basketball')
                                                                                              this.$set(this.myFriend.habby, 1, 'Basketball')
                                                                            },
                                                                            removeRugby(){
                                                                                              this.myFriend.habby = this.myFriend.habby.filter((obj)=>{
                                                                                                                return obj!='橄榄球'
                                                                                              })
                                                                            }
                                                          },
                                        });
                      </script>
    </body>
    
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
  • 相关阅读:
    900年历史的万安桥失火!传统古建筑又该如何保护?
    Android .kl按键布局文件
    SkiaSharp 之 WPF 自绘 五环弹动球(案例版)
    Oracle JDK 和 OpenJDK 有什么区别?
    【C++】模板初阶
    【C语言】文件操作
    Linux下最新版MySQL 8.0的下载与安装(详细步骤)
    解决Maven依赖下载缓慢的问题(亲测管用)
    SQL触发器
    C# 把多个dll合成一个dll
  • 原文地址:https://blog.csdn.net/weixin_43228946/article/details/126834209