Vue 데이터 가 업데이트 되 었 으 나 페이지 가 업데이트 되 지 않 은 7 가지 상황 집계 및 연장 요약
1.Vue 에서 인 스 턴 스 가 생 성 되 었 을 때 data 에 존재 하지 않 는 property 를 검사 할 수 없습니다.
원인:Vue 는 인 스 턴 스 를 초기 화 할 때 property 실행
getter/setter
으로 전환 되 기 때문에 property 는data
대상 에 존재 해 야 Vue 가 응답 식 으로 전환 할 수 있 습 니 다.필드:
var vm = new Vue({
data:{},
//
template: '<div>{{message}}</div>'
})
vm.message = 'Hello!' // `vm.message`
해결 방법:
var vm = new Vue({
data: {
// a、b
message: '',
},
template: '<div>{{ message }}</div>'
})
vm.message = 'Hello!'
2.Vue 에서 대상 property 의 추가 또는 제거 가 불가능 함이유:공식-JavaScript(ES5)의 제한 으로 Vue.js 는 대상 속성의 추가 또는 삭 제 를 감지 할 수 없습니다.Vue.js 는 인 스 턴 스 를 초기 화 할 때 속성 을 getter/setter 로 바 꾸 기 때문에 속성 은
data
대상 에서 만 Vue.js 를 변환 시 켜 야 응답 할 수 있 습 니 다.필드:
var vm = new Vue({
data:{
obj: {
id: 001
}
},
//
template: '<div>{{ obj.message }}</div>'
})
vm.obj.message = 'hello' //
delete vm.obj.id //
해결 방법:
// - Vue.set
Vue.set(vm.obj, propertyName, newValue)
// - vm.$set
vm.$set(vm.obj, propertyName, newValue)
//
// Object.assign(this.obj, { a: 1, b: 2 })
this.obj = Object.assign({}, this.obj, { a: 1, b: 2 })
// - Vue.delete
Vue.delete(vm.obj, propertyName)
// - vm.$delete
vm.$delete(vm.obj, propertyName)
3.Vue 는 배열 색인 을 통 해 배열 항목 을 직접 수정 하 는 것 을 감지 할 수 없습니다.원인:공식-JavaScript 의 제한 으로 인해 Vue 는 배열 과 대상 의 변 화 를 감지 할 수 없습니다.유 우 계-성능 대가 와 사용자 체험 획득 은 정비례 하지 않 는 다.
필드:
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' //
해결 방법:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// vm.$set
vm.$set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
확장:Object.defineProperty()는 배열 의 변 화 를 모니터링 할 수 있 습 니 다.Object.defineProperty()는 배열 의 변 화 를 모니터링 할 수 있다.그러나 배열 에 속성(index)을 추가 하면 데이터 변 화 를 감지 하지 못 합 니 다.새로 추 가 된 배열 의 아래 표 시 를 감지 할 수 없 기 때문에 속성(index)을 삭제 하 는 것 도 마찬가지 입 니 다.
필드:
var arr = [1, 2, 3, 4]
arr.forEach(function(item, index) {
Object.defineProperty(arr, index, {
set: function(value) {
console.log(' setter')
item = value
},
get: function() {
console.log(' getter')
return item
}
})
})
arr[1] = '123' // setter
arr[1] // getter "123"
arr[5] = 5 // setter getter
4.Vue 는 배열 의 길 이 를 직접 수정 하 는 변 화 를 모니터링 할 수 없습니다.원인:공식-JavaScript 의 제한 으로 인해 Vue 는 배열 과 대상 의 변 화 를 감지 할 수 없습니다.유 우 계-성능 대가 와 사용자 체험 획득 은 정비례 하지 않 는 다.
필드:
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items.length = 2 //
해결 방법:
vm.items.splice(newLength)
5.비동기 업데이트 가 실행 되 기 전에 DOM 데 이 터 를 조작 하 는 것 은 변 하지 않 습 니 다.이유:Vue 는 DOM 을 업데이트 할 때 비동기 로 실 행 됩 니 다.데이터 변 화 를 감지 하면 Vue 는 같은 이벤트 순환 에서 발생 하 는 모든 데이터 변경 을 버퍼 링 합 니 다.같은 watcher 가 여러 번 트리거 되면 대기 열 에 한 번 만 추 가 됩 니 다.버퍼 링 을 할 때 중복 데 이 터 를 제거 하 는 것 은 불필요 한 계산 과 DOM 작업 을 피 하 는 데 매우 중요 하 다.그리고 다음 이벤트 순환"tick"에서 Vue 가 대기 열 을 새로 고치 고 실제(무 거 운 것)작업 을 수행 합 니 다.Vue 는 내부 에서 비동기 대기 열 에 대해 원생
Promise.then
,MutationObserver
,setImmediate
을 사용 하려 고 시도 하고 실행 환경 이 지원 되 지 않 으 면setTimeout(fn, 0)
으로 대체 합 니 다.필드:
<div id="example">{{message}}</div>
var vm = new Vue({
el: '#example',
data: {
message: '123'
}
})
vm.message = 'new message' //
vm.$el.textContent === 'new message' // false
vm.$el.style.color = 'red' //
해결 방법:
var vm = new Vue({
el: '#example',
data: {
message: '123'
}
})
vm.message = 'new message' //
// Vue.nextTick(callback) callback DOM
Vue.nextTick(function () {
vm.$el.textContent === 'new message' // true
vm.$el.style.color = 'red' //
})
확장:비동기 업데이트 로 인 한 데이터 응답 에 대한 오해
<!-- : ! -->
<div id="example">{{message.text}}</div>
var vm = new Vue({
el: '#example',
data: {
message: {},
}
})
vm.$nextTick(function () {
this.message = {}
this.message.text = ' !'
})
상단 코드 에서 우 리 는data
대상 에서 빈 대상message
을 설명 한 다음 에 다음 DOM 업데이트 순환 이 끝 난 후에 발생 하 는 비동기 반전 에서 다음 과 같은 두 단계 코드 를 실 행 했 습 니 다.
this.message = {};
this.message.text = ' !'
여기까지 모드 가 업데이트 되면 페이지 가 마지막 으로 표 시 됩 니 다 !
.템 플 릿 이 업데이트 되 었 습 니 다.응답 식 특성 이 있어 야 합 니 다.그렇게 생각한다 면 잘못된 곳 으로 들 어 갔 을 것 입 니 다.
처음에 우 리 는
data
대상 에서 하나의message
빈 대상 만 밝 혔 을 뿐text
속성 을 가지 지 않 았 기 때문에 이text
속성 은 응답 식 특성 을 가지 지 않 았 다.그러나 템 플 릿 은 확실히 업데이트 되 었 는데,이것 은 또 어떻게 된 일 입 니까?
그것 은 Vue.js 의 DOM 업데이트 가 비동기 적 이기 때 문 입 니 다.즉,
setter
작업 이 발생 한 후에 명령 이 바로 업데이트 되 지 않 고 명령 의 업데이트 작업 이 지연 되 기 때 문 입 니 다.명령 이 진정 으로 실 행 될 때 이때text
속성 이 할당 되 었 기 때문에 명령 이 모델 을 업데이트 할 때 새로운 값 을 얻 을 수 있 습 니 다.템 플 릿 에 있 는 모든 명령/데이터 바 인 딩 은 해당 하 는 watcher 대상 이 있 고 계산 과정 에서 속성 을 의존 으로 기록 합 니 다.이후 의존 하 는 setter 가 호출 될 때 watcher 재 계산 을 촉발 하고 관련 명령 이 DOM 을 업데이트 할 수 있 습 니 다.
구체 적 인 절 차 는 다음 과 같다.
this.message = {};
라 는 문장 으로 인해 발생 한 것 입 니 다.트리거setter
가 발생 했 기 때문에 상기 예 를 보면 응답 식 특성 을 가 진 데 이 터 는message
층 만 있 고 그의 동적 추가 속성 은 갖 추 지 않 습 니 다.위 두 번 째 점-Vue 에 대응 하여 대상 property 의 추가 또는 제거 가 불가능 합 니 다.
6.순환 플러그 인 이 너무 깊 어서 보기 가 업데이트 되 지 않 습 니까?
인터넷 에서 어떤 사람들 은 데이터 업데이트 의 등급 이 너무 깊 어서 데이터 가 업데이트 되 지 않 거나 업데이트 가 느 려 서 업데이트 하지 않 으 려 고 한다 고 말한다.
저 는 이런 상황 을 만난 적 이 없 기 때문에 이런 장면 을 재현 하려 고 하 는 상황 에서 상기 상황 이 발생 하지 않 았 다 는 것 을 알 게 되 었 습 니 다.그래서 이 점 에 대해 너무 많은 묘 사 를 하지 않 았 습 니 다.
상기 상황 에 대한 해결 방안 은 강제 업 데 이 트 를 사용 하 는 것 이다.
Vue 에서 강제 업 데 이 트 를 해 야 한 다 는 것 을 알 게 된다 면 99.9%는 어 딘 가 에서 잘못 한 것 이다.
vm.$forceUpdate()
7.확장:루트 매개 변수 가 변 할 때 페이지 가 업데이트 되 지 않 음(데이터 가 업데이트 되 지 않 음)경로 의 매개 변수 변화 로 인해 페이지 가 업데이트 되 지 않 는 문 제 를 확대 하고 페이지 가 업데이트 되 지 않 는 것 은 본질 적 으로 데이터 가 업데이트 되 지 않 은 것 이다.
원인:루트 보기 구성 요소 가 같은 구성 요 소 를 인용 할 때 루트 가 변 할 때 이 구성 요 소 를 업데이트 할 수 없습니다.즉,우리 가 흔히 말 하 는 페이지 가 업데이트 할 수 없 는 문제 입 니 다.
필드:
<div id="app">
<ul>
<li><router-link to="/home/foo">To Foo</router-link></li>
<li><router-link to="/home/baz">To Baz</router-link></li>
<li><router-link to="/home/bar">To Bar</router-link></li>
</ul>
<router-view></router-view>
</div>
const Home = {
template: `<div>{{message}}</div>`,
data() {
return {
message: this.$route.params.name
}
}
}
const router = new VueRouter({
mode:'history',
routes: [
{path: '/home', component: Home },
{path: '/home/:name', component: Home }
]
})
new Vue({
el: '#app',
router
})
상단 코드 에서 우 리 는 루트 구축 옵션routes
에 동적 루트'/home/:name'
를 설 정 했 습 니 다.루트 구성 요소Home
를 함께 사용 합 니 다.이것 은 그들 이 다시 사용 하 는 것 을 의미 합 니 다RouterView
.경로 전환 을 할 때 페이지 는 첫 번 째 경로 가 일치 하 는 매개 변수 만 렌 더 링 한 다음 에 경로 전환 을 할 때
message
변화 가 없습니다.해결 방법:
해결 방법 은 여러 가지 가 있 는데,여 기 는 내 가 자주 사용 하 는 몇 가지 방법 만 열거 할 뿐이다.
감청
watch
을 통한 변화.
const Home = {
template: `<div>{{message}}</div>`,
data() {
return {
message: this.$route.params.name
}
},
watch: {
'$route': function() {
this.message = this.$route.params.name
}
}
}
...
new Vue({
el: '#app',
router
})
$route
에 귀속<router-view>
속성 을 주면 Vue 는 이것 이 다르다 고 생각 합 니 다key
.단점:
<router-view>
에서/home
등 다른 경로 로 넘 어가 면 우 리 는 구성 요소 업데이트 문 제 를 걱정 하지 않 아 도 되 기 때문에 이때/user
속성 은 불필요 하 다.
<div id="app">
...
<router-view :key="key"></router-view>
</div>
참고:Vue 응답 식 데이터 업데이트 에 대한 오해-https://github.com/xiaofuzi/deep-in-vue/issues/11
[작은 완자 의 성]-https://www.cnblogs.com/youhong/p/12173354.html
Vue 데 이 터 를 상세 하 게 업 데 이 트 했 지만 페이지 가 업데이트 되 지 않 은 7 가지 상황 을 모 아 정리 하고 연장 하 는 글 을 소개 합 니 다.더 많은 Vue 데이터 업데이트 내용 은 저희 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 저 희 를 많이 지 켜 주시 기 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Vue Render 함수로 DOM 노드 코드 인스턴스 만들기render에서createElement 함수를 사용하여 DOM 노드를 만드는 것은 직관적이지 않지만 일부 독립 구성 요소의 디자인에서 특수한 수요를 충족시킬 수 있습니다.간단한 렌더링 예는 다음과 같습니다. 또한 v...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.