목차
반응성 원리란 무엇인가요? Vue에서는 세 가지 반응형 솔루션, 즉 DefineProperty, Proxy 및 값 설정자가 사용되었습니다. 먼저 Vue 2의 DefineProperty API를 살펴보겠습니다.
定制响应式数据
Vueuse 工具包
click
웹 프론트엔드 View.js Vue3의 반응 메커니즘에 대한 심층 분석을 제공하는 기사

Vue3의 반응 메커니즘에 대한 심층 분석을 제공하는 기사

Sep 19, 2022 pm 08:13 PM
vue

Vue3의 반응 메커니즘에 대한 심층 분석을 제공하는 기사

오늘은 Vue 3의 반응 메커니즘을 심층적으로 이해하도록 안내하겠습니다. 오늘 내용을 학습한 후에는 반응 메커니즘에 대해 더 깊이 이해하게 될 것이라고 믿습니다. 반응 메커니즘을 익히도록 도와주세요. 공식적으로 학습을 시작해 보세요! [관련 권장 사항: vuejs 비디오 튜토리얼]

응답성은 항상 Vue

의 특별한 기능 중 하나였습니다. 반면에 JavaScript의 변수에는 응답성이라는 개념이 없습니다. JavaScript를 배울 때 주입되는 개념은 코드가 위에서 아래로 실행된다는 것입니다.

다음 코드를 살펴보겠습니다. 코드가 실행된 후 출력되는 두 개의 이중 결과는 값을 수정한 후에도 2입니다. 코드에서 count를 하면 double의 값은 전혀 변하지 않습니다

let count = 1
let double = count * 2
count = 2
로그인 후 복사
double의 값은 count에 2를 곱한 값을 기준으로 계산됩니다. 이제 double이 count의 변화와 변화를 따르도록 하려면 다음이 필요합니다. count 값이 수정될 때마다 double을 다시 계산하려면

예를 들어 다음 코드에서는 먼저 double을 계산하는 논리를 함수로 캡슐화한 다음 count를 수정한 후 다시 실행하면 다음과 같은 결과를 얻을 수 있습니다. 최신 이중값

let count = 1
// 计算过程封装成函数
let getDouble = n=>n*2 //箭头函数
let double = getDouble(count)
count = 2
// 重新计算double ,这里我们不能自动执行对double的计算
double = getDouble(count)
로그인 후 복사
실제 개발에서의 계산 로직은 이중값을 계산하는 것보다 훨씬 복잡하지만 실행을 위해 함수로 캡슐화할 수 있습니다. 다음으로 고려해야 할 것은 이중값을 자동 계산으로 만드는 방법입니다

아래 그림과 같이 getDouble 함수가 자동으로 실행되도록 할 수 있다면 JavaScript의 일부 메커니즘을 사용하여 count를 레이어로 래핑하고 count가 수정될 때마다 double의 값이 동기적으로 업데이트되어 느낌이 듭니다. double이 개수에 따라 자동으로 바뀌는 것처럼 이것이 반응성의 원형입니다

Vue3의 반응 메커니즘에 대한 심층 분석을 제공하는 기사

반응성 원리

반응성 원리란 무엇인가요? Vue에서는 세 가지 반응형 솔루션, 즉 DefineProperty, Proxy 및 값 설정자가 사용되었습니다. 먼저 Vue 2의 DefineProperty API를 살펴보겠습니다.

다음 코드에서는 객체 obj를 정의하고, defineProperty를 사용하여 프록시를 사용합니다. 이런 방식으로 obj 객체의 value 속성을 가로채고, count 속성을 읽을 때 get 함수를 실행하고, count 속성을 수정할 때 set 함수를 실행하고, set 함수 내에서 double을 다시 계산합니다. 이런 식으로 우리는 간단한 반응형 기능을 구현했습니다. 과정의 네 번째 부분에서는 더욱 완전한 반응형 시스템을 작성하도록 안내하겠습니다

하지만 DefineProperty API는 Vue 2처럼 반응성의 원칙을 구현합니다. 예를 들어 다음 코드에서 obj.count 속성을 삭제하면 set 함수가 실행되지 않고 double은 여전히 ​​이전 값이 됩니다. 이것이 Vue 2에서 필요한 이유입니다. 데이터를 삭제하는 특수 기능

