vue 数据绑定 与 利用proxy校验拦截

Vue 数据绑定

在这里插入图片描述

Vue2

vue.js

function vue(){
    this.$data ={
        a:1
     };
    this.el = document.getElementById("app");
    this._html = "";
    this.observe(this.$data)
    this.render()
}

vue.prototype.observe = function(obj){
    var value;
    var self = this;
    for(var key in obj){
        value = obj[key];
        if(typeof value === "object"){
            this.observe(value);
        }else{
            Object.defineProperty(this.$data, key, {
                get:function(){
                    // 会有依赖收集 deep()  
                    return value;
                },
                set:function(newvalue){
                    // notify更新     监听组件语法树ast  observe('AST)
                    value=newvalue;
                    self.render()
                }
            })
        }
    }
}

vue.prototype.render = function(){
    this._html="i am" + this.$data.a;
    this.el.innerHTML = this._html;
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="app">

    </div>

    <script src="vue.js"></script>
    <script>
        var vm=new vue()
        setTimeout(function(){
            console.log('change')
            console.log(vm.$data)
            vm.$data.a=4
        },3000)  // 3秒视图更新
    </script>
</body>
</html>

单一对象可以,但是数组是如何让他监听从而更新视图的呢

var arraypro = Array.prototype;
var arrayob = Object.create(arraypro);
var arr=["push","pop","shift"]
// arr里的方法,既能保持原有的方法,又能触发更新 装饰着模式
arr.forEach(function(method,index){
    arryob[method] = function(){
        var ret = arraypro[method].apply(this,arguments);
        console.log('检测数组变动,触发更新')
        // self.render()
        return ret
    }

})

var arr =[];
arr.__proto__=arrayob;
arr.push(1)
Vue3
function vue(){
    this.$data ={
        a:1
     };
    this.el = document.getElementById("app");
    this._html = "";
    this.observe(this.$data)
    this.render()
}


vue.prototype.observe = function(obj){
    var self = this;
    this.$data=new Proxy(this.$data,{
        get:function(target, key) {
            return target[key]
        },
        set: function(target, key, newvalue){
            target[key] = newvalue
            self.render()
        }
    })
}


vue.prototype.render = function(){
    this._html="i am" + this.$data.a;
    this.el.innerHTML = this._html;
}



也可以看我之前的 vue3数据绑定 链接 地址

两种比较

defineProperty只能监听某个属性,不能全局对象监听,而proxy就可以,所以省去for-in;
defineProperty get中没有值;
,提高效率,可以监听数组,不需要再去单独对数组做操作

Proxy 做校验拦截

function createValidator(target,validator){
    return new Proxy(target,{
        _validator:validator,
        set(target,key,value,proxy){
            if(target.hasOwnProperty(key)){
                var validator = this._validator[key];
                if(validator(value)){
                    return Reflect.set(target,key,value,proxy)
                }else{
                    throw Error('type,error')
                }
            }
        }
    })
}

var personValidator = {
    name(val){
        return typeof val === "string"
    },
    age(val){
        return typeof val === "number"&&age>18
    }
}

class Person{
    constructor(name,age){
        this.name = name;
        this.age = age;
        return createValidator(this,personValidator)
    }
}

var tss = new Person('YP',18)


// tss.name  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值