本文主要是介绍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
-
用于展示列表数据
-
语法:
v-for=“(item, index) in xxx” :key=“yyy”
,其中xxx是遍历的目标,yyy是唯一的索引,用于区分每个嘎达 -
可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
-
遍历数组的话,index是索引值(唯一),p是数组每个元素
-
遍历对象的话,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监测数据原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!