let getDouble = n=>n*2
let obj = {}
let count = 1
let double = getDouble(count)
Object.defineProperty(obj,'count',{
    get(){
        return count
    },
    set(val){
        count = val
        double = getDouble(val)
    }
})
console.log(double) // 打印2
obj.count = 2
console.log(double) // 打印4 有种自动变化的感觉
로그인 후 복사
Vue 3의 반응 메커니즘은 Proxy라는 이름에 관한 한 프록시를 의미한다는 것도 알 수 있습니다. Proxy의 중요한 의미는 Vue 2의 단점을 해결한다는 것입니다. 반응성

아래 코드를 보면 새 프록시를 통해 객체 obj를 프록시한 다음 get, set 및 deleteProperty 함수를 통해 객체의 읽기, 수정 및 삭제 작업을 프록시하여 반응형 기능을 실현하는 코드가 있습니다

delete obj.count
console.log(double) // doube还是4
로그인 후 복사
$delete여기서부터 시작하겠습니다. Proxy에서 구현한 함수는 Vue 2의 정의 프로퍼리(definePropery)와 유사하다는 것을 알 수 있습니다. 사용자가 데이터를 수정할 때 set 함수를 트리거하여 double을 자동으로 업데이트하는 기능을 실현할 수 있습니다. 또한 Proxy는 DefinePropery의 여러 가지 결함을 개선했습니다. 예를 들어 특정 속성이 아닌 개체의 삭제를 모니터링할 수 있으므로 정의할 때 존재하지 않는 프록시 속성뿐만 아니라 더 풍부한 프록시도 사용할 수 있습니다. Map, Set 등과 같은 데이터 구조를 구현하고 deleteProperty를 통해 삭제 작업 프록시를 구현할 수도 있습니다

물론 Proxy에 대한 이해를 돕기 위해 set 및 deleteProperty 함수에 이중 관련 코드를 작성할 수도 있습니다. 과정의 후반부에서는 보다 완전한 캡슐화를 수행하도록 안내하겠습니다. 예를 들어 다음 코드에서 Vue 3의 반응성 기능은 객체를 반응형 데이터로 변환할 수 있으며 반응성은 프록시를 기반으로 구현됩니다. obj.count를 수정한 후 watchEffect를 사용하여 데이터를 인쇄할 수도 있습니다

import {reactive,computed,watchEffect} from 'vue'
let obj = reactive({
    count:1
})
let double = computed(()=>obj.count*2)
obj.count = 2
watchEffect(()=>{
    console.log('数据被修改了',obj.count,double.value)
})
로그인 후 복사

有了 Proxy 后,响应式机制就比较完备了;但是在 Vue 3 中还有另一个响应式实现的逻辑,就是利用对象的 get 和 set 函数来进行监听,这种响应式的实现方式,只能拦截某一个属性的修改,这也是 Vue 3 中 ref 这个 API 的实现

在下面的代码中,我们拦截了 count 的 value 属性,并且拦截了 set 操作,也能实现类似的功能

let getDouble = n => n * 2
let _value = 1

double = getDouble(_value)
let count = {
    get value() {
        return _value
    },
    set value(val) {
        _value = val
        double = getDouble(_value)
    }
}

console.log(count.value,double)
count.value = 2
console.log(count.value,double)
로그인 후 복사

三种实现原理的对比表格如下,帮助你理解三种响应式的区别

实现原理 defineProperty Proxy value setter
实际场景 Vue 2 响应式 Vue 3 reactive Vue 3 ref
优势 兼容性 基于proxy实现真正的拦截 实现简单
劣势 数组和属性删除等拦截不了 兼容不了 IE11 只拦截了 value 属性
实际应用 Vue 2 Vue 3 复杂数据结构 Vue 3 简单数据结构

定制响应式数据

简单入门响应式的原理后,接下来我们学习一下响应式数据在使用的时候的进阶方式;我们看下使用 <script setup></script> 重构之后的 todolist 的代码;这段代码使用 watchEffect,数据变化之后会把数据同步到 localStorage 之上,这样我们就实现了 todolist 和本地存储的同步

import { ref, watchEffect, computed } from "vue";
let title = ref("");
let todos = ref(JSON.parse(localStorage.getItem('todos')||'[]'));
watchEffect(()=>{
    localStorage.setItem('todos',JSON.stringify(todos.value))
})
function addTodo() {
    todos.value.push({
        title: title.value,
        done: false,
    });
    title.value = "";
}
로그인 후 복사

更进一步,我们可以直接抽离一个 useStorage 函数,在响应式的基础之上,把任意数据响应式的变化同步到本地存储;我们先看下面的这段代码,ref 从本地存储中获取数据,封装成响应式并且返回,watchEffect 中做本地存储的同步,useStorage 这个函数可以抽离成一个文件,放在工具函数文件夹中

