Rumah > Artikel > hujung hadapan web > Adakah vue menyegarkan dom dalam masa nyata?
vue tidak memuat semula dom dalam masa nyata. Kemas kini data dalam Vue adalah tidak segerak, yang bermaksud elemen DOM yang diubah suai tidak boleh diperolehi serta-merta selepas mengubah suai Data. Vue dilaksanakan secara tidak segerak apabila mengemas kini DOM Selagi ia mengesan perubahan data, Vue akan membuka baris gilir dan menimpan semua perubahan data yang berlaku dalam gelung peristiwa yang sama dicetuskan beberapa kali dalam baris gilir, penyahduplikasian ini semasa penimbalan adalah sangat penting untuk mengelakkan pengiraan yang tidak perlu dan operasi DOM.
Persekitaran pengendalian tutorial ini: sistem windows7, versi vue3, komputer DELL G3.
Kemas kini data dalam Vue adalah tak segerak , yang bermaksud kami tidak boleh mendapatkan elemen DOM yang diubah suai serta-merta selepas mengubah suai Data.
Vue dilaksanakan secara tidak segerak apabila mengemas kini DOM
Selagi ia mengesan perubahan data, Vue
akan membuka baris gilir dan menampan semua data yang berlaku dalam gelung peristiwa yang sama Perubahan, jika. watcher
yang sama dicetuskan berbilang kali, hanya akan ditolak ke dalam baris gilir sekali. Pengalihan keluar data pendua semasa penimbalan adalah sangat penting untuk mengelakkan pengiraan yang tidak perlu dan operasi DOM
, di bawah Dalam gelung acara tick
. Vue
menyegarkan baris gilir dan melakukan kerja sebenar (deduplikat) Secara dalaman, Vue
cuba menggunakan Promise.then
asli, MutationObserver
dan setImmediate
untuk baris gilir tak segerak , setTimeout(fn, 0)
akan digunakan sebaliknya.
Prinsip Vue mengemas kini DOM secara tidak segerak
1. Bilakah saya boleh mendapatkan elemen DOM sebenar?
dalam panggilan balik nextTick Vue.
2. Mengapakah Vue perlu menggunakan kaedah nextTick untuk mendapatkan DOM terkini?
Apabila vue memanggil Watcher untuk mengemas kini paparan, ia tidak mengemas kini secara langsung, sebaliknya, ia menambah Watcher yang perlu dikemas kini pada baris gilir queueWatcher, dan kemudian menghantar kaedah kemas kini khusus flushSchedulerQueue kepada nexTick. untuk memanggil.
// src > core > observer > watcher.js + scheduler.js// 当一个 Data 更新时,会依次执行以下代码
// 1. 触发 Data.set
// 2. 调用 dep.notify
// 3. Dep 会遍历所有相关的 Watcher 执行 update 方法
class Watcher {
// 4. 执行更新操作
update() {
queueWatcher(this);
}
}
const queue = [];
function queueWatcher(watcher: Watcher) {
// 5. 将当前 Watcher 添加到异步队列
queue.push(watcher);
// 6. 执行异步队列,并传入回调
nextTick(flushSchedulerQueue);
}
// 更新视图的具体方法
function flushSchedulerQueue() {
let watcher, id;
// 排序,先渲染父节点,再渲染子节点
// 这样可以避免不必要的子节点渲染,如:父节点中 v-if 为 false 的子节点,就不用渲染了
queue.sort((a, b) => a.id - b.id);
// 遍历所有 Watcher 进行批量更新。
for (index = 0; index
2.2 nextTick -- Tambah flushSchedulerQueue masuk ke tatasusunan panggilan balik, dan kemudian laksanakan kaedah timerFunc.
const callbacks = [];
let timerFunc;
function nextTick(cb?: Function, ctx?: Object) {
let _resolve;
// 1.将传入的 flushSchedulerQueue 方法添加到回调数组
callbacks.push(() => {
cb.call(ctx);
});
// 2.执行异步任务
// 此方法会根据浏览器兼容性,选用不同的异步策略
timerFunc();
}
Kaedah 2.3 timerFunc -- ialah kaedah tak segerak yang dibuat berdasarkan keserasian penyemak imbas Selepas melaksanakan kaedah ini, kaedah flushSchedulerQueue akan dipanggil untuk kemas kini DOM tertentu.
let timerFunc;
// 判断是否兼容 Promise
if (typeof Promise !== "undefined") {
timerFunc = () => {
Promise.resolve().then(flushCallbacks);
};
// 判断是否兼容 MutationObserver
// https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver
} else if (typeof MutationObserver !== "undefined") {
let counter = 1;
const observer = new MutationObserver(flushCallbacks);
const textNode = document.createTextNode(String(counter));
observer.observe(textNode, {
characterData: true,
});
timerFunc = () => {
counter = (counter + 1) % 2;
textNode.data = String(counter);
};
// 判断是否兼容 setImmediate
// 该方法存在一些 IE 浏览器中
} else if (typeof setImmediate !== "undefined") {
// 这是一个宏任务,但相比 setTimeout 要更好
timerFunc = () => {
setImmediate(flushCallbacks);
};
} else {
// 如果以上方法都不知道,使用 setTimeout 0
timerFunc = () => {
setTimeout(flushCallbacks, 0);
};
}
// 异步执行完后,执行所有的回调方法,也就是执行 flushSchedulerQueue
function flushCallbacks() {
for (let i = 0; i
2.4 Meningkatkan pertimbangan logik
2.4.1 Menghakimi bendera yang ada untuk mengelak daripada menambah Pemerhati yang sama pada Baris Gilir ;
2.4.2 Menilai bendera menunggu supaya semua Pengawas dikemas kini dalam satu tanda; .
Jika keadaan v-if dicetuskan, Pemerhati baharu akan dipaparkan.
petua: nextTick hanyalah tugas tak segerak yang hanya disimulasikan melalui Promise, setTimeout dan kaedah lain.
3. Mengapa ini boleh.$nextTick memperoleh DOM yang dikemas kini?Memanggil ini.$nextTick sebenarnya memanggil kaedah nextTick dalam rajah dan melaksanakan fungsi panggil balik dalam baris gilir tak segerak. Menurut prinsip masuk dahulu keluar dahulu, baris gilir tak segerak kemas kini yang dicetuskan dengan mengubah suai Data akan dilaksanakan terlebih dahulu Selepas pelaksanaan selesai, DOM baharu akan dihasilkan Seterusnya, apabila fungsi panggil balik ini.$nextTick dilaksanakan, elemen DOM yang dikemas kini boleh diperolehi.
// 我们使用 this.$nextTick 其实就是调用 nextTick 方法
Vue.prototype.$nextTick = function (fn: Function) {
return nextTick(fn, this);
};
Atas ialah kandungan terperinci Adakah vue menyegarkan dom dalam masa nyata?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!