Vue2-绑定样式、条件渲染、列表渲染、列表过滤、模糊查询、Vue监测数据原理

本文主要是介绍Vue2-绑定样式、条件渲染、列表渲染、列表过滤、模糊查询、Vue监测数据原理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

🥔:想只有苦难,做才有答案

更多Vue知识请点击——Vue.js

VUE2-Day3

    • 绑定样式
      • 1、class绑定
      • 2、绑定style样式
    • 条件渲染
      • 1、v-show
      • 2、v-if
      • 条件渲染案例
    • 列表渲染
      • 1、v-for
      • 2、key的作用与原理(重要)
        • 面试题:react、vue中的key有什么作用?(key的内部原理)
        • 案例:给数组头部添加一个人
    • 列表过滤:实现模糊查询
      • 1、使用watch实现
      • 2、使用computed实现
    • 列表排序
    • Vue监测数据原理及其方法
      • 1、更新数据时的一个问题
      • 2、模拟Vue监视data对象中的数据
      • 3、Vue监测对象中的数据
        • (1)怎么监测对象中的数据?
        • (2)Vue.set()的使用
      • 4、Vue监测数组中的数据
        • 如何监测数组中的数据?
      • 5、回头看第一个
      • 监测数据综合案例

绑定样式

1、class绑定

