Vue2&vue3 데이터 대응 원리 분석 및 매뉴얼 구현(상세 예시)

WBOY
풀어 주다: 2021-12-22 18:25:28
앞으로
2247명이 탐색했습니다.

이 글에서는 vue2&vue3 데이터 반응형 원리 분석 및 수동 구현에 대한 관련 지식을 제공합니다. 데이터 반응형 뷰와 데이터가 자동으로 업데이트되면 뷰가 자동으로 업데이트되어 데이터의 변경 사항을 추적할 수 있기를 바랍니다. 모두가 도움이 될 것입니다.

Vue2&vue3 데이터 대응 원리 분석 및 매뉴얼 구현(상세 예시)

데이터 반응성

  • 뷰와 데이터가 자동으로 업데이트됩니다. 데이터가 업데이트되면 뷰도 자동으로 업데이트됩니다.
  • 데이터 변경 사항을 추적하면 데이터를 읽거나 데이터를 설정할 때 일부 작업이 도용될 수 있습니다.
  • vue2는 defineProperty
  • vue3을 사용하고 Proxy를 사용합니다

defineProperty 사용

변경 사항을 추적하는 방법

var obj = {}var age 
Object.defineProperty(obj, 'age', {
    get: function() {
        consoel.log('get age ...')
        return age    },
    set: function(val) {
        console.log('set age ...')
        age = val    }})obj.age =100 //set age ...console.log(obj.age)//get age ...
로그인 후 복사

객체 obj는 age 속성을 가져올 때 데이터 하이재킹의 get 메서드를 호출합니다
age 속성에 값을 할당할 때 set method

그런 다음 Object.defineProperty를 사용하여 데이터 응답을 구현하는 방법

function defineReactive(data) {
  if (!data || Object.prototype.toString.call(data) !== '[object Object]')
    return;
  for (let key in data) {
    let val = data[key];
    Object.defineProperty(data, key, {
      enumerable: true, //可枚举
      configurable: true, //可配置
      get: function() {
        track(data, key);
        return val;
      },
      set: function() {
        trigger(val, key);
      },
    });
    if (typeof val === "object") {
      defineReactive(val);
    }
  }}function trigger(val, key) {
  console.log("sue set", val, key);}function track(val, key) {
  console.log("sue set", val, key);}const data = {
  name:'better',
  firends:['1','2']}defineReactive(data)console.log(data.name)console.log(data.firends[1])console.log(data.firends[0])console.log(Object.prototype.toString.call(data))
로그인 후 복사

defineReactve 함수는 Object.defineProperty를 캡슐화하는 데 사용됩니다. 캡슐화 후에는 데이터, 키, 값만 전달하면 됩니다defineReactve用来对Object.defineProperty进行封装,从函数名可以看出,起作用就是定义一个响应式数据,封装后只需要传递data,key和val就行
每当从data中读取key的时候触发track函数,往data的key中设置数据时,set函数中的trigger函数触发

数组的响应式

我们通过Array原型上的方法来改变数组的内容不会触发getter和setter
整理发现Array原型中可以改变数组自身内容的方法有7个,分别push pop shift unshift splice sort reverse
vue2 改写了这这7种方法
实现方式:
以Array.propertype为原型创建一个arrayMethods对象,再使用Object.setPropertypeOf(o, arryMethods)将o的__proto__指向arrayMethods

Vue2&vue3 데이터 대응 원리 분석 및 매뉴얼 구현(상세 예시)

如何收集依赖

使用

<template><p>{{name}}</p></template>
로그인 후 복사

该模板中使用数据 name, 我们要观察数据, 当数据的属性发生变化的时候, 可以通知哪些使用的地方,
这就是我们要先收集依赖,即把用到数据name的地方收集起来,然后等数据变化的时候,把之前收集好的依赖循环触发一遍,总结来说就是getter中收集依赖,在setter中触发依赖

使用proxy

Proxy对象用于创建一个对象的代理, 从而实现基本操作的拦截和定义(如属性查找、赋值、枚举、函数掉用等)

const p = new Proxy(target, handler)
로그인 후 복사
  • target

  • 要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

  • handler

  • 一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。
    reflect是一个内置对象, 他提供拦截javascript操作的方法, 这些方法和Proxy handlers相同

Reflect.set将值分配给属性的函数。返回一个Boolean 如果更新成功则返回true

Reflect.get获取对象身上某个属性的值,类似target[name]

如何实现劫持

const dinner = {
  meal:'111'}const handler = {
  get(target, prop) {
    console.log('get...', prop)
    return Reflect.get(...arguments)
  },
  set(target, key, value) {
    console.log('get...', prop)
    console.log('set',key,value)
    return Reflect.set(...arguments)
  }}const proxy = new Proxy(dinner, handler)console.log(proxy.meal)console.log(proxy.meal)
로그인 후 복사

代码中dinner 对象代理到handler上
defineProperty区别
defineProperty 데이터에서 키를 읽을 때마다 추적 기능이 트리거되고 데이터가 설정될 때 이 기능이 작동되는 것을 볼 수 있습니다. set 함수의 데이터 키에 트리거 함수는

배열의 응답성

을 트리거합니다. 우리는 배열 프로토타입의 메서드를 사용하여 배열의 내용을 변경하지만 getter 및 setter

