Vue2(四):Vue监测数据的原理

本文讨论了Vue中如何更新单个属性和对象时的差异,以及Vue监测数据改变的原理,包括setter的作用、Vue.set()方法的应用和数组响应式的实现。重点介绍了对象中新增属性的响应式处理和数组操作的注意事项。
摘要由CSDN通过智能技术生成

一、更新时的问题

更新马冬梅的信息,一个属性一个属性的改,可以修改成功,Vue也可以监测到并且更改到新的页面里。
如果直接更改对象,数据被改写了,但是Vue监测不到也改不到新的的页面里面。
先点击按钮索引值为0的信息被改了,后点开发者工具,就能呈现。

		<!-- 准备好一个容器-->
		<div id="root">
			<h2>人员列表</h2>
			<button @click="updateMei">更新马冬梅的信息</button>
			<ul>
				<li v-for="(p,index) of persons" :key="p.id">
					{{p.name}}-{{p.age}}-{{p.sex}}
				</li>
			</ul>
		</div>

		<script type="text/javascript">
			Vue.config.productionTip = false
			
			const vm = new Vue({
				el:'#root',
				data:{
					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:'男'}
					]
				},
				methods: {
					updateMei(){
						// this.persons[0].name = '马老师' //奏效
						// this.persons[0].age = 50 //奏效
						// this.persons[0].sex = '男' //奏效
						// this.persons[0] = {id:'001',name:'马老师',age:50,sex:'男'} //不奏效
						this.persons.splice(0,1,{id:'001',name:'马老师',age:50,sex:'男'})
					}
				}
			}) 

		</script>

二 、Vue监测数据改变的原理_对象

原生js模拟Vue监测数据改变监视data中的数据

  1. 在setter中不是简单的输出,而是重新解析模板,生成虚拟DOM,新旧虚拟DOM对比,更新页面实现响应式。
  2. Vue中vm对_data做了数据代理,可以直接vm.name,不用vm._data.name。
  3. 但是js原生写的有瑕疵,只是监视了一次data中的数据,data里面还有对象的话,监测不出来,Vue就能监测到。
<script type="text/javascript">

		let data = {
			name: '尚硅谷',
			address: '北京',
		}

		//创建一个监视的实例对象,用于监视data中属性的变化
		const obs = new Observer(data)
		console.log(obs)

		//准备一个vm实例对象
		let vm = {}
		vm._data = data = obs

		function Observer(obj) {
			//汇总对象中所有的属性形成一个数组
			const keys = Object.keys(obj)
			//遍历
			keys.forEach((k) => {
				// this 实列对象Observer
				Object.defineProperty(this, k, {
					get() {
						return obj[k]
					},
					set(val) {
						console.log(`${k}被改了,我要去解析模板,生成虚拟DOM.....我要开始忙了`)
						obj[k] = val
					}
				})
			})
		}
	</script>

三、监测对象中的数据

1.怎么监视对象中的数据?

一层一层扒

2.Vue.set()方法的使用

只能给data中的某一个对象追加属性,不能给data追加属性。

<body>
	<!-- 准备好一个容器-->
	<div id="root">
		<h1>个人信息</h1>
		<h2>个人名称:{{personal.name}}</h2>
		<h2>个人地址:{{personal.address}}</h2>
		<hr />
		<h1>学生信息</h1>
		<button @click="addSex">添加一个性别属性,默认值是男</button>
		<h2>学生姓名:{{student.name}}</h2>
		<h2 v-if="student.sex">学生性别:{{student.sex}}</h2>
		<h2>学生年龄:真实{{student.age.rAge}},对外:{{student.age.sAge}}</h2>
		<h2>朋友们</h2>
		<ul>
			<li v-for="(f,index) in student.friends" :key="index">
				{{f.name}}--{{f.age}}
			</li>
		</ul>
		<h2>监护人是:{{leader}}</h2>


	</div>
</body>

<script type="text/javascript">
	Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

	const vm = new Vue({
		el: '#root',
		data: {
			personal: {
				name: '野良',
				address: '黑龙江',
			},
			student: {
				name: 'tom',
				// sex: '男',
				age: {
					rAge: 40,
					sAge: 29,
				},
				friends: [
					{ name: 'jerry', age: 35 },
					{ name: 'tony', age: 36 }
				]
			}
		},
		methods: {
			addSex() {
				// Vue.set(this.student,'sex','男')
				this.$set(this.student, 'sex', '男')
			}
		}
	})
</script>

3.监测数据的原理

数组:添加push,删除shift,替换splice(0,1,‘XXX’)。
改变数组中的内容,是Vue重新改写数组不是重载。
增删改查:被包裹过的方法。

四、总结

Vue监视数据的原理:

  1. vue会监视data中所有层次的数据。

  2. 如何监测对象中的数据?
    通过setter实现监视,且要在new Vue时就传入要监测的数据。
    (1).对象中后追加的属性,Vue默认不做响应式处理
    (2).如需给后添加的属性做响应式,请使用如下API:
    Vue.set(target,propertyName/index,value) 或
    vm.$set(target,propertyName/index,value)

  3. 如何监测数组中的数据?
    通过包裹数组更新元素的方法实现,本质就是做了两件事:
    (1).调用原生对应的方法对数组进行更新。
    (2).重新解析模板,进而更新页面。

  4. 在Vue修改数组中的某个元素一定要用如下方法:
    (1)使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
    (2)Vue.set() 或 vm.$set()

特别注意:Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象 添加属性!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值