这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战
前言
各位掘友们晚上好,闲暇之余,让我们继续昨天的话题,Vue2的响应式原理Object.defineProperty() -下篇。
Object.defineProperty()在vue中的使用体现
首先下面写段vue实例的demo,代码如下:
<body>
<div id="app">
<h1>《{{title}}》</h1>
<h3 class="item">{{poets.dynasty}} - {{poets.name}}</h3>
<h3>{{poets.first}},{{poets.second}}</h3>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data: {
title: '望庐山瀑布',
poets: {
dynasty: '唐代',
name: '李白'
}
}
})
</script>
</body>
效果如图:
这个就是很简单的数据渲染视图的效果,但是小伙伴们不难发现,为什么一些数据必须要在data中先定义,后续使用this. 这个语法就可以拿到值或者定义值,比如拿到后端返回的数据,赋值给事先定义的数据或对象,这是因为 Object.defineProperty()天生就有 ‘如果对象新增一个属性,那这个属性不是响应式的’ 这个缺陷,所以在使用数据之前为了保证响应式,必须先在data中定义。
比如下面在控制台打印的,带{...}的就是被劫持的对象属性,当我们访问的时候 就会执行get函数,上节课也有说过。
当我们给诗人重新命名的时候,就会同步响应到dom上,更改视图,如图:
下面我们想给诗歌附上内容,在控制台输入以下内容:
可是发现浏览器内没有发生任何变化,这是因为新增的对象属性,在data中没有事先定义,加上去不是响应式的,不会同步更改,但是属性确定是加上了的,如图所示:
如何解决新增属性是响应式的
官网提供了,vue.set()的方法,和vm.$set()一样,都可以实现对象新增属性是响应式的。vue.set直通车 语法结构如下: Vue.set( target, propertyName/index, value ) 参数一: 设置属性的对象 参数二: 给对象新增什么属性 参数三: 新增属性的值
正确书写
Vue.set(vm.poets, 'first' , '白日依山尽')