vue2响应式原理,数据劫持,数据代理,Object.defineProperty()方法

数据代理、数据劫持概念

数据劫持

data中数据通过各种逻辑和封装变成_data,从而去监测data数据的变化,一旦发现data中数据变化了,_data就去修改页面,这个过程通过Object.defineProperty实现,叫数据劫持

数据代理

_data中数据拿出放在vm身上,就可以直接通过vm.name,不需要vm._data.name 通过Object.defineProperty()实现,这个过程叫数据代理

Object.defineProperty()方法

  • es5新增的一个方法
  • 作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性

语法:

js 复制代码
 Object.defineProperty(obj,prop,desc)
// obj:在哪个对象身上添加或者修改属性
// prop:添加或修改的属性名
// desc:配置项,一般是一个对象
/* 
  desc 配置项还有6个配置属性
  value: "jack",  给属性添加指定属性值
  writable: true, 默认false不可以修改,true属性可以被修改
  enumerable: true, 默认false不可以遍历,true可以被遍历
  configurable: true, 默认false不能删除,true可以被删除
  get(){}, 当读取属性值的时候,getter就会被调用,函数的返回值会作为该属性的值
  set(){}, 当修改属性值的时候,getter就会被调用,该方法将接受唯一参数,即该属性新的参数值
*/

注意:

  1. 当使用了 getter 或 setter 方法,不允许使用 writable 和 value这两个属性
  2. 不要在 gette r中再次获取该属性值,也不要在 setter 中再次设置该属性,否则会栈溢出

示例:

js 复制代码
  let  person = {
  name:"码农",
  age: 18
     }
     Object.defineProperty(person,'sex',{
         value:"男",  //设置属性值
         enumerable:true, //控制属性是否可以枚举,默认值是false
         writable:true, //控制属性是否可以被修改,默认值是false
         configurable:true //控制属性是否可以被删除,默认值是false
      })
    console.log(person)

数据代理

数据代理的概念

数据代理(Data Proxy):

  • 通过访问代理对象的属性,来间接访问目标对象的属性
  • 在 Vue 中,将data 对象中的属性代理到 Vue 的实例上
  • 这样一来,我们可以通过直接访问 Vue 实例来访问和修改其data对象的属性(这就是为什么直接Vue的实例 . 就可以访问到属性以及方法的底层原理)
  • 更加方便的操作data中的数据

Vue数据代理对属性名的要求

  • data对象的属性名不可以以 " _ "或 " $ " 开头,
  • 因为Vue的实例上的属性名以 " _ " 或 " $ " 开头,会产生冲突

数据劫持

数据劫持(Data Interception):

  • 数据劫持是指在访问或修改对象的属性时,对这些操作进行拦截和监视,以便在属性发生变化时能够触发相关的操作。
  • 在 Vue 中,数据劫持用于监听数据的变化,以实现双向绑定和响应式更新
  • Vue 通过在数据对象的属性上使用 Object.defineProperty 来实现数据劫持
  • 每当访问属性或修改属性时,Vue 会触发相应的 getset 拦截器,从而实现对数据变化的监听
  • 通过数据劫持,Vue 能够在属性发生变化时自动触发视图的更新,从而实现了响应式的特性

Vue数据代理、数据劫持底层实现

html 代码部分

html 复制代码
  <script src='./myVue.js'></script>
  <div id ="root"></div>
  <script>
   let vm = new MyVue({
    el: '#root',
    data(){
       return{
        name: '张三',
        age:18
       }
      },
     methods: {
       fn(){
        console.log('我是方法');
       }
     }
   });
  </script>

js 代码部分

js 复制代码
class MyVue {
  //简单实现数据代理
  constructor(options) {
    Object.keys(options.data()).forEach((item, index) => {
      Object.defineProperty(this, item, {
        get() {
          console.log('读取了数据',item);
          return options.data()[item]
        },
        set(value) {
          console.log('修改了数据',item,value);
          options.data()[item] = value
        }
      })
    })
    // 简单实现methods
    Object.keys(options.methods).forEach(item =>{
      this[item] = options.methods[item]
    })
  }
}
相关推荐
喵叔哟5 分钟前
重构代码之取消临时字段
java·前端·重构
远望清一色14 分钟前
基于MATLAB边缘检测博文
开发语言·算法·matlab
何曾参静谧22 分钟前
「Py」Python基础篇 之 Python都可以做哪些自动化?
开发语言·python·自动化
Prejudices26 分钟前
C++如何调用Python脚本
开发语言·c++·python
我狠狠地刷刷刷刷刷39 分钟前
中文分词模拟器
开发语言·python·算法
wyh要好好学习43 分钟前
C# WPF 记录DataGrid的表头顺序,下次打开界面时应用到表格中
开发语言·c#·wpf
AitTech43 分钟前
C#实现:电脑系统信息的全面获取与监控
开发语言·c#
qing_0406031 小时前
C++——多态
开发语言·c++·多态
孙同学_1 小时前
【C++】—掌握STL vector 类:“Vector简介:动态数组的高效应用”
开发语言·c++
还是大剑师兰特1 小时前
D3的竞品有哪些,D3的优势,D3和echarts的对比
前端·javascript·echarts