写法:class=“xxx” xxx可以是字符串、对象、数组。
字符串写法适用于:类名不确定,要动态获取。
数组写法适用于:要绑定多个样式,但是不确定绑定哪几个,就写成数组,省的一个一个绑定。
对象写法适用于:要绑定多个样式,而且要动态决定用不用,这里面可以写一些判断的逻辑。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>绑定class样式</title><!-- 引入vue.js文件 --><script type="text/javascript" src="../js/vue.js"></script><!-- 设置css样式 --><style>.basic {width: 400px;height: 100px;border: solid 1px black;margin-top: 50px;}.happy {background-color: pink;}.normal {background-color: greenyellow;}.sad {background-color: grey;}.style1 {background-color: skyblue;}.style2 {font-size: 28px;}.style3 {text-align: center;}</style></head><body><div id="root"><!--   :是v-bind:的简写 --><!--   1. 绑定class样式--字符串写法,适用于样式的类名不确定,需要动态指定--><div class="basic" :class="mood" @click="changeMood">{{name}}</div><!--   2. 绑定class样式--数组写法,适用于要绑定的样式个数不确定,名字也不确定--><div class="basic" :class="classArr" @click="removeStyle">{{name}}</div><br /><!--   3. 绑定class样式--对象写法,适用于要绑定的样式个数确定,名字也确定,要动态决定用不用--><div class="basic" :class="classObj">{{name}}</div><br /><button @click="useStyle1">点击添加样式1</button><button @click="useStyle2">点击添加样式2</button></div><script type="text/javascript">const vm = new Vue({el: "#root",data: {name: "我是最棒滴!!!",mood: "normal",classArr: ["style1", "style2", "style3"],classObj: {style1: false,style2: false,},},methods: {changeMood() {const arr = ["happy", "normal", "sad"];const index = Math.floor(Math.random() * 3);this.mood = arr[index];},//点击去掉第二个框的style样式//由于pop()是删掉最后一个元素,所以多次点击依次删除style3->style2->style1removeStyle() {this.classArr.pop();},//点击添加样式1useStyle1() {this.classObj.style1 = true;},//点击添加样式2useStyle2() {this.classObj.style2 = true;},},});</script></body>
</html>
  • 可以拿此例子自己敲敲,多到浏览器运行调试看看

2、绑定style样式

:style="{fontSize: xxx + 'px'}"其中xxx是动态值。
:style="[a,b]"其中a、b是样式对象。

对象写法比较常用。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>绑定style样式</title><!-- 引入vue.js文件 --><script type="text/javascript" src="../js/vue.js"></script><!-- 设置css样式 --><style>.basic {width: 400px;height: 100px;border: solid 1px black;margin-top: 50px;}</style></head><body><div id="root"><!-- 绑定style样式-对象写法 --><div class="basic" :style="styleObj1">{{name}}</div><!-- 绑定style样式-数组写法 --><div class="basic" :style="[styleObj1,styleObj2]">{{name}}</div><div class="basic" :style="styleArr">{{name}}</div></div><script type="text/javascript">const vm = new Vue({el: "#root",data: {name: "我是最棒的!!!",styleObj1: {fontSize: "40px",backgroundColor: "pink",},styleObj2: {color: "red",},styleArr: [{fontSize: "40px",backgroundColor: "blue",},{color: "yellow",},],},});</script></body>
</html>

条件渲染

1、v-show

写法:v-show=“表达式”
适用于:切换频率较高的场景。(不会动DOM树,只是隐藏,相当于添加display:none)
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。这是因为v-if会一不小心把标签直接从页面上干掉,而v-show不会干掉,只会隐藏。

2、v-if

写法:
(1).v-if=“表达式”
(2).v-else-if=“表达式”
(3).v-else=“表达式”
适用于:切换频率较低的场景。(因为会动DOM树,节点删来删去不太好)
特点:不展示的DOM元素直接被移除。
注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。

条件渲染案例

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>条件渲染</title><!-- 引入vue文件 --><script type="text/javascript" src="../js/vue.js"></script></head><body><div id="root"><!-- 使用v-show做条件渲染:v-show值为true时显示,为false时隐藏(display: none) --><h1 v-show="true">你好呀,{{name}}</h1><h1 v-show="1===1">你好呀,{{name}}</h1><!-- 使用v-if做条件渲染,v-if="false"时会彻底删除标签--><h1 v-if="true">再见,{{name}}</h1><h1 v-if="1===3">再见,{{name}}</h1><!-- 实现功能:随着n递增展示不同的div --><h2>{{n}}</h2><button v-on:click="n++">点击n+1</button><!-- 这里的v-if,v-else-if,v-else和基础js里的一样儿 --><div v-if="n === 1">Angular</div><div v-else-if="n === 2">React</div><div v-else-if="n === 3">Vue</div><div v-else>potato</div><!-- v-if和template的配合使用(v-show不行)template不会影响页面结构,页面运行后会自动去掉,但是可以配合v-if控制多个元素整体显示而且不会影响css拿节点--><template v-if="n === 1"><div>鱿鱼西一号</div><div>鱿鱼西二号</div><div>鱿鱼西三号</div></template></div><script type="text/javascript">const vm = new Vue({el: "#root",data: {name: "鱿鱼西",n: 0,},});</script></body>
</html>

列表渲染

1、v-for

  1. 用于展示列表数据

  2. 语法:v-for=“(item, index) in xxx” :key=“yyy”,其中xxx是遍历的目标,yyy是唯一的索引,用于区分每个嘎达

  3. 可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)

  4. 遍历数组的话,index是索引值(唯一),p是数组每个元素

  5. 遍历对象的话,index就是属性名(唯一),p是属性值

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>基本列表渲染</title><!-- 引入vue文件 --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备一个容器 --><div id="root"><!-- 遍历数组:遍历数组的话,index是索引值,p是数组每个元素  --><h2>人员列表(遍历数组)</h2><ul><li v-for="(p,index) in persons" :key="p.id">{{p.name}}-{{p.age}}-{{index}}</li></ul><!-- 遍历对象:遍历对象的话,index就是属性名,p是属性值 --><h2>汽车信息(遍历对象)</h2><ul><li v-for="(p,index) of car" :key="index">{{p}}-{{index}}</li></ul><!-- 遍历字符串:遍历字符串的话,index就是索引值,p是每个字符 --><h2>遍历字符串</h2><ul><li v-for="(p,index) of str" :key="index">{{p}}-{{index}}</li></ul><!-- 遍历指定次数:遍历指定次数的话,index就是索引值,p是从1开始数 --><h2>遍历指定次数</h2><ul><li v-for="(p,index) of 5" :key="index">{{p}}-{{index}}</li></ul></div><script type="text/javascript">new Vue({el: "#root",data: {persons: [{ id: "001", name: "张三", age: 18 },{ id: "002", name: "李四", age: 19 },{ id: "003", name: "王五", age: 20 },],car: {name: "马沙拉弟",price: "10块钱",color: "骚粉色",},str: "hello",},});</script></body>
</html>

2、key的作用与原理(重要)

ey可以有三种情况:写唯一标识、写index、不写。其中唯一标识最合适,如果不写会默认是写index。

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

1、 虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】, 随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较(diff算法),比较规则如下:

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 name="viewport" content="width=device-width, initial-scale=1.0" /><title>key的原理和作用</title><!-- 引入vue文件 --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备一个容器 --><div id="root"><!-- 遍历数组:遍历数组的话,index是索引值,p是数组每个元素  --><h2>人员列表(遍历数组)</h2><button @click="add">点击添加老六</button><ul><!-- index-索引号,p.id-唯一标识符 --><li v-for="(p,index) in persons" :key="p.id">{{p.name}}-{{p.age}}-{{index}}<input type="text" /></li></ul></div><script type="text/javascript">new Vue({el: "#root",data: {persons: [{ id: "001", name: "张三", age: 18 },{ id: "002", name: "李四", age: 19 },{ id: "003", name: "王五", age: 20 },],},methods: {add() {const p = { id: "004", name: "老六", age: 19 };// unshift():此方法的作用是将指定元素添加到数组的开头this.persons.unshift(p);},},});</script></body>
</html>
案例:给数组头部添加一个人
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>key的原理和作用</title><!-- 引入vue文件 --><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备一个容器 --><div id="root"><!-- 遍历数组:遍历数组的话,index是索引值,p是数组每个元素  --><h2>人员列表(遍历数组)</h2><button @click="add">点击添加老六</button><ul><!-- index-索引号,p.id-唯一标识符 --><li v-for="(p,index) in persons" :key="p.id">{{p.name}}-{{p.age}}-{{index}}<input type="text" /></li></ul></div><script type="text/javascript">new Vue({el: "#root",data: {persons: [{ id: "001", name: "张三", age: 18 },{ id: "002", name: "李四", age: 19 },{ id: "003", name: "王五", age: 20 },],},methods: {add() {const p = { id: "004", name: "老六", age: 19 };// unshift():此方法的作用是将指定元素添加到数组的开头this.persons.unshift(p);},},});</script></body>
</html>

遍历列表时key的作用(index作为key):

请添加图片描述

遍历列表时key的作用(唯一标识作为key):

请添加图片描述

列表过滤:实现模糊查询

1、使用watch实现

handler函数必须在keyword被改变时才执行,也就是说页面上来还是没有信息的,必须手动输入个东西再删掉(手动改变keyword),才能执行handler函数,才能显示所有人物的信息,所以必须加个属性immediate: true,才能默认初始化先调用handler,这样就能实现上来就显示所有人物的信息(最开始keyword=''

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>列表过滤</title><script type="text/javascript" src="../js/vue.js"></script></head><body><div id="root"><h2>人员列表</h2><input type="text" placeholder="请输入关键字" v-model="keyWord" /><ul><li v-for="(p,index) of filPersons" :key="p.id">{{p.name}}-{{p.age}}-{{p.sex}}</li></ul></div><script type="text/javascript">//   用监视(侦听)属性watch实现new Vue({el: "#root",data: {keyWord: "",persons: [{ id: "001", name: "马冬梅", age: 18, sex: "女" },{ id: "002", name: "周冬雨", age: 19, sex: "女" },{ id: "003", name: "周杰伦", age: 18, sex: "男" },{ id: "004", name: "温兆伦", age: 18, sex: "男" },],filPersons: [],},watch: {keyWord: {//页面上来由于filPersons是空,不会显示数据,想要让页面初始化就显示所有人,就要加个immediate: true//这样就可以让handler函数初始化时先调用一次,由于开始keyword=''// 而字符串里都包含空字符串,就可以先筛选出来,初始化所有人物信息immediate: true,handler(newVal, oldVal) {this.filPersons = this.persons.filter((p) => {//判断keyword变化后的新值在不在每个对象的name中,并返回一个新的数组return p.name.indexOf(newVal) !== -1;});},},},});</script></body>
</html>

2、使用computed实现

使用计算属性可以解决watch中的一些繁琐写法,也不用在data中再新定义一个空数组newPersons。

计算属性和监视属性最大的区别就是handler函数是被监视的属性更改时执行,而get是属性被读取时就执行,所以页面加载时filPersons被读取直接就调用get函数返回了一个被筛选后的新数组(条件是name包含空字符串),之后每次keyword改动都会导致Vue模板重新解析,get重新调用。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>列表过滤</title><script type="text/javascript" src="../js/vue.js"></script></head><body><div id="root"><h2>人员列表</h2><input type="text" placeholder="请输入关键字" v-model="keyWord" /><ul><li v-for="(p,index) of filPersons" :key="p.id">{{p.name}}-{{p.age}}-{{p.sex}}</li></ul></div><script type="text/javascript">//用计算属性computed实现;new Vue({el: "#root",data: {keyWord: "",persons: [{ id: "001", name: "马冬梅", age: 18, sex: "女" },{ id: "002", name: "周冬雨", age: 19, sex: "女" },{ id: "003", name: "周杰伦", age: 18, sex: "男" },{ id: "004", name: "温兆伦", age: 18, sex: "男" },],},computed: {filPersons() {return persons.filters((p) => {return p.name.indexOf(this.keyWord) !== -1;});},},});</script></body>
</html>

列表排序

先过滤,再排序
首先定义一个sortType属性来判断排序的种类,然后在计算属性里做一个判断。
注意这里仔细理解理解数组的sort方法,很奇怪。
这个案例再次体现出计算属性的强大之处,只要get里用到的数据(keyword,sortType)发生改变,get都会重新执行,模板都会重新解析,这个业务逻辑就实现了

先复习一下数组的排序sort升序降序方法

      let arr = [1, 5, 3, 7, 4];//降序b-a//   arr.sort((a, b) => {//     return b - a;//   });//   console.log(arr);//升序a-barr.sort((a, b) => {return b - a;});console.log(arr);

例子:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>列表排序</title><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器 --><div id="root"><h1>人员列表</h1><input type="text" placeholder="请输入关键字" v-model="keyword" /><button @click="sortType = 0">原顺序</button><button @click="sortType = 1">年龄降序</button><button @click="sortType = 2">年龄升序</button><ul><li v-for="(p,index) in newPersons" :key="p.id">{{p.name}}----{{p.age}}----{{p.sex}}</li></ul></div><script>const vm = new Vue({el: "#root",data: {sortType: 0, //0原顺序,1年龄降序,2年龄升序keyword: "",persons: [{ id: "001", name: "马冬梅", age: 18, sex: "女" },{ id: "002", name: "周冬雨", age: 19, sex: "女" },{ id: "003", name: "周杰伦", age: 30, sex: "男" },{ id: "004", name: "温兆伦", age: 50, sex: "男" },],},computed: {newPersons() {//先过滤,再排序const arr = this.persons.filter((ele) => {return ele.name.includes(this.keyword);});// 或者if(this.sortType)if (this.sortType !== 0) {arr.sort((a, b) =>this.sortType === 1 ? b.age - a.age : a.age - b.age);}return arr;},},});</script></body>
</html>

Vue监测数据原理及其方法

1、更新数据时的一个问题

如果我要点击按钮实现更新马冬梅的信息,那么如果一个属性一个属性地改,可以修改成功,并且Vue也会检测到并更新到页面。但是我如果直接把整个对象改了,可以修改成功,但是Vue监测不到并且不更新到页面,这是为什么?

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>列表排序</title><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器 --><div id="root"><h1>人员列表</h1><button @click="updateMei">更新马冬梅信息</button><ul><li v-for="(p,index) in persons" :key="p.id">{{p.name}}----{{p.age}}----{{p.sex}}</li></ul></div><script>const vm = new Vue({el: "#root",data: {persons: [{ id: "001", name: "马冬梅", age: 18, sex: "女" },{ id: "002", name: "周冬雨", age: 19, sex: "女" },{ id: "003", name: "周杰伦", age: 30, sex: "男" },{ id: "004", name: "温兆伦", age: 50, sex: "男" },],},methods: {updateMei() {// this.persons[0].name = "马老师"; //奏效(页面和Vue都监测到了)// this.persons[0].age = 28; //奏效(页面和Vue都监测到了)// this.persons[0].sex = "男"; //奏效(页面和Vue都监测到了)//此处Vue监测不到数据改变,但是实际上已经改了this.persons[0] = { id: "001", name: "马老师", age: 28, sex: "男" };},},});</script></body>
</html>

2、模拟Vue监视data对象中的数据

用原生js写一个Vue监视data数据改变的效果
可以看出,Vue监视数据的原理,就是靠setter
如果不理解obj[k],想想前边讲Object.defineProperty时那个number

getter:当属性值被访问时,会触发getter方法,这时Vue会将当前的Watcher对象(即订阅者)存储起来,用于后续数据变化时的更新操作。

setter:属性被修改–>调用setter–>重新解析模板–>生成新的虚拟DOM–>新旧DOM对比(diff)–>更新页面

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><script type="text/javascript">let data = {name: "小猪佩奇",age: 5,};//创建一个监视的实例对象,用于监视data中属性的变化const obs = new Observer(data);console.log(obs);//准备一个vm实例对象let vm = {};vm._data = data = obs;function Observer(obj) {//1.创建一个数组接收传入对象的属性名const keys = Object.keys(obj);//2.遍历属性名,让Observer实例对data中的每个数据进行数据代理keys.forEach((k) => {Object.defineProperty(this, k, {get() {//有人想读实例中的属性值,我就把data中对应的属性值拿过来return obj[k];},set(val) {console.log(`${k}被改了,我要去解析模板,生成虚拟DOM...我要开始忙了`);//有人想改实例中的属性值,我就把data中对应的属性值更改(数据代理)obj[k] = val;},});});}</script></body>
</html>

这只是一个简单的模拟,实际上Vue做了更多事情,比如:
1、在setter中不是简单的输出,而是重新解析模板,生成虚拟DOM,新旧虚拟DOM对比,更新页面实现响应式。
2、Vue中vm还对_data做了数据代理,可以直接vm.name,不用vm._data.name
3、上面的简单模拟例子,如果数据是套娃的(对象中还有对象还有对象),就监测不到。但是Vue就可以,不管你数据藏得多深,Vue都能找到,每个数据都有自己的getter和setter。只要有数据被改,就会实现响应式。

3、Vue监测对象中的数据

(1)怎么监测对象中的数据?

1、vue会监视data中所有层次的数据,不管你藏得有多深。
2、如何监测对象中的数据?
通过setter实现监视,且要在new Vue时就传入要监测的数据。
(1).对象中后追加的属性,Vue默认不做响应式处理
(2).如需给后添加的属性做响应式,请使用如下API:

Vue.set(target,propertyName/index,value) 或 
vm.$set(target,propertyName/index,value)
(2)Vue.set()的使用

用法:
向响应式对象中添加一个 property(属性),并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如 this.girlfriend.sex = '女')为啥呢?

_data在收集data中的数据之前,先做了一个加工(这个加工也可以称之为数据劫持),那就是给每个数据匹配一个getter和setter,前面说了,Vue监视数据的原理,就是靠setter。所以如果我们后期手动直接给_data添加属性(注意区别手动添加和从data中收集),是无法实现响应式的,因为没办法给它setter,只有从data中收集过来的属性才能有setter。

Vue.set()是有局限性的!!!它只能给data中的某个对象追加属性,不能给vm 或 vm的根数据对象(data或_data) 添加属性!!!
也就是说第一个参数不能是 Vue 实例,或者 Vue 实例的根数据对象(_data)

<div id="root"><h2>我的名字:{{name}}</h2><h2>我的年龄:{{age}}</h2><!-- v-if当属性值为undefined不显示,也不报错 --><h3 v-if="sex">我的性别:{{sex}}</h3><button @click="addmySex">点击添加我的性别</button><hr><h2>她的名字:{{girlfriend.name}}</h2><button @click="addherSex">点击添加性别,属性值为女</button><h2 v-if="girlfriend.sex">她的性别:{{girlfriend.sex}}</h2><h2>她的年龄:对外{{girlfriend.age.fakeAge}},真实{{girlfriend.age.realAge}}</h2><h2>朋友们</h2><ul><li v-for="p in girlfriend.friends" :key="p.id">{{p.name}}----{{p.age}}</li></ul>
</div>
<script>const vm = new Vue({el: '#root',data: {name: 'www',age: 18,girlfriend: {name: 'zzz',// sex: '女',age: {realAge: 23,fakeAge: 18}}},methods: {addherSex() {// Vue.set(this.girlfriend, 'sex', '女');this.$set(this.girlfriend, 'sex', '女');                         //vm.$set(vm.girlfriend, 'sex', '女');},addmySex() {Vue.set(this, 'sex', '男');}},})
</script>

4、Vue监测数组中的数据

如何监测数组中的数据?

Vue定义了一个非常厉害的方法,目的只有一个:实现响应式。

方法里包装的代码本质就是做了两件事:
(1)调用原生对应的方法对数组进行更新。然后第二步在这个基础上再加东西
(2)重新解析模板,生成虚拟DOM,diff算法……进而更新页面,实现响应式。

所以在Vue修改数组中的某个元素实现响应式一定要用如下方法:
(1)使用这些API:push()在后面追加、pop()删除最后一个、shift()删除第一个、unshift()在前面追加、splice()在指定位置增删改、sort()数组排序、reverse()反转数组,这些api都是可以修改原数组的,可以在(MDN Web Docs (mozilla.org))查看。
(2)Vue.set()vm.$set()也可以实现响应式,第二个参数写索引,第三个写元素,可以改也可以加

5、回头看第一个

说了这么多,再回头看第一个问题,恍然大悟
1、单独改每个属性可以奏效,是因为Vue可以监测到对象里的每个属性,不管它藏的多深,只要是个对象,就有相应的getter和setter
2、将数组中的元素单独替换,数据修改成功,但是Vue没有监测到,页面不显示,这是因为数组中的每个元素是没有getter和setter的,如果修改数组中的元素无法实现响应式.
3、要想让更改数组中的元素实现响应式,就得调用数组的七个api或者用Vue.set()方法

解决:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>列表排序</title><script type="text/javascript" src="../js/vue.js"></script></head><body><!-- 准备好一个容器 --><div id="root"><h1>人员列表</h1><button @click="updateMei">更新马冬梅信息</button><ul><li v-for="(p,index) in persons" :key="p.id">{{p.name}}----{{p.age}}----{{p.sex}}</li></ul></div><script>const vm = new Vue({el: "#root",data: {persons: [{ id: "001", name: "马冬梅", age: 18, sex: "女" },{ id: "002", name: "周冬雨", age: 19, sex: "女" },{ id: "003", name: "周杰伦", age: 30, sex: "男" },{ id: "004", name: "温兆伦", age: 50, sex: "男" },],},methods: {updateMei() {// this.persons[0].name = "马老师"; //奏效(页面和Vue都监测到了)// this.persons[0].age = 28; //奏效(页面和Vue都监测到了)// this.persons[0].sex = "男"; //奏效(页面和Vue都监测到了)//不奏效,此处Vue监测不到数据改变,但是实际上已经改了// this.persons[0] = { id: "001", name: "马老师", age: 28, sex: "男" };this.persons.splice(0, 1, {id: "001",name: "马老师",age: 28,sex: "男",});},},});</script></body>
</html>

监测数据综合案例

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>数据监测综合案例</title><script type="text/javascript" src="../js/vue.js"></script></head><body><div id="root"><h1>学生信息</h1><!-- 六个任务如下 --><button @click="student.age++">年龄加1</button><br /><button @click="addSex">增加性别属性,默认值:男</button><br /><button @click="addFriend">在列表首位添加一个朋友</button><br /><button @click="updateFirstFriendName">修改第一个朋友的名字为:小张,年龄改为20</button><br /><button @click="addHobby">添加一个爱好</button><br /><button @click="updateHobby">修改一个爱好为:开车</button><br /><h3>姓名:{{student.name}}</h3><h3>年龄:{{student.age}}</h3><h3 v-if="student.sex">性别:{{student.sex}}</h3><h3>爱好:</h3><ul><li v-for="(h,index) in student.hobby" ::key="index">{{h}}</li></ul><h3>朋友们:</h3><ul><li v-for="(f,index) in student.friends" ::key="index">{{f.name}}-{{f.age}}</li></ul></div><script type="text/javascript">const vm = new Vue({el: "#root",data: {student: {name: "小吴",age: 18,hobby: ["羽毛球", "乒乓球", "篮球"],friends: [{ name: "小黄", age: 19 },{ name: "小何", age: 19 },],},},methods: {addSex() {Vue.set(this.student, "sex", "男");//this.$set(this.student, "sex", "男")},addFriend() {this.student.friends.unshift({ name: "小王", age: 18 });},updateFirstFriendName() {// this.student.friends[0].name = "小张";// this.student.friends[0].age = 20;// 另一种写法this.student.friends.splice(0, 1, { name: "小张", age: 20 });},addHobby() {this.student.hobby.push("排球");},updateHobby() {//把第二个修改为开车this.student.hobby.splice(1, 1, "开车");//this.$set(this.student.hobby,1,'开车')},},});</script></body>
</html>

这篇关于Vue2-绑定样式、条件渲染、列表渲染、列表过滤、模糊查询、Vue监测数据原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/209425

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

pandas数据过滤

Pandas 数据过滤方法 Pandas 提供了多种方法来过滤数据,可以根据不同的条件进行筛选。以下是一些常见的 Pandas 数据过滤方法,结合实例进行讲解,希望能帮你快速理解。 1. 基于条件筛选行 可以使用布尔索引来根据条件过滤行。 import pandas as pd# 创建示例数据data = {'Name': ['Alice', 'Bob', 'Charlie', 'Dav

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

c++的初始化列表与const成员

初始化列表与const成员 const成员 使用const修饰的类、结构、联合的成员变量,在类对象创建完成前一定要初始化。 不能在构造函数中初始化const成员,因为执行构造函数时,类对象已经创建完成,只有类对象创建完成才能调用成员函数,构造函数虽然特殊但也是成员函数。 在定义const成员时进行初始化,该语法只有在C11语法标准下才支持。 初始化列表 在构造函数小括号后面,主要用于给

hdu4407容斥原理

题意: 有一个元素为 1~n 的数列{An},有2种操作(1000次): 1、求某段区间 [a,b] 中与 p 互质的数的和。 2、将数列中某个位置元素的值改变。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.Inpu