vue响应式理解

本文是个人对vue响应式的理解,如果有错误欢迎大家指正

阅读本文前请大家仔细理解官网中的响应式内容

https://cn.vuejs.org/v2/guide/reactivity.html

https://cn.vuejs.org/v2/guide/components.html#data-%E5%BF%85%E9%A1%BB%E6%98%AF%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0

 

响应式,官网的说法是:当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并追踪等。。。

我个人总结的是:未响应过的数据在第一次放到data选项中会被遍历然后进行追踪,给已经追踪过的数据添加新的属性如果不按照官网说的方式,则新加的属性不会被追踪

响应的时候只要有一个被响应的属性值改变就会重载一次数据,请看vue生命周期图 下图(when data changes)

下面粘出我的测试代码

在Child文件中

<template>
    <div @click="testParentClick" style="background: red;width: 100%;height: 100px"></div>
</template>

<script>
    export default {
        name: "Child",
        // data之所以用方法的方式,也是由于响应式,用有个function能保证每次创建的对象都是一个新的,如果不用function的形式就会出现(A,B都在调用该组件)在父类A中改变该组件的值,那么父类B中也会被改变,这是我个人理解;官方:https://cn.vuejs.org/v2/guide/components.html#data-%E5%BF%85%E9%A1%BB%E6%98%AF%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0
        data(){

            return {
                childData:[]
            }
        },
        methods:{
            testChildClick(){
                // 创建一个测试数据
                let testData=[
                    {name:'王二',age:'12'},
                    {name:'张三',age:'13'},
                    {name:'李四',age:'14'},
                ];
                console.log('子组件test1')
                console.log(testData) // 可以在控制台查看该对象是不是被响应了,结果:未被响应(测试该项的时候请先不要传值给父类要分步测试,如果传给父类了也会被改变)
                // 将数据传给父组件
                // this.$emit('parent-no-respond',testData) // 测试父类时使用
                 // 将 testData 给 childData,这是第一次赋值,会被响应
                this.childData=testData
                console.log(this.childData) // 响应数据
                console.log('子组件test2')
                console.log(testData) // 发现此时数据是响应的了
                // 将数据传给父组件
                // this.$emit('parent-respond',testData) // 测试父类时使用

            },
            testParentClick(){
                // 创建一个测试数据
                let testData=[
                    {name:'王二',age:'12'},
                    {name:'张三',age:'13'},
                    {name:'李四',age:'14'},
                ];
                // 将数据传给父组件
                this.$emit('parent-no-respond',testData) // 测试父类时使用
                // 将 testData 给 childData,这是第一次赋值,会被响应
                this.childData=testData
                // 将数据传给父组件
                this.$emit('parent-respond',testData) // 测试父类时使用
            }
        }
    }
</script>

<style scoped>

</style>

在父组件中Parent文件

 

<template>
<child @parent-no-respond="noRespond" @parent-respond="respond"></child>
</template>

<script>
    import Child from "./Child";
    export default {
        name: "Parent",
        components: {Child},
        data(){
            return {
                noRespondData:null,
                respondData:null
            }
        },
        methods:{
            noRespond(noData){
                console.log('父组件noRespond')
                console.log(noData)// 此时发现数据是未响应的
                this.noRespondData=noData
                console.log(noData)// 此时发现数据是响应的,因为noData一开始是未响应的,第一次赋值给data中的noRespondData会走getter setter 遍历属性
            },
            respond(respondData){
                console.log('父组件respond')
                console.log(respondData)// 此时发现数据是响应的
                // 给数据中每个人添加一个sex
                respondData.forEach((item)=>{
                    if (!('sex' in item)) {
                        item['sex'] = 11
                    }
                })
                console.log(respondData)// 此时发现sex是不响应的
                this.respondData=respondData
                console.log(this.respondData)// 此时发现sex是不响应的
                 /*之所以是sex是不响应的,因为respondData是已经被响应的不会再走官网说的getter和setter,所以新增的属性不会再响应。
                 如果想要sex响应
                  item['sex'] = 11替换成下面格式
                  this.$set(item, 'sex', 11)
                 */


            }
        }
    }
</script>

<style scoped>

</style>

以上就是我个人的理解以及相关测试,如有理解错误欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值