Object.defineProperty在Vue2双向绑定中的核心原理及应用

news2024/11/15 11:01:28

目录

1.Object.defineProperty方法

(1)介绍

(2)语法

(3)descriptor属性描述符

2.Object.defineProperty在Vue2双向绑定的核心原理

3.Object.defineProperty在vue2中的应用

(1)v-model指令

(2)计算属性(Computed Properties)

(3)侦听器(Watchers)

4.Vue 3.x中的变化

(1)Object.defineProperty进行数据劫持的缺点

(2)Vue3的Proxy

总结:


本文主要讲解了Object.defineProperty方法的功能及在Vue中实现双向绑定的核心原理。强调了Object.defineProperty在Vue框架中用于数据劫持、属性定义和修改的重要性,以及如何通过这种方式实现数据与视图的自动同步更新。

1.Object.defineProperty方法

(1)介绍

Object.defineProperty() 方法是 JavaScript 中的一个非常重要的方法,它允许你精确地添加或修改对象的属性。与简单地使用赋值操作(如 obj.prop = value)不同,Object.defineProperty() 允许你设置属性的多种特性,如是否可枚举(enumerable)、是否可配置(configurable)、是否可写(writable),以及为属性指定一个 getter 或 setter 函数。

(2)语法

Object.defineProperty(obj, prop, descriptor)
  • obj:定义属性的对象。
  • prop:定义或修改的属性的名称。
  • descriptor:通常设置一个对象,去定义或修改的属性描述符。

(3)descriptor属性描述符

属性描述符对象具有以下属性:

  • value:属性默认值。
  • writable:设置属性是否能改修改(true|false)。
  • enumerable:是否可以枚举,即是否允许遍历(true|false)。
  • configurable:是否可以删除(true|false)。
  • get:作为该属性的获取getter 函数,如果没有 getter 则为 undefined当访问该属性时,会调用此函数,执行时不传入任何参数,并返回该属性的值。
  • set:作为该属性的设置setter 函数,如果没有 setter 则为 undefined当属性值被修改时,会调用此函数,该函数接受一个参数(被赋予的新值),并不返回任何值,使用 return 语句是无效的。

示例 1:简单使用

javascript代码

// 定义一个空对象
let obj = {};

// 定义一个属性并使用Object.defineProperty方法定义其特性
Object.defineProperty(obj, 'name', {
    value: 'John', // 属性的值
    writable: false, // 该属性的值是否可以被修改
    enumerable: true, // 该属性是否可以被枚举
    configurable: false // 该属性是否可以被删除或修改特性
});

// 尝试修改属性值
obj.name = 'Jane'; //设置无效

// 枚举属性
for (let key in obj) {
    console.log(key); // name
}

// 获取属性描述符
console.log(Object.getOwnPropertyDescriptor(obj, 'name')); // { value: 'John', writable: false, enumerable: true, configurable: false }

// 删除属性
delete obj.name; //删除无效
console.log(obj.name); // John
const obj1 = {};
Object.defineProperty(obj1, 'sex', {
    get:function() {
        console.log("正在获取属性");
    },
    set:function(value) { 
        console.log("正在设置属性");
    }
});

示例 2:使用get和set

const myObj = {
    __prop:'initial value'
};
Object.defineProperty(myObj,'prop',{
    get:function(){
        return this.__prop;
    },
    set:function(newValue){
        this.__prop = newValue;
    },
    enumerable: true,
    configurable: true, 
})
console.log(myObj.prop); //initial value
myObj.prop = "new value"; 
console.log(myObj.prop); //new value 

示例3:JS实现双向数据绑定原理

<body>
    <div id="demo"></div>
    <label for="inp">请输入文本:</label>  
    <input type="text" id="inp">
    <!-- Object.defineProperty是JavaScript 中用于定义或修改对象的属性的方法,可以控制属性的特性(如可枚举性、可配置性、可写性等)。 -->
    <!-- 语法: Object.defineProperty(obj,prop,descriptor)-->
    <script>
    // 实现双向数据绑定原理
    let obj2 = {};
    let demo = document.getElementById('demo');
    let inp = document.getElementById('inp');
    Object.defineProperty(obj2,"name",{
        get:function(){

        },
        set:function(newVal){
            console.log(newVal);
            demo.innerHTML = newVal;
        }
    })
    inp.addEventListener('input',function(e){
        obj2.name = e.target.value;
    })
    </script>
