Vue--数据代理


Object.defineProperty

let gender = '男';
let obj = {
  name: '野原新之助',
  age: 6
}
Object.defineProperty(obj, 'gender', {
  //默认不可枚举,要想可以枚举,就可以加enumerable: true
  //默认不可修改,要想可以修改,就可以加writable: true
  //默认不可删除,要想可以删除,就可以加configurable: true
  //当读取gender的值的时候,get函数(getter)会被调用,返回age的值
  get(){
    return gender;
  },
  //当修改gender的值的时候,set函数(setter)会被调用,更改age的值
  //采用这种方法的话可以实现gender与相应值的动态绑定
  set(value) {
    gender = value
  }
})
console.log(obj); //加了一个属性---gender: 男

在这里插入图片描述
先修改gen的值就可以发现obj的gender值也被修改了。
注意:如果是直接在对象设置值的话,将无法实现拓展功能,如不能被枚举、写等,以及无法实现动态绑定。而用该Object方法的话,相当于对象与变量之间的桥梁,从而能动态绑定。


简单的数据代理

let obj1 = {x: 100};
let obj2 = {y: 200};
Object.defineProperty(obj2,'x',{
    get(){
    //get的值来自于obj1中的x
        return obj1.x;
    },
    set(value) {
    //修改的时候将obj1中的x修改即可
        obj1.x = value;
    }
})

在这里插入图片描述


Vue中的数据代理

在这里插入图片描述
在这里插入图片描述
1.至于数据的动态变换涉及到之前的动态变化(data值一改变,就会在页面上呈现出来)。
2.为了实现响应式,将_data的内容做了一些改变
请添加图片描述


Vue检测数据的原理

对象

Vue是怎么检测到data的内容的改变呢,其实根本原因就是会给包括对象的内容加相应的getter和setter。(因此不可以直接将数组内的对象进行赋值,会检测不到)

部分底层原理:

<script type="text/javascript">
    let data ={
        name:'野原新之助',
        age:'6岁'
    }
	//接受相应的对象
    const obs = new Observer(data);

    let vm = {};	//创建vm实例对象
    vm._data = data = obs	//obs赋值给data,data赋值给vm._data

    function Observer(obj) {
        const keys = Object.keys(obj);  //获取obj对象中的keys
        keys.forEach((key)=>{     //遍历每个key
            Object.defineProperty(this, key, {  //this向外找到为Observer
                get() {
                    return obj[key];	//获取对象中某个
                },
                set(value) {
                    obj[key] = value;
                }
            })
        })
    }
</script>

而vue在实现相应功能还加了一些新的
1.数据代理,就是不需要通过_data来改变属性,参考前面内容。
2.即使是多层对象,每个对象都有相应的setter和getter(因为用了递归)。

在这里插入图片描述

Vue.set()方法

当在写完代码后,想在data中加一些数据(如增加属性值),不能直接在里面添加值,因为没有对应的getter和setter,也就不能进行响应式了,这是因为数据从data到_data的过程会增加setter和getter,而直接添加进_data就没有了,而且还不能直接在data里加值,因为vm中的属性本身就是通过数据代理来的,更不能直接在vm实例中添加。这时候就需要用到Vue.set()方法了,因为该方法会给添加的属性增加相应的getter和setter。

<div id="testBox">
    <h1>名字:{{name}}</h1>
    <h1>年龄:{{age}}</h1>
    <h1>幼儿园:{{people.kindergarten}}</h1>
    <h1>哪来的:{{people.address}}</h1>
    <h1>母亲名字:{{people.family.mother}}</h1>
    <h2>朋友:</h2>
    <ul>
        <li v-for="(friend,index) in people.friends" :key="index">
            {{friend.name}}--{{friend.age}}
        </li>
    </ul>
    <button @click="clickFun">点击增加幼儿园属性</button>
    
</div>
<script type="text/javascript">
    const vm = new Vue({
        el:'#testBox',
        data:{
            name:'野原新之助',
            age:'6岁',
            people:{
                address:'蜡笔小新',
                family:{
                    father:'野原广志',
                    mother:'野原美伢'
                },
                friends:[
                    {name:'饭团头',age:'6岁'},
                    {name:'妮妮',age:'5岁'}
                ]
            }
        },
        methods: {
            clickFun() {
                //Vue.set(target,key,val)
                Vue.set(this.people, 'kindergarten', '向日葵班');
                //或者this.$set(this.people, 'kindergarten', '向日葵班');
            }
        },
    })
</script>
</body>
</html>

还没添加
请添加图片描述

请添加图片描述

添加后
请添加图片描述

请添加图片描述

数组

请添加图片描述

数组内容没有相应的setter和getter,因此直接改变数组内索引对应的内容,不会改变页面的内容,即不会响应式,但是数据确实已经改变了。而对象的话,从前面我们已经知道,对象的属性会有getter和setter,因此是响应式的。

请添加图片描述

请添加图片描述

数组的响应式方法

1.push
尾部插入元素
2.pop
尾部删除元素
3.shift
头部删除元素
4.unshift
头部添加元素
5.splice
可以增删改

删除/插入/替换元素
删除元素:第二个参数传入你要删除几个元素(如果没有传,就删除后面所有元素)
替换元素:第二个参数,表示我们要替换几个元素,后面是用于替换前面的元素
插入元素:第二个参数,传入0,并且后面跟上要插入的元素
通用的方法就是splice(索引,删除元素个数,添加的元素),如果删除元素个数不为0,就是替换;如果删除元素个数为0,则是插入。

splice—菜鸟教程

6.sort
排序
7.reverse
反转元素
8.vue.set或者vm.$set(代码可以用this)(修改的对象,索引值,想要修改成为的值)

那么这些响应式的方法是怎么实现响应式的?

push为例:数组原型的push与受到Vue管理的数组数据的push不是同个方法。Vue管理的push除了有原数组的添加功能外,还加了重新解析模板的功能,也就是跟之前data一改变,进行响应式同样的道理。

请添加图片描述

数组更新检测–Vue

数据劫持

大佬的回答

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值