Vue2 中m-v和v-m的响应式原理简单复现

1.声明一个发布订阅模式
let dep = {
    map:{}, //map用于通过 事件名:【触发的函数1,触发的函数2】形式,来保存对象
    collect(keyName,fn){
        if(!this.map[keyName]){
            this.map[keyName]=[]
        }
        this.map[keyName].push(fn)
    },  //类似addEventListener,将监听的事件名都放入map中,在此案例中,一个属性名可能对应着多个m-v函数,同时触发
    trigger(keyName){
        this.map[keyName]&&this.map[keyName].forEach(fn=>fn())
    } //通过trigger方法来触发对应事件名所带有的所有函数
}

2.声明对象
let data = {a:'张三',b:'李四',c:'王五'}

3.遍历对象,给对象中的每个属性添加get和set的响应事件
object.keys(data).forEach(key=>{
    //将响应事件的函数抽离出来
    defineReactive(data,key,data[key])
})

3.defineReactive函数中定义响应式内容
function defineReactive(data,key,value){
    Object.defineProperty(data,key,()=>{
        get(){
            return value
        },
        set(newValue){
            if(newValue === value) return
            value = newValue
               dep.trigger(key)  //通过触发自定义事件,来使得修改某个属性的时候,触发该属性对应的多个相关视图的变化
        }
    })
}

4.定义一个compile函数,并触发(初始化),来丰富发布订阅里边的map
function compile(){
    let nodes = document.querySelector('#ap').childNodes
    nodes.forEach(node=>{
        if(node.nodeType===1){
            const attrs = node.attributes
            Array.from(attrs).forEach(attr=>{
                const dirName = attr.nodeName
                const dataPro = attr.nodeValue
                if(dirName ==='v-text'){
                    node.innerText = data[dataPro] //初始化渲染
                    dep.collect(dataPro,()=>{
                     node.innetText = data[dataPro]
                    })
                }
                if(dirName ==='v-model'){
                    node.value = data[dataPro] //初始化渲染
                    dep.collect(dataPro,()=>{
                       node.value = data[dataPro]
                    })
                    //设置监听事件
                    node.addEventListner('input',e=>{
                        data[dataPro]=.e.target.value
                    })
                }
            })
        }
    })
}

5. compile() 初始化渲染
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值