Vue 3의 반응성 탐색: ref 및 watchEffect
14502 단어 programmingwebdevvuejavascript
그리고 시리즈의 두 번째 첫 번째 부분에서는 Vue 3의 반응성이
ref
및 watchEffect
와 어떻게 작동하는지 살펴보겠습니다.Vue 3의 반응성
이 문서의 범위 내에서 지금은
ref
및 watchEffect
만 살펴보겠습니다. 다른 반응성 함수는 시리즈의 다음 부분에서 살펴볼 것입니다.우리는 여기에서 반응성에 대해 많이 이야기하고 있습니다. 그렇다면 실제로 반응성은 무엇입니까? 사실 새로운 패러다임은 아닙니다. 일반적인 예는 Excel 스프레드시트입니다.
위의 예에서 B1 셀은
= A1 + A2
로 정의됩니다. A1 또는 A2를 업데이트하면 B1도 사후 업데이트됩니다.그러나 JavaScript에서는 변수가 그런 식으로 작동하지 않습니다.
let A1 = 1
let A2 = 4
let B1 = A1 + A2
console.log(B1) // 5
A1 = 3
console.log(B1) // still 5
우리의 목적이 A1 또는 A2가 변경될 때 A1과 A2의 합계를 기록하는 것이라면 Vue 3에서 다음과 같이 작성할 수 있습니다.
const A1 = ref(1)
const A2 = ref(4)
watchEffect(() => {
console.log('B1 =', A1.value + A2.value)
})
하지만 어떻게 작동합니까?
watchEffect
는 A1 또는 A2가 언제 변경되는지 어떻게 알 수 있습니까? 이 질문에 답하기 위해 처음부터 ref
를 빌드해 보겠습니다. getter 및 setter가 있는 속성이 1개value
인 개체로 시작합니다.export function ref(value) {
return new RefImpl(value)
}
class RefImpl {
private _value
constructor(value) {
this._value = value
}
get value() {
return this._value
}
set value(newVal) {
this._value = newVal
}
}
아직 아무 일도 일어나지 않습니다. 여기서 사용할 마술은
value
개체의 ref
속성을 읽을 때(getter 메서드 호출) 자동으로 호출자를 ref
개체의 구독자로 추가하는 것입니다. 또한 이 구독자를 효과(부작용의 줄임말)라고 합니다. ref
개체는 이제 효과의 종속성이 됩니다.export function ref(value) {
return new RefImpl(value)
}
class RefImpl {
private _value
public dep = undefined // Ironically, in the Vue's codebase, the subscribers/effects of a ref object seem to also be called its dependencies.
constructor(value) {
this._value = value
}
get value() {
trackRefValue(this)
return this._value
}
set value(newVal) {
this._value = newVal;
}
}
export function trackRefValue(ref) {
if (!activeEffect) return;
if (!ref.dep) ref.dep = new Set() // We must use Set here to avoid duplication
ref.dep.add(activeEffect) // Add the active (currently running) effect as one of the ref object's subscribers
}
이제 2가지 문제가 남았습니다.
activeEffect
의 값은 어디에서 왔습니까? 즉, 현재 어떤 효과가 실행되고 있는지 어떻게 알 수 있습니까? ref
속성이 변경될 때 모든 value
개체의 구독자/종속성을 트리거/알려야 합니다. 두 번째 문제는 매우 간단하기 때문에 먼저 다루겠습니다.
export function ref(value) {
return new RefImpl(value)
}
class RefImpl {
private _value
public dep = undefined // Ironically, in the Vue's codebase, the subscribers/effects of a ref object seem to also be called its dependencies.
constructor(value) {
this._value = value
}
get value() {
trackRefValue(this)
return this._value
}
set value(newVal) {
this._value = newVal
triggerRefValue(this)
}
}
export function trackRefValue(ref) {
if (!activeEffect) return;
if (!ref.dep) ref.dep = new Set() // We must use Set here to avoid duplication
ref.dep.add(activeEffect) // Add the active (currently running) effect as one of the ref object's subscribers
}
export function triggerRefValue(ref) {
if (!ref.dep) return;
for (const effect of ref.dep) {
effect() // run the effect
}
}
이제 남은 가장 중요한 질문은
activeEffect
의 값은 어디에서 오는가? watchEffect
의 원시 구현을 살펴보겠습니다.export let activeEffect = undefined
export function watchEffect(effectHandler) {
const effect = () => {
activeEffect = effect
effectHandler()
// The above function call will read the value property of any ref object inside it
// and trigger the getter method of the value property,
// which in turn adds this effect as one of the subscribers of that ref object.
activeEffect = undefined
}
effect() // watchEffect triggers the effect (handler) immediately
}
watchEffect
는 항상 즉시 실행되기 때문에 처음 실행될 때 항상 내부에 있는 value
개체의 ref
속성의 getter 메서드를 트리거하고 효과를 이러한 ref
개체의 구독자로 등록합니다. 이것이 watchEffect
에 대한 종속성을 명시적으로 지정할 필요가 없는 이유입니다.다음은
ref
및 watchEffect
의 작업 코드 예제입니다.지금은
ref
및 watchEffect
의 대략적인 작동 버전이 있습니다. 실패할 수 있는 경우를 너무 많이 생략하고 일괄 처리가 없으며 여기에서 제어 흐름이 약간 엉망이기 때문에 거의 사용할 수 없습니다. 그러나 바라건대 뒤에서 무슨 일이 일어나고 있는지에 대한 지나치게 단순화된 예로서 그 목적에 부합합니다.결론
시리즈의 이 부분에서는 Vue 3의
ref
및 watchEffect
의 요지를 활용했습니다. 다음 부분에서는 ref
및 watchEffect
의 지나치게 단순화된 버전을 계속 개선하여 실제 구현과 더 가깝게 일치하도록 하고 reactive
, computed
및 watch
에 대해서도 살펴보겠습니다.어떻게든 유용하게 사용하시길 바랍니다. 제안이나 조언이 있으시면 주저하지 말고 의견 섹션에서 저에게 연락하십시오.
Reference
이 문제에 관하여(Vue 3의 반응성 탐색: ref 및 watchEffect), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/huytaquoc/exploring-frontend-frameworks-internals-part-2-vue-3s-reactivity-2482텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)