您的位置:首页 > Web前端 > Vue.js

vue深入响应式原理

2019-04-19 21:51 459 查看
  1. vue深入响应式原理
    数据模型 —》 vm(创建的实例 new Vue())中 的data选项
    状态管理
    什么叫做状态?什么叫做状态管理?
    我们使用一个数据去管理视图中的一个部分, 那么这条数据就叫做状态, 这种管理模式就叫做状态管理

对象的创建:

  1. var obj = {}
  2. var obj = new Object()

深入响应式原理:

  1. 当视图模型(VM)中的数据模型(M)发生改变时, 视图(V)就会进行更新
  2. Vue通过watcher将data中的属性全部使用Object.definePropery编程getter和setter,当属性值发生改变的时候, 就会触发, 然后watcher就会触发, 告诉视图(V)进行重新渲染
  3. 数据必须放在data选项中才能进行深入响应式

底层原理:
核心使用的是es5的一个方法,这个方法不支持ie8以及以下

Object.defineProperty(obj,obj.attr,descriptor)
参数:
obj
要在其上定义属性的对象。
obj.attr
要定义或修改的属性的名称。
descriptor
将被定义或修改的属性描述符。它是一个对象, 这个对象有哪些构成?
configurable: 决定了对象的key是否可删除
enumerable: 决定了对象是否可遍历(枚举)
writeable: 决定了对象的key的value是否可修改
存储器:
get函数 ----起了个名字getter 设置当前对象的key的初始值
set函数 ----起了个名字setter 修改当前对象的key的值

var vm = new Vue({
el: '#app',
data: {
msg: 'hello vue.js',
list: {
id: 1
}
},
methods: {
setHandler(){
this.$set(this.list,'name','张三')
}
},
watch: { //起到监听的作用
/* watch中存放的是方法, 方法名就是M(data选项) */
msg(){
console.log('msg改变了')
}
}
})

需求: 实例中data外的数据就要它响应
解决: 将非响应式属性合并到响应式属性身上

Vue.set(vm.someObj,prop,value)
this.$set(vm.someObj,prop,value)

问题: Vue.set底层源代码?
分析: 将一个对象(key , value)合并另一个对象身上
解决: 对象的合并: Object.assign(目标对象, 当前对象)

var obj = {
name:'张三'
}
Object.defineProperty(obj,'name',{
//存储器
get(){
//要求必须有返回值
return '李四'
},
set(value){ //value就是修改后的对象的key的value
console.log('set')
console.log('====================================');
console.log(value);
console.log('====================================');
document.querySelector('#app').innerHTML = value
}

// 监听机制
})
obj.name = 'wyx'
// document.querySelector('#app').innerHTML = obj.name

双向数据绑定(v-model )
效果
数据改 , 视图更
视图改, 数据更
实现
使用v-model实现
缺点
v-model默认绑定value属性, 所以v-model只能在表单使用
原理
为什么数据能直接在视图显示v-model默认绑定了DOM对象的value属性, 当它初次绑定的时候, 就会触发getter,watcher就会触发, watcher通知Vue生成新的VDOM树, 再通过render函数进行渲染,生成真实DOM
为什么视图修改数据就会修改当视图修改是, 意味着DOM的value属性值改变,就会触发setter,watcher监听机制就会执行watcher通知Vue生成新的VDOM树,再通过render函数进行渲染,生成真实 4000 DOM
watch
作用:
用来监听数据的变换, 当数据模型 (data选项 M)发生改变时, watch就会触发
使用
两种用法:

key的value值是一个函数 普通玩家
new Vue({
watch: {
key(value,oldvalue){}
}
})
key的value值是一个对象 主播/职业玩家
new Vue({
watch: {
key: {
deep: true/false 深入监听,
handler(value,oldvalue){} // 监听的处理函数
}
}
})

watch中的key指的就是data选项中key
例子:

第一种用法:

业务:当我写好姓和名 , 全称自动显示

Html:
<div id="app">
<div>
姓: <input type="text" v-model = "firstName">
</div>
<div>
名: <input type="text" v-model = "lastName">
</div>
<div>
全称; <input type="text" v-model = "fullName">
</div>
</div>

Js:
new Vue({
el: '#app',
data: {
firstName: '',
lastName: '',
fullName: ''
},
watch: {
firstName(val){
this.fullName = val + this.lastName
},
lastName(val){
this.fullName = this.firstName + val
},
fullName(val){
console.log( val )
this.firstName = val.slice(0,1)
this.lastName = val.slice(1)
}
}
})

第二种用法:

Html:

<div id="app"></div>
Js:
new Vue({
el: '#app',
data: {
msg: 'hello vue.js'
},
watch: {
msg: {
deep: true,
handler: function(){
alert('msg发生改变了')
}
}
}
})

watch,methods和computed
业务: 当我写好姓和名 , 全称自动显示

目的: 对比 watch vs computed vs methods

methods: 事件

computed:

有逻辑
要像变量一样使用 , 这个时候选computed
watch:

有异步操作
开销较大

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: