vue3双向绑定实现原理解读

 更新时间:2023年10月07日 09:25:17   作者:这是提莫大人  
这篇文章主要介绍了vue3双向绑定实现原理解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一、vue3为什么要用proxy实现双向绑定?

1.object.defineProperty的缺点

因为es5的object.defineProperty无法监听对象属性的删除和添加

不能监听数组的变化,除了push/pop/shift/unshift/splice/spObject.definert/reverse,其他都不行

Object.defineProperty只能遍历对象属性直接修改(需要深拷贝进行修改)

2.proxy的优点

>1、直接监听对象而非属性

>2、直接监听数组的变化

>3、拦截的方式有很多种(有13种,set,get,has)

>4、Proxy返回一个新对象,可以操作新对象达到目的

3.proxy的缺点

1、proxy有兼容性问题

不能用polyfill来兼容(polyfill主要抚平不同浏览器之间对js实现的差异)

二、实现Vue3双向绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div></div>
    <script>
        const toProxy = new WeakMap(); //存放的是代理后的对象
        const toRaw = new WeakMap();   //存放的是代理前的对象
        function trigger() {
            console.log('触发视图更新')
        }
        function isObject(target) {
            return typeof target === 'object' && target !== null;
        }
        function reactive(target) {
            if (!isObject(target)) {
                return target;
            }
            let proxy = toProxy.get(target)
            // 如果代理表中已经存在了  就把这个结果返回
            if (proxy) {
                return proxy
            }
            // 如果这个对象已经被代理过了  就直接返回
            if (toRaw.has(target)) {
                return target;
            }
            const handlers = {
                set(target, key, value, receiver) {
                    if (target.hasOwnProperty(key)) {
                        trigger()
                    }
                    return Reflect.set(target, key, value, receiver)
                },
                get(target, key, value, receiver) {
                    const res = Reflect.get(target, key, receiver)
                    if (isObject(target[key])) {
                        return reactive(res)
                    }
                    return res;
                },
                deleteProperty(target, key) {
                    return Reflect.deleteProperty(target, key)
                }
            }
            let observed = new Proxy(target, handlers)
            toProxy.set(target, observed);
            toRaw.set(observed, target)
            return observed
        }
        let obj = {
            name: '温小鹿',
            arr: [1, 2, 3]
        }
        // let p = reactive(obj)
        // p.name = 'jw'
        // let arr = [1, 2 ,3];
        // let p = reactive(arr)
        // p.push(4);
        // console.log(p)
        let p = reactive(obj)
        p = reactive(p)
        p = reactive(p)
        p.arr.push(4)
        console.log(p)
    </script>
</body>
</html>

害,基础不扎实,复习一下

Reflect是ES6为操作对象而提供的新API,proxy对象的方法在rReflect上都能找到

new WeakMap() 是弱引用,在内存不足的时候垃圾回收机制才会回收,可以作为缓存

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 使用Pinia Persistedstate插件实现状态持久化的操作方法

    使用Pinia Persistedstate插件实现状态持久化的操作方法

    Pinia 作为 Vue 的新一代状态管理工具,以其轻量化和易用性受到开发者的喜爱,然而,Pinia 默认使用内存存储状态,为了解决这个问题,我们可以借助 Pinia Persistedstate 插件来实现状态的持久化存储,本文将详细介绍该插件的使用方法,需要的朋友可以参考下
    2024-11-11
  • Vue使用Three.js创建交互式3D场景的全过程

    Vue使用Three.js创建交互式3D场景的全过程

    在现代Web开发中,通过在页面中嵌入3D场景,可以为用户提供更加丰富和交互性的体验,Three.js是一款强大的3D JavaScript库,它简化了在浏览器中创建复杂3D场景的过程,本文将介绍如何在Vue中使用Three.js,创建一个简单的交互式3D场景,需要的朋友可以参考下
    2023-11-11
  • vue2.0模拟锚点的实例

    vue2.0模拟锚点的实例

    下面小编就为大家分享一篇vue2.0模拟锚点的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • vue3 + ts + pnpm:nprogress / 页面顶部进度条效果实现

    vue3 + ts + pnpm:nprogress / 页

    NProgress是一款轻量级的进度条库,主要用于网页顶部显示页面加载或运行进度,它易于安装和使用,并提供良好的视觉效果,NProgress也可以与VueRouter结合使用,通过导航守卫在路由跳转时自动显示和隐藏进度条,该库的使用提高了用户对网页加载状态的感知,优化了用户体验
    2024-09-09
  • 使用Vue3和Plotly.js绘制交互式漏斗图的示例代码

    使用Vue3和Plotly.js绘制交互式漏斗图的示例代码

    漏斗图常用于可视化业务流程中的各个阶段的转换率,例如销售漏斗或营销漏斗,它可以帮助用户识别流程中的瓶颈和改进机会,本文给大家介绍了如何使用Vue3和Plotly.js绘制交互式漏斗图,,文中有相关代码示例供大家参考,需要的朋友可以参考下
    2024-07-07
  • 详解vue项目的构建,打包,发布全过程

    详解vue项目的构建,打包,发布全过程

    小编给大家通过本文详细介绍了关于vue.js项目的构建、打包、发布的全过程,文章很以后价值,值得你参考。
    2017-11-11
  • JavaScript获取echart曲线上任意点位的值详解

    JavaScript获取echart曲线上任意点位的值详解

    这篇文章主要为大家介绍了JavaScript获取echart曲线上任意点位的值详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 轻量级富文本编辑器wangEditor结合vue使用方法示例

    轻量级富文本编辑器wangEditor结合vue使用方法示例

    在我们项目中,有些时候需要使用富文本编辑器。本文将以百度开发的Ueditor结合Vue.js介绍一下。非常具有实用价值,需要的朋友可以参考下
    2018-10-10
  • vue3实现移动端滑动模块

    vue3实现移动端滑动模块

    这篇文章主要为大家详细介绍了vue3实现移动端滑动模块,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-09-09
  • Vue使用虚拟键盘及中英文切换功能

    Vue使用虚拟键盘及中英文切换功能

    这篇文章主要给大家介绍了关于Vue使用虚拟键盘及中英文切换的相关资料,有时候在大型触屏设备(如双屏设备)中往往就没有键盘去操作,所以就需要去建立一个虚拟键盘去操作,需要的朋友可以参考下
    2023-06-06

最新评论