IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Vue数据代理 -> 正文阅读

[JavaScript知识库]Vue数据代理

1 Object.defineProperty方法

在Vue中,有很多地方使用到了Object.defineProperty方法,例如数据劫持、数据代理、计算属性等。Object.defineProperty方法用来给一个对象添加属性,或者修改一个对象上的属性。它的语法如下:

Object.defineProperty(obj, prop, descriptor)
// obj:要定义属性的对象
// prop:要定义或修改的属性名称或Symbol
// descriptor:要定义或修改的属性描述符
// 返回值:该对象

在默认情况下,使用Object.defineProperty添加的属性不可以执行枚举、修改等操作,因此需要在descriptor中添加响应的配置项,配置项具体如下:

配置项描述
value该属性对应的值,可以是任何有效的JavaScript 值(数值,对象,函数等),默认为undefined
enumerable表示该属性是否可以枚举,true为可枚举,默认为false不可枚举
writable控制属性是否可以被修改,true为可以修改,默认为false
configurable控制属性是否可以被删除,true为可以被删除,默认为false
get(){}属性的getter函数,当访问该属性时,会调用此函数,该函数的返回值会被用作属性的值
set(){}属性的setter函数,当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),默认为undefined

示例:使用Object.defineProperty()方法为person对象添加一个新属性

let person = {};
Object.defineProperty(person, "name", {
    value: "橘猫吃不胖", // name属性值为橘猫吃不胖
    enumerable: true, // 属性可以枚举
})
console.log(person) // { name: '橘猫吃不胖' }
person.name = "张三"; // 修改name属性值为张三,结果不能修改
console.log(person) // { name: '橘猫吃不胖' }
delete person.name; // 删除该属性,结果不能删除
console.log(person) // { name: '橘猫吃不胖' }

由上面代码可知,无法修改和删除name属性,因此为其再添加配置项writable(是否可以被修改)和configurable(是否可以被删除),就可以执行修改和删除的操作了,代码如下:

let person = {};
Object.defineProperty(person, "name", {
    value: "橘猫吃不胖", // name属性值为橘猫吃不胖
    enumerable: true, // 属性可以枚举
    writable: true, // 属性可以被修改
    configurable: true, // 属性可以被删除
})
console.log(person); // { name: '橘猫吃不胖' }
person.name = "张三";
console.log(person); // { name: '张三' }
delete person.name;
console.log(person); // {}

示例:自定义setter和getter

let person = {};
let str = "橘猫吃不胖";
Object.defineProperty(person, "name", {
    get() { // 返回一个字符串
        return str;
    },
    set(value) {
        str = value; // 将字符串的值改为最新的值
    }
})
console.log(person.name); // 橘猫吃不胖
person.name = "张三";
console.log(person.name); // 张三

2 什么是数据代理

数据代理就是通过一个对象代理对另一个对象中属性的操作(读/写)。

比如说,有两个对象obj1和obj2,其中obj1中有一个属性x,但是在obj2中可以读取和修改obj1中的属性x,这样就达到了一个数据代理的效果,代码如下:

let obj1 = { x: 100 };
let obj2 = { y: 200 };
// 通过Object.defineProperty()方法为obj2添加属性x
Object.defineProperty(obj2, "x", {
    get() { // 读取时返回obj1的x值
        return obj1.x;
    },
    set(value) { // 修改时更改obj1的x值
        obj1.x = value;
    }
})

以上代码就是最简单的一个数据代理,我们可以通过obj2访问并修改obj1中的x的值,示例如下:

console.log(obj2.x); // 100
console.log(obj1.x); // 100
obj2.x = 150; // 通过obj2修改x的值为150
console.log(obj2.x); // 150
console.log(obj1.x); // 150

3 Vue中的数据代理

下面一段代码中,我们在data中定义了nameage,然后在页面上使用双大括号{{}}进行了数据显示。其中,Vue实例vm的身上会出现nameage两个属性。

    <div id="app">
        <h3>姓名:{{name}}</h3>
        <h3>年龄:{{age}}</h3>
    </div>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                name: "橘猫吃不胖",
                age: "2岁"
            }
        })
    </script>

我们在控制台输出一下vm实例,可以看到nameage两个属性,当我们将鼠标悬停在(...)上时,显示了Invoke property getter。通过对Object.defineProperty()方法的了解,我们可以知道nameage两个属性都是通过Object.defineProperty()方法添加上来的。
在这里插入图片描述
当访问name时,是getter在工作,当修改name时,是setter在工作,因此,在vm中,我们也可以看到它们的getter和setter方法。
在这里插入图片描述
那么我们通过vm读取与修改name都是通过读取与修改data中的name,这就是一个数据代理


接下来可以对我们刚才的结论进行验证。

验证getter方法

验证思路如下:当我们修改data中的name时,vm中的name也会进行一个修改。首先在控制台读取当前的namevm.name,我们通过vm来获得name,那么getter会将data中的name返回给vm
在这里插入图片描述
那么接下来我们将data中的name修改为张三,然后再来访问vm中的name,发现这时name变成了张三,此时我们就验证了getter方法。

    <div id="app">
        <h3>姓名:{{name}}</h3>
        <h3>年龄:{{age}}</h3>
    </div>
    <script>
        var vm = new Vue({
            el: "#app",
            data: {
                name: "张三", // name修改为张三
                age: "2岁"
            }
        })
    </script>

在这里插入图片描述

验证setter方法

在上面代码中我们将name修改为了张三,那么我们在控制台修改vm.name为橘猫吃不胖,这时会将data中的name修改为橘猫吃不胖。这个变化我们并不能通过我们的代码看出来,也不能通过普通的data.name拿到dataname的值,因此我们需要通过其他的途径拿到data的值。
在这里插入图片描述
这时我们发现,Vue实例vm中的_data属性帮我们存储了data的值,下面我们先对这个进行一个简单的验证。
在这里插入图片描述
思路如下,在代码中将data在外部定义,通过验证vm._data === options.data === data来验证我们的想法,其中options就是new Vue({})中大括号{}内的配置项,这时options.data就是我们在外部定义的data,具体代码如下:

    <div id="app">
        <h3>姓名:{{name}}</h3>
        <h3>年龄:{{age}}</h3>
    </div>
    <script>
        let data = {
            name: "张三",
            age: "2岁"
        }
        var vm = new Vue({
            el: "#app",
            data
        })
    </script>

在这里插入图片描述
这时我们就验证了vm._data就是在Vue配置项中的data。回到我们之前通过vm.name将张三修改为橘猫吃不胖,那么我们可以通过观察vm._data.name是否被修改来验证setter方法,从结果可以看到,答案是正确的。
在这里插入图片描述
因此,当我们使用vm.name = "橘猫吃不胖"来将name从张三修改为橘猫吃不胖时,那么就会通过setter方法将data进行一个修改。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-06-29 18:55:53  更:2022-06-29 18:56:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:42:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码