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() 是弱引用,在内存不足的时候垃圾回收机制才会回收,可以作为缓存

总结

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

相关文章

  • vuex如何重置所有state(可定制)

    vuex如何重置所有state(可定制)

    在正式场景中我们经常遇到一个问题,就是登出页面或其他操作的时候,我们需要重置所有的vuex,让其变为初始状态,那么如何重置呢,下面就跟随小编一起来了解一下
    2019-01-01
  • Vue项目中使用WebUploader实现文件上传的方法

    Vue项目中使用WebUploader实现文件上传的方法

    WebUploader是由 Baidu WebFE(FEX) 团队开发的一个简单的以 HTML5为主 , FLASH为辅 的现代 文件上传组件 。这篇文章主要介绍了在Vue项目中使用WebUploader实现文件上传,需要的朋友可以参考下
    2019-07-07
  • vue中如何监听url地址栏参数变化

    vue中如何监听url地址栏参数变化

    这篇文章主要介绍了vue中如何监听url地址栏参数变化问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • 纯前端使用Vue3上传文件到minio文件服务器(粘贴可直接用)

    纯前端使用Vue3上传文件到minio文件服务器(粘贴可直接用)

    vue是目前最流行的前端框架,下面这篇文章主要给大家介绍了关于纯前端使用Vue3上传文件到minio文件服务器的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-04-04
  • Vue3中如何使用Three.js详解(包括各种样例、常见场景、问题及解决方案)

    Vue3中如何使用Three.js详解(包括各种样例、常见场景、问题及解决方案)

    Three.js是一个常见的需求,Three.js是一个用于在浏览器中创建和显示动画3D计算机图形的JavaScript库,这篇文章主要介绍了Vue3中如何使用Three.js的相关资料,包括各种样例、常见场景、问题及解决方案,需要的朋友可以参考下
    2025-04-04
  • vue如何解决空格和空行报错的问题

    vue如何解决空格和空行报错的问题

    这篇文章主要介绍了vue如何解决空格和空行报错的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • vue自定义指令directive的使用方法

    vue自定义指令directive的使用方法

    这篇文章主要介绍了vue自定义指令directive的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • 使用Vue CLI配置代码压缩、加密和混淆功能示例代码

    使用Vue CLI配置代码压缩、加密和混淆功能示例代码

    这篇文章主要介绍了使用Vue CLI配置代码压缩、加密和混淆功能,通过配置 vue.config.js 文件,我们可以使用 Vue CLI 轻松实现对 Vue 应用程序代码的压缩、加密和混淆,需要的朋友可以参考下
    2023-06-06
  • 详解如何在Vue3中实现懒加载组件

    详解如何在Vue3中实现懒加载组件

    随着现代前端框架的发展,懒加载作为一种优秀的性能优化技术,在用户体验和加载速度上扮演着越来越重要的角色,本文将详细介绍如何在 Vue 3 中实现懒加载组件,确保你能够将这一技术应用到自己的项目中,需要的朋友可以参考下
    2024-11-11
  • 解决element DateTimePicker+vue弹出框只显示小时

    解决element DateTimePicker+vue弹出框只显示小时

    这篇文章主要介绍了解决element DateTimePicker+vue弹出框只显示小时,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03

最新评论