前端小白不迷路 - 今天来介绍下Vue2的响应式原理Object.defineProperty() -下篇

345 阅读2分钟

这是我参与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>

效果如图:

image.png

这个就是很简单的数据渲染视图的效果,但是小伙伴们不难发现,为什么一些数据必须要在data中先定义,后续使用this. 这个语法就可以拿到值或者定义值,比如拿到后端返回的数据,赋值给事先定义的数据或对象,这是因为 Object.defineProperty()天生就有 ‘如果对象新增一个属性,那这个属性不是响应式的’ 这个缺陷,所以在使用数据之前为了保证响应式,必须先在data中定义。

比如下面在控制台打印的,带{...}的就是被劫持的对象属性,当我们访问的时候 就会执行get函数,上节课也有说过。 image.png 当我们给诗人重新命名的时候,就会同步响应到dom上,更改视图,如图:

image.png

下面我们想给诗歌附上内容,在控制台输入以下内容:

image.png

可是发现浏览器内没有发生任何变化,这是因为新增的对象属性,在data中没有事先定义,加上去不是响应式的,不会同步更改,但是属性确定是加上了的,如图所示:

image.png

如何解决新增属性是响应式的

官网提供了,vue.set()的方法,和vm.$set()一样,都可以实现对象新增属性是响应式的。vue.set直通车 语法结构如下: Vue.set( target, propertyName/index, value ) 参数一: 设置属性的对象 参数二: 给对象新增什么属性 参数三: 新增属性的值

正确书写

Vue.set(vm.poets, 'first' , '白日依山尽')

image.png