Vue 의 nextTick 방법 을 간단하게 이해 합 니 다.
예시
먼저 예 를 들 어 Vue 의 DOM 업데이트 와 nextTick 의 역할 에 대해 알 아 보 겠 습 니 다.
템 플 릿
<div class="app">
<div ref="msgDiv">{{msg}}</div>
<div v-if="msg1">Message got outside $nextTick: {{msg1}}</div>
<div v-if="msg2">Message got inside $nextTick: {{msg2}}</div>
<div v-if="msg3">Message got outside $nextTick: {{msg3}}</div>
<button @click="changeMsg">
Change the Message
</button>
</div>
Vue 실례
new Vue({
el: '.app',
data: {
msg: 'Hello Vue.',
msg1: '',
msg2: '',
msg3: ''
},
methods: {
changeMsg() {
this.msg = "Hello world."
this.msg1 = this.$refs.msgDiv.innerHTML
this.$nextTick(() => {
this.msg2 = this.$refs.msgDiv.innerHTML
})
this.msg3 = this.$refs.msgDiv.innerHTML
}
}
})
클릭 전클릭 후
그림 에서 알 수 있 듯 이 msg 1 과 msg 3 에 표 시 된 내용 은 변 경 된 것 이 고 msg 2 에 표 시 된 내용 은 변 경 된 것 이다.그 근본 적 인 원인 은 Vue 에서 DOM 업데이트 가 비동기 적 이기 때문이다.
2.응용 장면
다음은 nextTick 의 주요 응용 장면 과 원인 을 알 아 보 겠 습 니 다.
Vue 라 이 프 사이클 의 created()갈고리 함수 에서 진행 되 는 DOM 작업 은 Vue.nextTick()의 리 셋 함수 에 넣 어야 합 니 다.
created()갈고리 함수 가 실 행 될 때 DOM 은 렌 더 링 을 하지 않 았 습 니 다.이때 DOM 작업 을 하 는 것 은 헛 된 것 이 아니 므 로 DOM 작업 의 js 코드 를 Vue.nextTick()의 리 셋 함수 에 넣 어야 합 니 다.이에 대응 하 는 것 은 mounted()갈고리 함수 입 니 다.이 갈고리 함수 가 실 행 될 때 모든 DOM 마 운 트 와 렌 더 링 이 완료 되 었 기 때문에 이 갈고리 함수 에서 어떠한 DOM 작업 도 문제 가 되 지 않 습 니 다.
데이터 가 변 한 후에 실행 할 동작 입 니 다.이 동작 은 데이터 에 따라 변 경 된 DOM 구 조 를 사용 해 야 할 때 이 동작 은 모두 Vue.nextTick()의 리 셋 함수 에 넣 어야 합 니 다.
구체 적 인 원인 은 Vue 의 공식 문서 에서 상세 하 게 설명 한다.
Vue 비동기 로 DOM 업 데 이 트 를 실행 합 니 다.데이터 변 화 를 관찰 하면 Vue 는 하나의 대기 열 을 열 고 같은 이벤트 순환 에서 발생 하 는 모든 데이터 변 화 를 버퍼 링 합 니 다.같은 watcher 가 여러 번 트리거 되면 대기 열 에 한 번 만 추 가 됩 니 다.버퍼 링 을 할 때 중복 데 이 터 를 제거 하 는 것 은 불필요 한 계산 과 DOM 작업 을 피 하 는 데 매우 중요 하 다.그리고 다음 이벤트 순환"tick"에서 Vue 가 대기 열 을 새로 고치 고 실제(무 거 운 것)작업 을 수행 합 니 다.Vue 는 내부 에서 비동기 대기 열 에 원생 Promise.then 과 MessageChannel 을 사용 하려 고 시도 하 며,실행 환경 이 지원 되 지 않 으 면 setTimeout(fn,0)으로 대체 합 니 다.
예 를 들 어 vm.somedata='new value'를 설정 하면 이 구성 요 소 는 바로 렌 더 링 되 지 않 습 니 다.대기 열 을 새로 고 칠 때 구성 요 소 는 이벤트 순환 대기 열 이 비어 있 을 때 다음"tick"을 업데이트 합 니 다.대부분의 경우 우 리 는 이 과정 에 관심 을 가 질 필요 가 없 지만,DOM 상태 가 업 데 이 트 된 후에 무엇 을 하고 싶다 면 좀 까다 로 울 수 있다.Vue.js 는 개발 자 들 이'데이터 구동'방식 으로 생각 하고 DOM 과 직접 접촉 하지 않도록 격려 하지만 가끔 우 리 는 이렇게 해 야 한다.데이터 가 변 한 후 Vue 가 DOM 업 데 이 트 를 완료 할 때 까지 기다 리 기 위해 서 는 데이터 가 변 한 후 바로 Vue.nextTick(callback)을 사용 할 수 있 습 니 다.이렇게 리 셋 함 수 는 DOM 업데이트 가 완료 되면 호출 됩 니 다.
3.nextTick 소스 코드 에 대한 분석
역할.
Vue.nextTick 은 코드 실행 을 지연 시 키 는 데 사 용 됩 니 다.2 개의 인자(리 셋 함수 와 리 셋 함 수 를 실행 하 는 컨 텍스트 환경)를 받 아들 입 니 다.리 셋 함 수 를 제공 하지 않 으 면 promise 대상 으로 돌아 갑 니 다.
소스 코드
/**
* Defer a task to execute it asynchronously.
*/
export const nextTick = (function () {
const callbacks = []
let pending = false
let timerFunc
function nextTickHandler () {
pending = false
const copies = callbacks.slice(0)
callbacks.length = 0
for (let i = 0; i < copies.length; i++) {
copies[i]()
}
}
// the nextTick behavior leverages the microtask queue, which can be accessed
// via either native Promise.then or MutationObserver.
// MutationObserver has wider support, however it is seriously bugged in
// UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It
// completely stops working after triggering a few times... so, if native
// Promise is available, we will use it:
/* istanbul ignore if */
if (typeof Promise !== 'undefined' && isNative(Promise)) {
var p = Promise.resolve()
var logError = err => { console.error(err) }
timerFunc = () => {
p.then(nextTickHandler).catch(logError)
// in problematic UIWebViews, Promise.then doesn't completely break, but
// it can get stuck in a weird state where callbacks are pushed into the
// microtask queue but the queue isn't being flushed, until the browser
// needs to do some other work, e.g. handle a timer. Therefore we can
// "force" the microtask queue to be flushed by adding an empty timer.
if (isIOS) setTimeout(noop)
}
} else if (!isIE && typeof MutationObserver !== 'undefined' && (
isNative(MutationObserver) ||
// PhantomJS and iOS 7.x
MutationObserver.toString() === '[object MutationObserverConstructor]'
)) {
// use MutationObserver where native Promise is not available,
// e.g. PhantomJS, iOS7, Android 4.4
var counter = 1
var observer = new MutationObserver(nextTickHandler)
var textNode = document.createTextNode(String(counter))
observer.observe(textNode, {
characterData: true
})
timerFunc = () => {
counter = (counter + 1) % 2
textNode.data = String(counter)
}
} else {
// fallback to setTimeout
/* istanbul ignore next */
timerFunc = () => {
setTimeout(nextTickHandler, 0)
}
}
return function queueNextTick (cb?: Function, ctx?: Object) {
let _resolve
callbacks.push(() => {
if (cb) {
try {
cb.call(ctx)
} catch (e) {
handleError(e, ctx, 'nextTick')
}
} else if (_resolve) {
_resolve(ctx)
}
})
if (!pending) {
pending = true
timerFunc()
}
if (!cb && typeof Promise !== 'undefined') {
return new Promise((resolve, reject) => {
_resolve = resolve
})
}
}
})()
우선,nextTick 에서 정의 하 는 세 가지 중요 한 변 수 를 알 아 보 세 요.
function nextTickHandler () {
pending = false
const copies = callbacks.slice(0)
callbacks.length = 0
for (let i = 0; i < copies.length; i++) {
copies[i]()
}
}
이 함 수 는 콜 백 스에 저 장 된 모든 리 셋 함 수 를 실행 하 는 데 사 용 됩 니 다.다음은 트리거 방식 을 timerFunc 에 할당 합 니 다.
원생 지원 promise 여 부 를 먼저 판단 하고 지원 하면 promise 를 이용 하여 리 셋 함 수 를 실행 합 니 다.
그렇지 않 으 면 MutationObserver 를 지원 하면 관찰자 대상 을 예화 하고 텍스트 노드 의 변 화 를 관찰 할 때 모든 리 셋 함 수 를 실행 합 니 다.
지원 되 지 않 으 면 setTimeout 설정 을 0 으로 지연 합 니 다.
마지막 으로 queue NextTick 함수 입 니 다.nextTick 은 실시 간 함수 이기 때문에 quueNextTick 함 수 는 되 돌아 오 는 함수 입 니 다.사용자 가 들 어 오 는 인 자 를 받 아들 여 콜백 스에 리 셋 함 수 를 저장 합 니 다.
위의 그림 은 전체 실행 프로 세 스 입 니 다.관건 은 timeFunc()입 니 다.이 함 수 는 실행 을 지연 시 키 는 역할 을 합 니 다.
위의 설명 을 통 해 알 수 있 듯 이 timeFunc()는 모두 세 가지 실현 방식 이 있다.
다음은 Mutation Observer 에 중심 을 두 고 소개 하 겠 습 니 다.
MutationObserver 는 HTML 5 의 새 API 로 DOM 변동 을 감시 하 는 인터페이스 입 니 다.그 는 DOM 대상 에서 발생 하 는 하위 노드 삭제,속성 수정,텍스트 내용 수정 등 을 감청 할 수 있다.
호출 과정 은 매우 간단 하지만,좀 심상 치 않다.너 는 먼저 그 에 게 리 셋 을 해 야 한다.
var mo = new MutationObserver(callback)
Mutation Observer 의 구조 함수 에 리 셋 을 전달 하면 Mutation Observer 인 스 턴 스 를 얻 을 수 있 습 니 다.이 리 셋 은 Mutation Observer 인 스 턴 스 가 변동 을 감청 할 때 실 행 됩 니 다.이때 당신 은 Mutation Observer 인 스 턴 스 에 리 셋 을 연결 시 켰 을 뿐 어떤 DOM,감청 노드 가 삭제 되 었 는 지,감청 속성 이 수정 되 었 는 지 구체 적 으로 감청 하 였 을 뿐 설정 되 지 않 았 습 니 다.그의 observer 방법 을 호출 하면 이 단 계 를 완성 할 수 있다.
var domTarget = dom
mo.observe(domTarget, {
characterData: true // 。
})
nextTick 에서 Mutation Observer 의 역할 은 위의 그림 과 같다.DOM 업 데 이 트 를 감청 한 후 리 셋 함 수 를 호출 합 니 다.
사실 Mutation Observer 를 사용 하 는 이 유 는 nextTick 이 비동기 API 를 원 하기 때 문 입 니 다.현재 동기 코드 가 실 행 된 후에 제 가 실행 하고 싶 은 비동기 리 셋 을 실행 하 는 데 사 용 됩 니 다.Promise 와 setTimeout 을 포함 한 것 은 모두 이 때 문 입 니 다.그 중에서 도 microtask 등 내용 이 깊이 있 고 이해 하지 못 하면 깊이 소개 하지 않 습 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.