</body>

注意:默认情况下,使用 Object.defineProperty() 添加的属性是不可枚举的,即不会出现在 for...in 循环和 Object.keys() 方法中,除非明确将 enumerable 设置为 true

2.Object.defineProperty在Vue2双向绑定的核心原理

在Vue的双向绑定中,Object.defineProperty方法是核心。

Vue.js的Vue 2.x版本通过Object.defineProperty方法实现了数据的双向绑定。这一方法允许开发者直接在一个对象上定义新属性,或者修改一个对象的现有属性,并返回这个对象。具体到Vue的双向绑定中,Object.defineProperty被用来劫持或监听对象属性的getter和setter方法。

数据劫持:当Vue实例初始化时,它会对data选项中的每个属性使用Object.defineProperty方法进行数据劫持。当数据发生变化时,就会触发setter函数,通知依赖该属性的视图进行更新。

依赖收集:Vue内部维护了一个依赖收集系统,通常是通过Watcher对象实现的。当组件渲染时,会触发getter方法,Vue会将当前Watcher对象添加到该属性的依赖列表中。

更新视图:当数据变化时,setter方法被触发,Vue会遍历该属性的依赖列表,通知所有依赖的Watcher对象进行更新。Watcher对象随后会触发对应的视图更新。

3.Object.defineProperty在vue2中的应用

在Vue的双向绑定中,Object.defineProperty的应用主要体现在以下几个方面:

(1)v-model指令

v-model是Vue中实现双向绑定的主要指令。当在表单元素上使用v-model时,Vue会自动为该元素创建一个数据绑定,并监听其input事件来更新数据。这背后就是Object.defineProperty在起作用,它确保了数据模型(Model)和视图(View)之间的同步,非常方便。

注:CDN引入的vue2

示例:

<body>
    <div id="app">
        <p>{{name}}</p>
        <input type="text" v-model="name" placeholder="请输入名字">
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
    <script>
        // v-model实现双向数据绑定
        new Vue({
            el: '#app',
            data: {
                name: '哈哈'
            }
        })
    </script>
</body>

(2)计算属性(Computed Properties)

计算属性是基于它们的依赖进行缓存的响应式属性。Vue在内部也是通过Object.defineProperty来定义这些计算属性的getter和setter。尽管setter在大多数情况下是不必要的,因为计算属性通常是只读的。

示例:

<body>
    <div id="app">  
        <p>原始字符串: "{{ message }}"</p>  
        <p>处理后的: "{{ reversedMessage }}"</p>  
    </div>  
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
    <script>  
        new Vue({  
            el: '#app',  
            data: {  
                message: '123456'  
            },  
            computed: {  
                reversedMessage: function () {  
                    return this.message.split('').reverse();  
                }  
            }  
        })  
    </script>  
</body>

(3)侦听器(Watchers)

Vue允许开发者使用watch选项来观察和响应Vue实例上数据的变动。这同样依赖于Object.defineProperty来实现对数据的监听和响应。

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.js"></script>
</head>
<body>
    <div id="app">  
        <p>问题: {{ question }}</p>  
        <input v-model="answer" placeholder="输入答案">  
    </div>  
    <script>  
        var app = new Vue({  
            el: '#app',  
            data: {  
                question: '1 + 1 等于多少?',  
                answer: ''  
            },  
            watch: {  
                // 当answer发生变化时,这个匿名函数就会被调用  
                answer: function (newVal, oldVal) {  
                    console.log(`新答案: ${newVal}, 旧答案: ${oldVal}`);  
                    // 可以添加更复杂的逻辑,比如异步请求等  
                }  
            }  
        })  
    </script>  
</body>
</html>

4.Vue 3.x中的变化

(1)Object.defineProperty进行数据劫持的缺点

