vue3的数据响应式基础原理

231 阅读1分钟

1.Proxy  对象用于定义基本操作的自定义行为(可以字面意思理解:代理)

和defineProperty类似,功能几乎一样,只不过用法上有不同


var ob = {

    a:1,

    b:2

}

// 不需要借助外部变量

// 不会污染源对象,会返回一个代理后的新对象

// 和defineProperty相比,它可以进行全对象监听,不需要进行 for in循环

// 可以监听数组,不用再去单独的对数组做特异性操作

var obj = new Proxy(ob,{

    // target:{a:1,b:2}

    // key:a/b

    // receiver:代理后的对象obj

    get(target,key,receiver){

        return target[key]

    },

    // value:传入的新值

    set(target,key,value,receiver){

        // return target[key] = value

        return Reflect.set(target,key,value)

    }

})


2.实现简单版的数据响应式

vue3.js:

function vue (){

    this.$data = {a:1}

    this.el = document.getElementById('app')

    this.virtualdom=""

    this.observer(this.$data)

    this.render()

}
// 注册get 和 setvue.prototype.observer = function (obj) {

    var self = this

    this.$data = new Proxy(this.$data,{

        get(target,key){

            return target[key]

        },

        // value:传入的新值

        set(target,key,value){

            // return target[key] = value

            Reflect.set(target,key,value)

            self.render()

        }

    })

}
vue.prototype.render = function () {    this.virtualdom = 'i am ' + this.$data.a

    this.el.innerHTML = this.virtualdom

}

index.html: 参考 vue2的数据响应式基础原理



3.还可以用proxy做什么


类型验证:创建对象时,该对象的name和age属性进行校验,name必须是中文,age必须是数字,并且大于18


// 策略模式

var validtor = {

    name:function(value){

        var reg=/^[\u4E00-\u9FA5]+$/

        if (typeof value === 'string' && reg.test(value)){

            return true

        }

        return false

    },

    age:function (value) {

        if (typeof value === 'number' && value >= 18) {

            return true

        }

        return false

    }

}
function person (age,name) {    this.age = age

    this.name = name

    return new Proxy(this,{

        get:function (target,key) {

            return target[key]

        },

        set :function(target,key,value){

            if (validtor[key](value)){

                return Reflect.set(target,key,value)

            }else {

                throw new Error(key + 'is not right!')

            }

        }

    })

}