를 트리거하지 않습니다. 배열 프로토타입에서 배열 자체의 내용을 변경할 수 있는 메서드를 구성하고 발견한 후 각각 push pop 7개가 있습니다. Shift unshift splice sort <code>reverse

vue2는 이 7가지 메서드를 다시 작성합니다

구현 방법:

Array.propertype을 프로토타입으로 사용하여 arrayMethods 객체를 만든 다음 Object.setPropertypeOf(o, arryMethods)o의 __proto__를 arrayMethods<img src="https://img.php.cn/upload/article/000/000/067/acd642f4f02e97980836bd636302ac44-1.png" alt="Vue2&vue3 데이터 대응 원리 분석 및 매뉴얼 구현(상세 예시)">

Vue2&vue3 데이터 대응 원리 분석 및 매뉴얼 구현(상세 예시)

종속성 수집 방법

function reactive(obj) {
  const handler = {
    get(target, prop, receiver) {
      track(target, prop);
      const value =  Reflect.get(...arguments);
      if(typeof value === 'Object') {
        reactive(value)
      }else {
        return value      }
    },
    set(target,key, value, receiver) {
      trigger(target,key, value);
      return Reflect.set(...arguments);
    },
  };
  return new Proxy(obj,handler)}function track(data, key) {
  console.log("sue set", data, key);}function trigger(data, key,value) {
  console.log("sue set", key,':',value);}const dinner = {
  name:'haochi1'}const proxy  =reactive(dinner)proxy.name
proxy.list = []proxy.list.push(1)
로그인 후 복사
를 사용하세요

데이터 이름이 사용됩니다. 이 템플릿에서는 데이터를 관찰해야 합니다. 데이터의 속성이 변경되면 해당 데이터가 사용되는 위치에 알릴 수 있습니다.
    이는 먼저 종속성을 수집해야 함, 즉 데이터 이름이 있는 위치를 수집해야 함을 의미합니다. 그런 다음 데이터가 변경되면 이전에 수집된 종속성 루프를 트리거합니다. 요약하면 종속성은 getter에서 수집되고 종속성은 setter에서 트리거됩니다.
  1. 프록시 개체를 사용하여 개체에 대한 프록시를 생성합니다. 기본 연산(속성 검색, 할당, 열거, 함수 삭제 등)의 차단 및 정의 구현
rrreee
  • target code><li> <li> <code>프록시(기본 배열, 함수 또는 다른 프록시를 포함한 모든 유형의 개체일 수 있음)
    handler
    일반적으로 함수를 속성으로 포함하는 개체입니다. 각 속성의 함수는 각각 다양한 작업을 수행할 때 에이전트 p의 동작을 정의합니다.
  • Reflect는 자바스크립트 작업을 가로채는 메서드를 제공하는 내장 개체입니다. 이러한 메서드는 속성에 값을 할당하는 프록시 처리기

  • Reflect.set 함수와 동일합니다. 부울을 반환하고 업데이트가 성공하면 true를 반환합니다.

    Reflect.get은 target[name]과 유사한 개체의 속성 값을 가져옵니다.
  • 하이재킹을 구현하는 방법

    rrreee

    코드의 저녁 개체는 다음으로 프록시됩니다. 핸들러
  • defineProperty Difference
defineProperty의 속성을 따라 모든 속성을 감독하려면 순회해야 합니다.

프록시를 사용하여 개체의 모든 속성을 프록시합니다

프록시를 사용하여 구현합니다. 시뮬레이션된 응답

rrreee실행 후 자동으로 인쇄

🎜🎜🎜생각: 왜 get 및 not set에서만 재귀를 사용합니까? 🎜🎜할당에도 get first가 필요합니다🎜🎜간단한 요약: 🎜🎜🎜vue2(얕은 응답)🎜🎜🎜 🎜데이터를 탐색하고 defineProperty를 사용하여 모든 속성을 가로채기🎜🎜사용자가 뷰를 조작하면 set 인터셉터가 트리거됩니다.🎜🎜set는 먼저 현재 데이터를 변경한 다음 시계에 알리고 시계가 뷰 업데이트를 알리도록 합니다.🎜🎜View redraw , 그리고 get again에서 해당 데이터를 얻습니다🎜🎜🎜 🎜vue3(깊은 응답성):🎜🎜🎜🎜🎜프록시를 위해 프록시를 사용합니다. 🎜🎜🎜🎜Reflect를 사용하면 프록시 객체의 해당 속성에 대해 특정 작업을 동적으로 수행합니다.🎜🎜🎜🎜프록시 객체(프록시)의 반사 객체(reflect)는 서로 협력해야 합니다. 응답성을 달성하기🎜🎜🎜🎜둘 사이의 차이점🎜🎜프록시 전체 객체를 하이재킹할 수 있는 반면, Object.defineProperty는 객체의 속성만 하이재킹할 수 있습니다. 전자는 해당 값의 프록시를 재귀적으로 반환하여 응답성을 달성할 수 있습니다. 후자는 각 속성을 심층적으로 탐색해야 하며 후자는 배열 작업에 매우 비우호적입니다. 🎜🎜더 많은 프로그래밍 관련 지식을 보려면 🎜프로그래밍 소개🎜를 방문하세요. ! 🎜

위 내용은 Vue2&vue3 데이터 대응 원리 분석 및 매뉴얼 구현(상세 예시)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:csdn.net
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