vue 탐지 데이터 의 변화 에 대한 기본 적 인 실현
데이터 변 화 를 탐지 하 는 논 리 를 모 의 해 보 겠 습 니 다.
우리 가 해 야 할 일 을 강조 하 자.데이터 변 화 는 외부 에 알 리 고(외부 에서 자신의 논리 적 처 리 를 다시 하 는 것,예 를 들 어 보 기 를 다시 과장 하 는 것).
인 코딩 을 시작 하기 전에 우 리 는 먼저 다음 과 같은 몇 가지 질문 에 대답 해 야 한다.
1.대상 의 변 화 를 어떻게 조사 합 니까?
2.데이터 가 변 할 때 우 리 는 누구 에 게 통지 합 니까?
5.언제 수집 의존?
6.어디로 모 을 까?
인 코딩 은 다음 과 같 습 니 다(직접 실행 가능).
// ,
let globalData = undefined;
//
function defineReactive (obj,key,val) {
//
let dependList = []
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function () {
// (Watcher)
globalData && dependList.push(globalData)
return val
},
set: function reactiveSetter (newVal) {
if(val === newVal){
return
}
// (Watcher)
dependList.forEach(w => {
w.update(newVal, val)
})
val = newVal
}
});
}
//
class Watcher{
constructor(data, key, callback){
this.data = data;
this.key = key;
this.callback = callback;
this.val = this.get();
}
//
get(){
// globalData
globalData = this;
//
let value = this.data[this.key]
globalData = undefined
return value;
}
// ,
update(newVal, oldVal){
this.callback(newVal, oldVal)
}
}
/* */
let data = {};
// name
defineReactive(data, 'age', '88')
// age , Watcher, Watcher
new Watcher(data, 'age', (newVal, oldVal) => {
console.log(` :newVal = ${newVal} ; oldVal = ${oldVal}`)
})
data.age -= 1 // : :newVal = 87 ; oldVal = 88
콘 솔 에서 data.age -= 1
을 계속 실행 하면 :newVal = 86 ; oldVal = 87
을 출력 합 니 다.Data,defineReactive,dependelist,Watcher 와 외부의 관계 도 를 첨부 합 니 다.
우선 defineReactive()방법 을 통 해 data 를 응답 식(
defineReactive(data, 'age', '88')
)으로 전환 합 니 다.외부 에 서 는 Watcher 를 통 해 데이터(
let value = this.data[this.key]
)를 읽 고 데이터 의 getter 는 트리거 되 기 때문에 globalData 를 통 해 Watcher 를 수집 합 니 다.데이터 가 수정(
data.age -= 1
)되면 setter 를 터치 하고 의존(dependelist)을 알 리 며 의존 은 Watcher(w.update(newVal, val)
)에 알 리 고 마지막 으로 Watcher 는 외부 에 알 립 니 다.질문
생각해 보 세 요:위의 예 를 들 어
delete data.age
을 계속 집행 하면 외부 에 알 릴 수 있 습 니까?아니요.setter 를 터치 하지 않 기 때 문 입 니 다.이어서 보 세 요.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id='app'>
<section>
{{ p1.name }}
{{ p1.age }}
</section>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
p1: {
name: 'ph',
age: 18
}
}
})
</script>
</body>
</html>
실행 하면 페이지 에 ph 18
이 표 시 됩 니 다.데 이 터 를 변경 하면 보기 가 다시 렌 더 링 된다 는 것 을 알 고 콘 솔 에서 delete app.p1.name
을 실행 하 였 으 며 페이지 에 변화 가 없 음 을 발견 하 였 습 니 다.이 는 위의 예제 에서 delete data.age
을 실행 하 는 것 과 마찬가지 로 setter 를 촉발 하지 않 고 외부 에 알 리 지 않 는 다.이 문 제 를 해결 하기 위해 Vue 는 두 개의 API 를 제공 합 니 다.vm.$set 와 vm.$delete 입 니 다.
app.$delete(app.p1, 'age')
을 계속 실행 하면 페이지 에 아무런 정보 가 없 음 을 발견 할 수 있 습 니 다.주:여기 서
app.p1.sex = 'man'
을 실행 하면 데이터 p1 을 사용 하 는 곳 도 알려 지지 않 습 니 다.이 문 제 는 vm.$set 를 통 해 해결 할 수 있 습 니 다.3.Array 의 변화 조사
3.1 배경
만약 에 데이터 가
let data = {a:1, b:[11, 22]}
이 라면 Object.defineProperty 를 통 해 응답 식 으로 전환 한 후에 우 리 는 데 이 터 를 data.a = 2
으로 수정 하면 외부 에 알 릴 것 입 니 다.이것 은 이해 하기 쉽 습 니 다.마찬가지 로 data.b = [11, 22, 33]
도 외부 에 알 리 지만 다른 방식 으로 데이터 b 를 수정 하면 이렇게 data.b.push(33)
은 외부 에 알 리 지 않 을 것 이다.setter 를 가지 않 았 기 때문이다.예 시 를 보십시오.
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function () {
console.log(`get val = ${val}`)
return val
},
set: function reactiveSetter (newVal) {
if(val === newVal){
return
}
console.log(`set val = ${newVal}; oldVal = ${val}`)
val = newVal
}
});
}
// {1}
let data = {}
defineReactive(data, 'a', [11,22])
data.a.push(33) // get val = 11,22 ( setter) {2}
data.a // get val = 11,22,33
data.a = 1 // set val = 1; oldVal = 11,22,33( setter)
push()방법 을 통 해 배열 의 값 을 변경 합 니 다.setter(행{2})를 실행 하지 않 았 거나 외부 에 알 릴 수 없습니다.Object.definePropery()방법 을 통 해 대상 을 응답 식 으로 만 바 꿀 수 있 고 배열 을 응답 식 으로 바 꿀 수 없습니다.사실 Object.define Propery()는 배열 을 응답 식 으로 바 꿀 수 있 습 니 다.예 시 를 보십시오.
// , ( {1}) :
let data = []
defineReactive(data, '0', 11)
data[0] = 22 // set val = 22; oldVal = 11
data.push(33) // {10}
Object.definePropery()는 배열 을 응답 식 으로 바 꿀 수 있 지만 data.push(33)
(행{10})이라는 방식 으로 배열 을 수정 하여 외부 에 알 리 지 않 습 니 다.그래서 Vue 에서 데 이 터 를 응답 식 으로 바 꾸 고 두 가지 방식 을 사 용 했 습 니 다.대상 은 Object.defineProperty()를 사용 합 니 다.배열 은 다른 세트 를 사용한다.
3.2 실현
es6 에 서 는 프 록 시 로 배열 의 변 화 를 탐지 할 수 있다.예 시 를 보십시오.
let data = [11,22]
let p = new Proxy(data, {
set: function(target, prop, value, receiver) {
target[prop] = value;
console.log('property set: ' + prop + ' = ' + value);
return true;
}
})
console.log(p)
p.push(33)
/*
:
[ 11, 22 ]
property set: 2 = 33
property set: length = 3
*/
es6 예전 부터 좀 귀 찮 았 어 요.차단 기 를 사용 할 수 있어 요.원 리 는 [].push()
을 실행 할 때 배열 원형(Array.prototype)중의 방법 을 호출 하 는 것 이다.[].push()
과 Array.prototype
사이 에 차단 기 를 추가 하고 [].push()
을 호출 할 때 차단기 의 push()방법 을 먼저 실행 합 니 다.차단기 의 push()는 Array.prototype 의 push()방법 을 호출 합 니 다.예 시 를 보십시오.
//
let arrayPrototype = Array.prototype
//
let interceptor = Object.create(arrayPrototype)
//
;('push,pop,unshift,shift,splice,sort,reverse').split(',')
.forEach(method => {
let origin = arrayPrototype[method];
Object.defineProperty(interceptor, method, {
value: function(...args){
console.log(` : args = ${args}`)
return origin.apply(this, args);
},
enumerable: false,
writable: true,
configurable: true
})
});
//
let arr1 = ['a']
let arr2 = [10]
arr1.push('b')
// arr2
Object.setPrototypeOf(arr2, interceptor) // {20}
arr2.push(11) // : args = 11
arr2.unshift(22) // : args = 22
이 예 는 배열 자체 의 내용 을 바 꿀 수 있 는 7 가지 방법 을 모두 차단기 에 넣 었 다.어떤 배열 의 변 화 를 조사 하려 면 이 배열 의 원형 을 차단기(행{20})로 가리 키 십시오.push 등 7 가지 방법 으로 이 배열 을 수정 하면 차단기 에서 작 동 되 어 외부 에 알 릴 수 있 습 니 다.여기까지 우 리 는 배열 의 변 화 를 조사 하 는 임무 만 완수 했다.
데이터 변 화 를 외부 에 알리다.위의 인 코딩 의 실현 은 Object 데이터 만 을 위 한 것 이 고,여 기 는 Array 데이터 가 필요 합 니 다.
우리 도 같은 문 제 를 생각해 보 자.
1.배열 의 변 화 를 어떻게 조사 합 니까?
{a: [11,22]}
예 를 들 어 우리 가 a 배열 을 사용 하려 면 반드시 방문 대상 의 속성 a 를 사용 해 야 한다.여기까지 입 니 다.더 이상 펼 치지 않 겠 습 니 다.다음 글 에서 저 는 vue 에서 데이터 수사 와 관련 된 소스 코드 를 떼 어 내 고 본 고 와 결합 하여 간단하게 분석 하 겠 습 니 다.
질문
// vue.js。
<div id='app'>
<section>
{{ p1[0] }}
{{ p1[1] }}
</section>
</div>
<script>
const app = new Vue({
el: '#app',
data: {
p1: ['ph', '18']
}
})
</script>
실행 후 페이지 에 ph 18
을 표시 합 니 다.콘 솔 에서 app.p1[0] = 'lj'
페이지 를 실행 하면 반응 이 없습니다.배열 은 지정 한 7 가지 방법 을 호출 해 야 차단 기 를 통 해 외부 에 알 릴 수 있 기 때 문 입 니 다.app.$set(app.p1, 0, 'pm')
페이지 를 실행 하면 pm 18
페이지 가 됩 니 다.이상 은 vue 수사 데이터 의 변화 에 대한 기본 적 인 실현 에 대한 상세 한 내용 입 니 다.vue 수사 데이터 의 변화 에 관 한 자 료 는 우리 의 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Fastapi websocket 및 vue 3(Composition API)1부: FastAPI virtualenv 만들기(선택 사항) FastAPI 및 필요한 모든 것을 다음과 같이 설치하십시오. 생성main.py 파일 및 실행 - 브라우저에서 이 링크 열기http://127.0.0.1:...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.