【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中简单实现的响应式系统

/**
 * 订阅-发布,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中简单实现的响应式系统

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. vue2 双向数据实现原理

    2024-03-21 18:48:02       28 阅读
  2. Vue双向数据是如何实现

    2024-03-21 18:48:02       28 阅读
  3. Vue双向数据原理

    2024-03-21 18:48:02       63 阅读
  4. vue双向原理

    2024-03-21 18:48:02       52 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-21 18:48:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-21 18:48:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-21 18:48:02       82 阅读
  4. Python语言-面向对象

    2024-03-21 18:48:02       91 阅读

热门阅读

  1. ThreeJs的音频和位置音频

    2024-03-21 18:48:02       46 阅读
  2. 最新版android stuido加上namespace

    2024-03-21 18:48:02       41 阅读
  3. Python从入门到精通秘籍十

    2024-03-21 18:48:02       44 阅读
  4. 周记-week3-人脸识别

    2024-03-21 18:48:02       43 阅读
  5. 阿里云企业级 Kubernetes 部署方案详解

    2024-03-21 18:48:02       40 阅读
  6. 27-3 文件上传漏洞 - 文件类型绕过(后端绕过)

    2024-03-21 18:48:02       40 阅读
  7. set和map

    set和map

    2024-03-21 18:48:02      45 阅读
  8. 关于Grok-1

    2024-03-21 18:48:02       46 阅读
  9. C/C++蓝桥杯之报数游戏

    2024-03-21 18:48:02       39 阅读