function useStorage(name, value=[]){
    let data = ref(JSON.parse(localStorage.getItem(name)||'[]'))
    watchEffect(()=>{
        localStorage.setItem(name,JSON.stringify(data.value))
    })
    return data
}
로그인 후 복사

在项目中我们使用下面代码的写法,把 ref 变成 useStorage,这也是 Composition API 最大的优点,也就是可以任意拆分出独立的功能

let todos = useStorage('todos',[])
function addTodo() {
    ...code
}
로그인 후 복사

现在,你应该已经学会了在 Vue 内部进阶地使用响应式机制,去封装独立的函数;在后续的实战应用中,我们也会经常对通用功能进行封装;如下图所示,我们可以把日常开发中用到的数据,无论是浏览器的本地存储,还是网络数据,都封装成响应式数据,统一使用响应式数据开发的模式;这样,我们开发项目的时候,只需要修改对应的数据就可以了

Vue3의 반응 메커니즘에 대한 심층 분석을 제공하는 기사

基于响应式的开发模式,我们还可以按照类似的原理,把我们需要修改的数据,都变成响应式;比如,我们可以在 loading 状态下,去修改浏览器的小图标 favicon;和本地存储类似,修改 favicon 时,我们需要找到 head 中有 icon 属性的标签

在下面的代码中,我们把对图标的对应修改的操作封装成了 useFavicon 函数,并且通过 ref 和 watch 的包裹,我们还把小图标变成了响应式数据

import {ref,watch} from 'vue'
export default function useFavicon( newIcon ) {
    const favicon = ref(newIcon)
    const updateIcon = (icon) => {
        document.head
        .querySelectorAll(`link[rel*="icon"]`)
        .forEach(el => el.href = `${icon}`)
    }
watch( favicon,
    (i) => {
        updateIcon(i)
    }
)
    return {favicon,reset}
}
로그인 후 복사

这样在组件中,我们就可以通过响应式的方式去修改和使用小图标,通过对 faivcon.value 的修改就可以随时更换网站小图标;下面的代码,就实现了在点击按钮之后,修改了网页的图标为 geek.png 的操作

<script>
    import useFavicon from &#39;./utils/favicon&#39;
    let {favicon} = useFavicon()
    function loading(){
        favicon.value = &#39;/geek.png&#39;
    }
</script>
<template>
    <button>123</button>
</template>
로그인 후 복사

Vueuse 工具包

我们自己封装的 useStorage,算是把 localStorage 简单地变成了响应式对象,实现数据的更新和localStorage 的同步;同理,我们还可以封装更多的类似 useStorage 函数的其他 use 类型的函数,把实际开发中你用到的任何数据或者浏览器属性,都封装成响应式数据,这样就可以极大地提高我们的开发效率

Vue 社区中其实已经有一个类似的工具集合,也就是 VueUse,它把开发中常见的属性都封装成为响应式函数

VueUse 趁着这一波 Vue 3 的更新,跟上了响应式 API 的潮流;VueUse 的官方的介绍说这是一个 Composition API 的工具集合,适用于 Vue 2.x 或者 Vue 3.x,用起来和 React Hooks 还挺像的

在项目目录下打开命令行里,我们输入如下命令,来进行 VueUse 插件的安装:

npm install @vueuse/core
로그인 후 복사

然后,我们就先来使用一下 VueUse;在下面这段代码中,我们使用 useFullscreen 来返回全屏的状态和切换全屏的函数;这样,我们就不需要考虑浏览器全屏的 API,而是直接使用 VueUse 响应式数据和函数就可以很轻松地在项目中实现全屏功能

<template>
    <h1 id="click">click</h1>
</template>
<script>
import { useFullscreen } from &#39;@vueuse/core&#39;
const { isFullscreen, enter, exit, toggle } = useFullscreen()
</script>
로그인 후 복사

useFullscreen 的封装逻辑和 useStorage 类似,都是屏蔽了浏览器的操作,把所有我们需要用到的状态和数据都用响应式的方式统一管理,VueUse 中包含了很多我们常用的工具函数,我们可以把网络状态、异步请求的数据、动画和事件等功能,都看成是响应式的数据去管理