Object.defineProperty 主要是用来定义对象的属性,它不能拦截到数组的方法调用(如 pushpopshiftunshiftsplicesortreverse 等),这些方法会改变数组的内容但不会触发 Object.defineProperty 设置的 getter/setter。Vue.js 通过覆盖这些数组方法来解决这个问题,

(2)Vue3的Proxy

在Vue 3.x中,双向绑定的实现方式有所变化。Vue 3.x引入了Proxy对象来替代Object.defineProperty进行响应式系统的实现。Proxy提供了一种更强大的方式来拦截和定义对象上的基本操作(如属性查找、赋值、枚举、函数调用等),可以完美监听到任何方式的数据改变。

总结:

Object.defineProperty在Vue 2.x的双向绑定中起核心作用,它通过数据劫持和依赖收集/派发更新的机制实现了数据模型与视图之间的自动同步。而在Vue 3.x中,采用了不同的实现方式(Proxy),但双向绑定的核心原理仍然相同。

如果对你有帮助,给个赞行嘛~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1971422.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

专业人士如何选?揭秘4款2024年常用的电脑录屏软件!

在这个数字化时代&#xff0c;无论是教学、演示、游戏直播还是软件操作&#xff0c;电脑录屏软件已经是我们日常工作中的好帮手。但市面上这么多的电脑录屏软件&#xff0c;要想挑一款既专业又好用的&#xff0c;还真是挺让人头疼的。今天&#xff0c;我们就来聊聊四款常用的电…

mybatis开启数据库的驼峰命名

在application.yml文件中添加 mybatis:configuration:map-underscore-to-camel-case: true

powerjob连接postgresql数据库(支持docker部署)

1.先去pg建一个powerjob-product库 2.首先去拉最新的包&#xff0c;然后找到server模块&#xff0c;把mysql的配置文件信息替换成pg的 spring.datasource.hikari.auto-committrue spring.datasource.remote.hibernate.properties.hibernate.dialecttech.powerjob.server.pers…

全自动迷你洗衣机什么牌子好?五款卓越内衣洗衣机大合集!

随着科技的发展&#xff0c;市面上也出现许多便利的小家电。其中被多次讨论起来的莫过于是内衣洗衣机&#xff0c;选择一款耐用、质量优秀的内衣洗衣机&#xff0c;不仅可以减少洗衣负担&#xff0c;还能提供高效的洗涤效果。然而&#xff0c;随着内衣洗衣机的爆火&#xff0c;…

maven仓库密码加密方案原理

前言 有一个要求就是说不能使用明文密码&#xff0c;需要对 settings.xml 文件中的password密码进行加密 原始配置是没有对密码进行加密的 <server><id>gleam-repo</id><username>admin</username><password>admin123</password>&l…

7.2 单变量(多->多),attention/informer

继续上文书写&#xff1a; 1 GRU Attention 收敛速度稳定的很多&#xff0c;你看这些模型是不是很容易搭&#xff0c;像积木一样&#xff1b; def create_model(input_shape, output_length,lr1e-3, warehouse"None"):input Input(shapeinput_shape)conv1 Conv…

怎么给电脑文件加密?实用的四种方法,「重磅来袭」!

小李&#xff1a;“嘿&#xff0c;小张&#xff0c;你上次提到的那个重要项目报告&#xff0c;我放在了电脑里&#xff0c;但总觉得不太安全&#xff0c;万一被误删了或者不小心泄露了怎么办&#xff1f;” 小张&#xff1a;“别担心&#xff0c;小李&#xff0c;给文件加密是…

如何提高工作效率?分享9个高效率工作的方法

如果您的企业正在面临以下问题&#xff1a; 员工敏捷性和生产力降低员工满意度不足利润下降 那么您需要创建一个运营改进指南。 这需要经常更新&#xff0c;因为这不是一次性的努力&#xff0c;而是必须定期进行的持续过程。然而&#xff0c;您的运营改进指南还必须强调优化…

java 垃圾回收器以及JVM调优方式

什么是垃圾&#xff1a; 没有被引用的对象 就是垃圾。 定位的方式 reference count: 引用计数&#xff0c;即在对象上记录着有多少个引用指向它。&#xff08;循环引用无法解决&#xff09; root searching: 根可达算法&#xff0c;根对象包含 线程栈变量&#xff0c;静态变…

