【Vue】Vue中响应式原理和双向绑定的实现

😁 作者简介:一名大四的学生,致力学习前端开发技术

⭐️个人主页:夜宵饽饽的主页

❔ 系列专栏:Vue小贴士

👐学习格言:成功不是终点,失败也并非末日,最重要的是继续前进的勇气

​🔥​前言:

这里是我整理的关于Vue中双向绑定和响应式原理的理解,还有关于Vue3和Vue2版本响应式的区别,希望可以帮助到大家,欢迎大家的补充和纠正

vue 响应式原理以及双向绑定实现代码 ?

一、 双向绑定

双向绑定可以理解成:

第一向:数据驱动视图,通过getter/setter提前设置数据改变之后的回调来完成

第二向:视图到数据,通过事件驱动,通常涉及的是用户交互

双向绑定的核心就是响应式系统

二、响应式原理:

1)数据劫持

Vue使用名为Observer的类来实现数据劫持,当创建Vue实例时,Vue会遍历传入的数据对象,对其进行遍历递归并使用Object.defineProperty方法将对象的属性转化为"响应式"属性

2)建立依赖追踪关系

在属性转化为响应式属性时,Vue会为每一个属性创建Dep依赖对象,用于收集当前属性的依赖关系

3)依赖收集

当访问一个响应式数据时,Vue会在访问的过程中收集依赖,这是通过在getter方法中进行依赖追踪来实现的,在getter方法中,Vue会判断是否存在Dep对象,如果存在将Dep对象添加到依赖列表中,这样就建立了依赖关系,将属性和对应的Watcher对象关联起来

4)响应更新

当属性发生变化时,Vue会触发属性的setter方法,并通知该属性的Dep对象,然后Dep对象会遍历依赖列表,通知每一个依赖的Watcher对象进行更新操作

这就是响应式原理,也被称为发布订阅

🌱vue2中简单实现的响应式系统

javascript 复制代码
/**
 * 订阅-发布,get订阅,set发布
 */

class Dep{
    constructor(){
        this.subscribers=new Set()
    }

    depend(){
        //判断依赖目标。空时没有意义的
        if(Dep.target){
            this.subscribers.add(Dep.target)
        }
    }

    notify(){
        this.subscribers.forEach(el=>el())
    }
}

Dep.target=null
function defineReactive(obj,key,val){
    const dep=new Dep()

    Object.defineProperty(obj,key,{
        enumerable:true,
        configurable:true,
        get:function reactiveGetter (){
            dep.depend()
            return val
        },
        set:function reactiveSetter (newVal){
            if(newVal===val) return
            val=newVal
            dep.notify()

        }
    })
}


function watcher(fun){
    Dep.target=fun
    fun()
    Dep.target=null
}

let data={age:15,number:3}
defineReactive(data,'age',data.age)
defineReactive(data,'number',data.number)

let total=0

watcher(()=>{
    total=data.age * data.number
})

console.log(total)
data.age=20
console.log(total)

🌱vue3中简单实现的响应式系统

javascript 复制代码
class Dep{
    constructor(){
        this.subscribers=new Set()
    }

    depend(){
        if(Dep.target){
            this.subscribers.add(Dep.target)
        }
    }

    notify(){
        this.subscribers.forEach(el=>el())
    }
}


function definereactive(target){
    const dep=new Dep()

    let handle={
        get(target,key,receiver){
            dep.depend()
            return Reflect.get(target,key,receiver)
        },

        set(target,key,value,receiver){
            if(target[key]===value) return true
            Reflect.set(target,key,value,receiver)
            dep.notify()
        }
    }

    return new Proxy(target,handle)
}

Dep.target=null


function watcher(fun){
    Dep.target=fun
    fun()
    Dep.target=null
}

let data={age:15,number:2}

let proxyData=definereactive(data)

let total=0
watcher(()=>{
    total=proxyData.age * proxyData.number
})

console.log(total)
proxyData.number=4
console.log(total)

总结

⭐Vue3中改用proxy的利弊

放弃了对低版本浏览器的兼容,换来了三点的提升

  1. 对属性的添加和删除动作的监测
  2. 对数组基于下标的修改的监测
  3. 对Map,Set,WeakMap,WeakSet的支持
相关推荐
你熬夜了吗?1 分钟前
日历热力图,月度数据可视化图表(日活跃图、格子图)vue组件
前端·vue.js·信息可视化
我想学LINUX1 小时前
【2024年华为OD机试】 (A卷,100分)- 微服务的集成测试(JavaScript&Java & Python&C/C++)
java·c语言·javascript·python·华为od·微服务·集成测试
screct_demo1 小时前
詳細講一下在RN(ReactNative)中,6個比較常用的組件以及詳細的用法
javascript·react native·react.js
CodeClimb7 小时前
【华为OD-E卷 - 第k个排列 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
沈梦研7 小时前
【Vscode】Vscode不能执行vue脚本的原因及解决方法
ide·vue.js·vscode
轻口味8 小时前
Vue.js 组件之间的通信模式
vue.js
光头程序员9 小时前
grid 布局react组件可以循数据自定义渲染某个数据 ,或插入某些数据在某个索引下
javascript·react.js·ecmascript
fmdpenny10 小时前
Vue3初学之商品的增,删,改功能
开发语言·javascript·vue.js
小美的打工日记10 小时前
ES6+新特性,var、let 和 const 的区别
前端·javascript·es6
涔溪11 小时前
有哪些常见的 Vue 错误?
前端·javascript·vue.js