(学习视频分享:web前端开发编程基础视频

위 내용은 Vue3의 반응 메커니즘에 대한 심층 분석을 제공하는 기사의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

vue.js로 JS 파일을 참조하는 방법 vue.js로 JS 파일을 참조하는 방법 Apr 07, 2025 pm 11:27 PM

vue.js에서 JS 파일을 참조하는 세 가지 방법이 있습니다. & lt; script & gt; 꼬리표;; mounted () 라이프 사이클 후크를 사용한 동적 가져 오기; Vuex State Management Library를 통해 수입.

Vue에서 시계를 사용하는 방법 Vue에서 시계를 사용하는 방법 Apr 07, 2025 pm 11:36 PM

vue.js의 시계 옵션을 사용하면 개발자가 특정 데이터의 변경 사항을들을 수 있습니다. 데이터가 변경되면 콜백 기능을 트리거하여 업데이트보기 또는 기타 작업을 수행합니다. 구성 옵션에는 즉시 콜백을 실행할지 여부와 DEEP를 지정하는 즉시 포함되며, 이는 객체 또는 어레이에 대한 변경 사항을 재귀 적으로 듣는 지 여부를 지정합니다.

Vue에서 부트 스트랩을 사용하는 방법 Vue에서 부트 스트랩을 사용하는 방법 Apr 07, 2025 pm 11:33 PM

vue.js에서 bootstrap 사용은 5 단계로 나뉩니다 : Bootstrap 설치. main.js.의 부트 스트랩 가져 오기 부트 스트랩 구성 요소를 템플릿에서 직접 사용하십시오. 선택 사항 : 사용자 정의 스타일. 선택 사항 : 플러그인을 사용하십시오.

게으른 부하 vue의 의미는 무엇입니까? 게으른 부하 vue의 의미는 무엇입니까? Apr 07, 2025 pm 11:54 PM

vue.js에서 게으른 로딩을 사용하면 필요에 따라 부품 또는 리소스를 동적으로로드 할 수 있으므로 초기 페이지로드 시간을 줄이고 성능을 향상시킵니다. 특정 구현 방법에는 & lt; keep-alive & gt를 사용하는 것이 포함됩니다. & lt; 구성 요소는 & gt; 구성 요소. 게으른 하중은 FOUC (Splash Screen) 문제를 일으킬 수 있으며 불필요한 성능 오버 헤드를 피하기 위해 게으른 하중이 필요한 구성 요소에만 사용해야합니다.

Vue 용 버튼에 기능을 추가하는 방법 Vue 용 버튼에 기능을 추가하는 방법 Apr 08, 2025 am 08:51 AM

HTML 템플릿의 버튼을 메소드에 바인딩하여 VUE 버튼에 함수를 추가 할 수 있습니다. 메소드를 정의하고 VUE 인스턴스에서 기능 로직을 작성하십시오.

Vue는 천막/텍스트 스크롤 효과를 인식합니다 Vue는 천막/텍스트 스크롤 효과를 인식합니다 Apr 07, 2025 pm 10:51 PM

CSS 애니메이션 또는 타사 라이브러리를 사용하여 VUE에서 Marquee/Text Scrolling Effects를 구현하십시오. 이 기사는 CSS 애니메이션 사용 방법을 소개합니다. & lt; div & gt; CSS 애니메이션을 정의하고 오버플로를 설정하십시오 : 숨겨진, 너비 및 애니메이션. 키 프레임을 정의하고 변환을 설정하십시오 : Translatex () 애니메이션의 시작과 끝에서. 지속 시간, 스크롤 속도 및 방향과 같은 애니메이션 속성을 조정하십시오.

VUE 버전을 쿼리하는 방법 VUE 버전을 쿼리하는 방법 Apr 07, 2025 pm 11:24 PM

Vue DevTools를 사용하여 브라우저 콘솔에서 vue 탭을 보면 VUE 버전을 쿼리 할 수 ​​있습니다. npm을 사용하여 "npm list -g vue"명령을 실행하십시오. package.json 파일의 "종속성"객체에서 vue 항목을 찾으십시오. Vue Cli 프로젝트의 경우 "vue -version"명령을 실행하십시오. & lt; script & gt에서 버전 정보를 확인하십시오. vue 파일을 나타내는 html 파일의 태그.

Vue가 이전 페이지로 돌아 오는 방법 Vue가 이전 페이지로 돌아 오는 방법 Apr 07, 2025 pm 11:30 PM

vue.js는 이전 페이지로 돌아갈 수있는 네 가지 방법이 있습니다. $ router.go (-1) $ router.back () 사용 & lt; router-link to = & quot;/quot; Component Window.history.back () 및 메소드 선택은 장면에 따라 다릅니다.

See all articles