Principio de enlace bidireccional de Vue2

1. En vue2, el secuestro de datos (cambios de datos de monitoreo de eventos) a través de Object.defineProperty () realiza un enlace de datos bidireccional

Objeto.defineProperty() :

definición:

Object.defineProperty() El método define una nueva propiedad directamente en un objeto, o modifica una propiedad existente de un objeto y devuelve el objeto. (Mi propio entendimiento: a través de este método, puede agregar propiedades a objetos o modificar propiedades existentes, y puede monitorear los cambios en las propiedades)

En Vue2 podemos usar este método para usar el objeto de datos (datos)Object.defineProperty()进行监听data里面属性的变化进行双向数据绑定

2. Para el uso de Object.defineProperty (), consulte la documentación oficial de mdn, que no se explicará aquí, la documentación es la siguiente:

Objeto.defineProperty() - JavaScript | MDN

3. Utilice Object.defineProperty() una función para encapsular una nueva propiedad de un objeto y puede monitorear el cambio de esta propiedad.

 function objAddProperty(obj, key,value){
  // 返回处理完毕的对象
    return Object.defineProperty(obj,key, {
    set(val) {
      //属性被赋值或者被修改时该函数自动执行,函数只有一个形参,
      //形参值为该属性被修改后的最新值
    console.log('obj.a被修改成...'+val)
    value = val
      },
      get(){
      //属性被访问时该函数自动执行
      //属性的值即为该函数的返回值
      console.log('obj.a被访问...')
    return value 
  }
})
}
//声明一个对象
let obj={}
// 为对象新增属性并进行监听该属性的变化
obj= objAddProperty(obj, 'a',1)
console.log(obj);
obj.a=666

3. Utilice Object.defineProperty() una función para modificar las propiedades existentes del objeto y puede monitorear los cambios de las propiedades. También puede realizar el secuestro de propiedades sin modificar las propiedades (secuestro de datos en Vue2, secuestro de cambios en las propiedades del objeto)

 1. Secuestrar un atributo en el objeto.

    function observeKey(obj, key) {
  let value = obj[key];
  Object.defineProperty(obj, key, {
    set(val) {
      //属性被赋值或者被修改时该函数自动执行,函数只有一个形参,
      //形参值为该属性被修改后的最新值
    console.log('属性被修改成...'+val)
    value = val
      },
      get(){
      //属性被访问时该函数自动执行
      //属性的值即为该函数的返回值
      console.log('属性被访问...')
    return value 
  }
  });
}
let obj = { a: 1 };
observeKey(obj, "a");
// 读取a,触发get函数
console.log(obj.a);
// 设置a,触发set函数
obj.a = 2;

2. Secuestra todas las propiedades del objeto.

De hecho, es atravesar las propiedades del objeto a monitorear.

   function observeObj(obj){
    //循环对象的属性进行监听
   for(let key in obj){
  observeKey(obj,key)
}
   }
    function observeKey(obj, key) {
  let value = obj[key];
  Object.defineProperty(obj, key, {
    set(val) {
      //属性被赋值或者被修改时该函数自动执行,函数只有一个形参,
      //形参值为该属性被修改后的最新值
    console.log('属性被修改成...'+val)
    value = val
      },
      get(){
      //属性被访问时该函数自动执行
      //属性的值即为该函数的返回值
      console.log('属性被访问...')
    return value 
  }
  });
}
let obj = { a: 1,b:2 };
observeObj(obj)
// 读取a,触发get函数
console.log(obj.a);
// 设置a,触发set函数
obj.a = 2;
// 读取b,触发get函数
console.log(obj.b);
// 设置a,触发set函数
obj.b = 3;

Nota: Hay un defecto en lo anterior, es decir, cuando el valor del atributo también es un objeto, el valor del atributo no se puede secuestrar, como {a:1,c:{b:1}}

Solución: determine el tipo de datos del valor del atributo del objeto y determine si se requiere recursividad

   function observeObj(obj){
    //循环对象的属性进行监听
   for(let key in obj){
  if(obj[key] instanceof Object){
    observeObj(obj[key])
  }
  else{
    observeKey(obj,key)
  }
}
   }
    function observeKey(obj, key) {
  let value = obj[key];
  Object.defineProperty(obj, key, {
    set(val) {
      //属性被赋值或者被修改时该函数自动执行,函数只有一个形参,
      //形参值为该属性被修改后的最新值
    console.log('属性被修改成...'+val)
    value = val
      },
      get(){
      //属性被访问时该函数自动执行
      //属性的值即为该函数的返回值
      console.log('属性被访问...')
    return value 
  }
  });
}
let obj = { a: 1,c:{b:2} };
observeObj(obj)
// 读取a,触发get函数
console.log(obj.a);
// 设置a,触发set函数
obj.a = 2;
// 读取b,触发get函数
console.log(obj.c.b);
// 设置a,触发set函数
obj.c.b = 3;

 Tenga en cuenta que la función observeObj no puede secuestrar las nuevas propiedades del objeto, solo puede secuestrar las propiedades existentes del objeto.

cuatro,Object.defineProperty()的缺陷

1. El monitoreo en profundidad requiere recursión única (alto consumo de rendimiento)

2. No se pueden monitorear las propiedades agregadas y eliminadas del objeto.

Cinco, simulación simple de enlace de datos bidireccional

Nota: Si no comprende this._name, utilizará Object.definePropety para informar un error Se excedió el tamaño máximo de la pila de llamadas

<!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 class="app">
      <input type="text">
      <p><span></span></p>
      <p><button>点击修改data数据模型的name值为马云</button></p>
    </div>
    <script>
      const button=document.querySelector("button")
      const span=document.querySelector("span")
      const input =document.querySelector('input')
      const data={
       name:'hsq'
      }
      input.value=data.name
      span.innerText=`data数据模型的值为${data.name}`
      Object.defineProperty(data,'name',{
        get(){
          return this._name
        },
        set(newValue){
          input.value=newValue
          this._name=newValue
          span.innerText=`data数据模型的值为${newValue}`
          console.log('data数据模型name属性值',newValue);
        }
      })
      input.addEventListener("input",function(e){
        console.log('输入框的值',e.target.value);
        data.name=e.target.value
      })
      button.addEventListener("click",function(){
        data.name='马云'
      })
    </script>
</body>
</html>

Supongo que te gusta

Origin blog.csdn.net/h18377528386/article/details/127515469
Recomendado
Clasificación