更新时的一个问题
就是使用对象进行更新时,发现页面并没有被渲染出来
但是实际上数据是已经改了,但是vue并没有监听到,并修改
如果我们先改数据,然后在点vue测试工具,就测试里面的数据发生改变了
此时我们就引出了vue监测数据的原理--对象
就是vm中的data是先加工然后在渲染到页面。get就是获取data中的值然后渲染到页面,而set是当data中的数据发生改变时,更新页面
如果要我们来做,我们可以通过这种方式实现。但是实际上的vue比我们完善的更多
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<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)=>{
Object.defineProperty(this,k,{
get(){
return obj[k]
},
set(val){
console.log(`${k}被改了,我要去解析模板,生成虚拟DOM.....我要开始忙了`)
obj[k] = val
}
})
})
}
</script>
</body>
</html>
这个是往this上面添加属性,也就是这个函数的实例对象Observer。这样是避免进入死悬念。因为如果你获取到了属性,就要去修改,你要去修改,就要获取值,这样就进入死循环了。
vue.set()的使用以及数组中的应用
这里讲了一个很有趣的事
{{student.age}} 这个不会报错,因为会去找data中的student,而这个student是一个对象,对象中没有这个属性,只会返回undefined,而vue是不会渲染到页面中的
{{age}}这个会报错,因为data中没有定义age这个数据
data:{
student:{
name:'zs'
}
}
我们直接在vm.sex='男'这样是不会渲染到页面上的,因为我们new 一个vue实例 它是通过get set响应式的,而不是干巴巴这样
就是我们想要后添加的也有响应式的效果
target:往谁身上追加数据
key:属性名
val:属性值
还有一个api效果跟这个也一样
注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象。
Vue是如何监测数组改变的
在数组中没有找到为数组中服务的get set因此就意味的数据能改掉的,但是vm并没有监测到,
用数组的方法就能 监测到
当然这个数组的方法是vue包装出来的
当然Vue.set()也能实现 1,‘打台球’ 意思是下标为1的元素替换为打台球
数据监测总结
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的根数据对象 添加属性!!!
数据劫持:每一次数据改变的时候,去执行更新视图的操作.