vue中响应式是什么?怎么理解响应式原理?
vue中响应式是什么?概念:官网解释:Vue 最独特的特性之一,是其非侵入性的响应式系统。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。简而言之就是数据变页面变实现原理:Vue在组件和实例初始化的时候,会将data里的数据进行数据劫持(object.definepropty对数据做处理)。被解除过后的数据会有两个属性:一个叫getter,一个叫set...
vue中响应式是什么?
概念:
官网解释:Vue 最独特的特性之一,是其非侵入性的响应式系统。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。
简而言之就是数据变页面变
实现原理:
Vue在组件和实例初始化的时候,会将data里的数据进行数据劫持(object.definepropty对数据做处理)。被解除过后的数据会有两个属性:一个叫getter,一个叫setter。
getter是使用数据的时候触发,setter是在修改数据的时候触发,修改数据的时候触发setter,同时也触发了底层的watcher监听,通知dom修改刷新。
举个例子:
我们新创建一个对象data,并在控制台输出
let data={name:1}
console.log(data)
我们看到的结果是这样的
接着我们用Object.defineProperty处理一下数据,比如创建一个成员
let data={name:1}
Object.defineProperty(data,'age',{
// getter
get(){
},
// setter
set(){
}
})
console.log(data)
再来看,这时多了两个方法
这就是Object.definepropty的作用,是es5中的一个方法,处理数据,给数据赋予getter和setter。
Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
正常情况下,这两个方法都不会触发,当我们给age赋值和改变age值的情况下会执行这两个函数
let middle = 6
Object.defineProperty(data,'age',{
get(){
console.log('获取age')
return middle
},
set(parmas){
//参数就是赋值的数据
console.log('修改age数据',parmas)
middle = parmas
}
})
console.log(data)
// 取值的时候触发getter
console.log(data.age)
//赋值的时候触发setter
data.age = 15
console.log(data.age)
difinePropty模拟响应式:
我们用这个方法来模拟vue底层的源码
通过按钮修改dom里面的数字:
<div id ='test'>
2
</div>
<button onclick="change()">change</button>
<script>
let data={}
function change(){
data.age =999
}
// 模拟vue中的源码
let middle = 2
Object.defineProperty(data,'age',{
get(){
return middle
},
set(params){
middle=params
// 只要是数据修改了就会指令
watcher()
}
})
// 绑定watcher监听
function watcher(){
// 数据改变之后触发 进行diff【判断是否应该修改dom
renderDom()
}
// 重新渲染的方法
function renderDom(h) {
let test = document.getElementById('test')
let age = data.age
test.innerHTML = age
}
console.log(data)
Vue中数据变页面一定变嘛?
- 那么问题来了,数据变页面一定变么?
- 不一定,数据变页面变的原因是因为数据劫持了data
先来看一个小例子:
<div id ='app'>
{{user}}
<hr>
<button @click='changeName'>changeName</button>
</div>
<script>
new Vue({
el:'#app',
data:{
user:{
age:15
}
},
methods: {
changeName(){
this.user.name = '韩梅梅'
console.log(this.user)
}
},
})
</script>
这时候我按钮,发现改变不了name的值,所以打开控制看一下
我们会发现只有age有getter和setter,name没有,Vue 无法检测到对象属性的添加或删除,所以没法进行响应式改变数据
TIPS:两种情况新添加的属性都有没有getter和setter,数据变页面也不变:1. 对象数据的添加 2. 数组长度的改变
解决方式:动态的往里面添加数据,使用this.$set方法
以上面例子为例:
methods: {
changeName(){
// this.user.name = '韩梅梅'
// set 将数据用 object.defainPropty进行处理 添加getter和setter
this.$set(this.user,'name','韩梅梅')
console.log(this.user)
}
}
这样我们就能在页面上看到新增的属性
更多推荐
所有评论(0)