bootStrap中操作行详情,删除,修改等操作

点击列表某一行的操作按钮&#xff0c;结合swtich case 出发不同操作

【2024算力大会分会 | SPIE出版】2024云计算、性能计算与深度学习国际学术会议(CCPCDL 2024)

【2024算力大会分会 | SPIE出版】 2024云计算、性能计算与深度学习国际学术会议(CCPCDL 2024) 2024 International conference on Cloud Computing, Performance Computing and Deep Learning CCPCDL往届均已完成EI检索&#xff0c;最快会后4个半月完成&#xff01; 2024中…

postgresql 11.17 开发环境rpm安装及扩展安装

进入postgresql安装文件rpm所在文件夹 cd /data460/software 执行 yum local install *.rpm 提示缺少啥依赖就对应yum安装 最后有个依赖比较特殊 Requires: llvm-toolset-7-clang > 4.0.1 You could try using --skip-broken to work around the problem 需要安装centos-re…

Spring WebFlux 整合 r2dbc 的增删改查案例

无障碍阅读方法 微信公众号关注:张家的小伙子 回复:10205文章目录 无障碍阅读方法说明准备创建mysql数据库和数据表创建一个maven项目添加项目依赖包创建项目基本目录接口启动类编写编写application配置添加跨域请求配置创建实体-数据表映射类创建Dao操作类编写自己的增删改…

VS code 美化之 代码窗背景图 日志2024/8/2

VS code 美化之 代码窗背景图 先看效果: 参考文档: VSCode设置背景图片的两种方式_vscode代码背景-CSDN博客 用插件那个方法我试了,其只会在右侧 侧边栏目出现背景图,可能是我设置不正确吧 而且安装这个插件之后出现弹窗 vscode安装出现问题什么的提示,删除这个拓展就不会有…

时间价值衰减对期权价格有哪些影响?投资必知!

今天带你了解时间价值衰减对期权价格有哪些影响&#xff1f;投资必知&#xff01;期权的时间对期权的价格和价值具有重要影响&#xff0c;这是由于期权的特性和市场机制决定的&#xff0c;其实期权的时间价值是会衰减的。 期权的时间价值&#xff0c;指的是潜在的可能性。 比…

TypeScript(switch判断)

1.switch 语法用法 switch是对某个表达式的值做出判断。然后决定程序执行哪一段代码 case语句中指定的每个值必须具有与表达式兼容的类型 语法switch(表达式){ case 值1&#xff1a; ​ 执行语句块1 break; case 值2&#xff1a; ​ 执行语句块3 break; dfault: //如…

CSDN选择:腾讯cdn缓存跟阿里云cdn对比

在如今互联网迅速发展的时代&#xff0c;内容分发网络&#xff08;CDN&#xff09;变得越来越重要。而在众多CDN提供商中&#xff0c;腾讯云和阿里云的CDN服务无疑是具代表性的两家。那么&#xff0c;这两家的CDN服务究竟有何差异&#xff1f;哪一家更值得选择呢&#xff1f;今…

Python WSGI服务器库之gunicorn使用详解

概要 在部署 Python Web 应用程序时,选择合适的 WSGI 服务器是关键的一步。Gunicorn(Green Unicorn)是一个高性能、易于使用的 Python WSGI HTTP 服务器,适用于各种应用部署场景。Gunicorn 设计简洁,支持多种工作模式,能够有效地管理和处理大量并发请求。本文将详细介绍…

【Canvas与艺术】八角大楼

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>八角大楼</title><style type"text/css">.cen…

System,InvalidOperationException:未在本地计算机,上注册“Microsoft.ACE,OLEDB.12.0”提供程序。

未在本地计算机,上注册“Microsoft.ACE,OLEDB.12.0”提供程序 问题原因分析解决方案&#xff1a;第一步第二步 问题 本地导入excel没有问题&#xff0c;发布到服务器上出现System,InvalidOperationException:未在本地计算机,上注册“Microsoft.ACE,OLEDB.12.0”提供程序。 原…