Rumah >hujung hadapan web >View.js >Biar saya memberi anda pemahaman yang lebih mendalam tentang perkara ini.$nextTick!
Sudah hampir 2023, adakah anda masih tidak tahu cara melakukannya.$nextTick Vue2 telah keluar selama hampir 10 tahun, dan Vue3 telah keluar selama lebih daripada dua tahun, betul! Memalukan untuk mengatakannya. Saya hanya tahu ini.nextTick sekarang (untuk memberitahu kebenaran, mari kita cari di Baidu dahulu, klik klik klik... Saya cepat-cepat melompat ke dokumen laman web rasmi Vue.js dan tiba-tiba menemui satu). ayat dalam dokumen? :
nextTick: Laksanakan panggilan balik tertunda selepas kitaran kemas kini DOM seterusnya tamat. Gunakan kaedah ini serta-merta selepas mengubah suai data untuk mendapatkan DOM yang dikemas kini. Ia mempunyai dua parameter: parameter pertama ialah
回调函数
, yang menyediakan panggilan janji jika tidak diluluskan; parameter kedua ialah执行环境上下文
, jika tidak diluluskan, ia akan terikat secara automatik kepada tika yang memanggilnya secara lalai. [Cadangan berkaitan: tutorial video vuejs, pembangunan bahagian hadapan web]
Mari kita lihat dahulu apakah nextTick itu?
console.log(this.$nextTick); // 控制台打印 if(fn){ return nextTick(fn, this); }
Kita dapat melihat bahawa nextTick ialah kaedah yang mempunyai dua parameter: fn dan ini fn ialah fungsi panggil balik yang perlu dilalui ini 🎜> ialah Konteks persekitaran pelaksanaan yang dipanggil. Jadi persoalannya, Bagaimana untuk melaksanakan panggilan balik tertunda dalam Vue sehingga kemas kini DOM seterusnya selesai? Mari kita lihat contoh berikut terlebih dahulu:
<div ref="test1">created:{{message}}</div> // vue实例 data: { message: "Hello World!", }, created(){ this.message = '你好,世界!'; console.log(this.$refs.test1.innerText);// 报错 // TypeError: Cannot read properties of undefined (reading 'innerText') this.$nextTick(()=>{ console.log('test1 nextTick:',this.$refs.test1.innerText);// 你好,世界! }); },Daripada contoh di atas, DOM dimanipulasi dalam kitaran hayat yang dicipta, tetapi kita semua tahu bahawa kitaran hayat yang dicipta hanya memulakan data . Dalam tempoh ini, masih terdapat Tanpa membuat DOM, jika kita mengendalikan DOM secara langsung, kita tidak dapat mencari elemen DOM Kemudian timbul persoalan:
Mengapa kita boleh mendapatkan elemen DOM dengan meletakkannya di nextTick? Bukankah ini jelas? Tunggu sehingga DOM dipaparkan dan kemudian panggil untuk mendapatkannya, supaya anda tahu . Jadi persoalan datang lagi, apa sebenarnya yang nextTick lakukan? Mari kita analisa prinsip nextTick versi Vue2 dan Vue3 daripada tahap kod sumber. nextTick作用就是用来等下次DOM渲染完才去调用nextTick内的DOM操作代码
Fungsi Panggilan Balik Tambah , untuk menangguhkan pelaksanaan fungsi panggil balik , untuk menentukan sama ada nextTick semasa dihantar ke dalam fungsi panggil balik . Jika tidak diluluskan, ia adalah Janji, ini.$nextTick.then(()=>{}), dan diproses sebagai Promise.
用来监听DOM的变动
,比如节点的增减、属性的变动、文本内容的修改等都会触发MutationObserver事件。注意地,与事件不同,事件是同步触发,DOM的变动会立即触发事件,而MutationObserver事件是异步触发,DOM不会立即触发,需要等当前所有DOM操作完毕才会触发。MutationObserver有7个属性:
childList
(true,监听子节点的变动)、attributes
(true,监听属性的变动)、characterData
(true,监听节点内容或节点文本的变动)、subtree
(是否应用于该节点的所有后代节点)、attributeOldValue
(观察attributes变动时,是否需要记录变动前的属性值)、characterDataOldValue
(观察characterData变动时,是否需要记录变动前的值)、attributeFilter
(数组,表示需要观察的特定属性(比如[‘class’,‘src’])。
为什么需要创建一个文本节点?因为在这里操作DOM保证浏览器页面是最新DOM渲染的,虽然看来好像是没什么作用,但这是保证拿到的DOM是最新的。
支持setImmediate、setTimeout,setImmediate即时计时器立即执行工作,它是在事件轮询之后执行,为了防止轮询阻塞,每次只会调用一个。setTimeout按照一定时间后执行回调函数。
好了好了,到了现在,我们都知道nextTick做了什么吧,但是我们有没有想过这样的一个问题:既然都是异步回调执行等待DOM更新后才去调用操作DOM的代码,那么这个机制又是什么原理?这就是JS的执行机制有关了,涉及宏任务与微任务的知识,我们先来看看这样的一道题:
console.log('同步代码1'); setTimeout(function () { console.log("setTimeout"); }, 0); new Promise((resolve) => { console.log('同步代码2') resolve() }).then(() => { console.log('promise.then') }) console.log('同步代码3');
我们可能会问上面的输出是个啥,首先js是单线程,所以在js程序运行中只有一个执行栈,实现不了多线程,所以就需要任务均衡分配,通俗的讲,按任务急优先处理原则,js中分为同步任务和异步任务,异步任务又分为宏任务和微任务,同步任务先入栈,程序会先把执行栈中的所有同步任务执行完,再去判断是否有异步任务,而异步任务中微任务的优先级高于宏任务。如果当前执行栈为空,而微任务队列不为空,就先执行微任务,等把所有微任务执行完,最后才会考虑宏任务。而上面代码中Promise是属于微任务
,而setTimeout是宏任务
,所以上面的输出为:
// 同步代码1 // 同步代码2 // 同步代码3 // promise.then // setTimeout
传入回调函数参数使用:
this.$nextTick(()=>{ // ...操作DOM的代码 })
不传入回调函数参数使用:
// 方式一 this.$nextTick().then(()=>{ // ...操作DOM的代码 }) // 方式二 await this.$nextTick(); // 后写操作DOM的代码
Vue3版本就没有Vue2版本的那么多环境支持,nextTick封装成了一个Promise异步回调函数执行。
// Vue3.2.45 // core-main\core-main\packages\runtime-core\src export function nextTick<T = void>( this: T, fn?: (this: T) => void ): Promise<void> { const p = currentFlushPromise || resolvedPromise return fn ? p.then(this ? fn.bind(this) : fn) : p }
传入回调函数使用
import { nextTick } from 'vue' // 引入 setup () { nextTick(()=>{ // ...操作DOM的代码 })
不传入回调函数的使用
import { nextTick } from 'vue' // 引入 setup () { // 方式一 nextTick().then(()=>{ // ...操作DOM的代码 }) // 方式二 await nextTick(); // 后写操作DOM的代码 }
Atas ialah kandungan terperinci Biar saya memberi anda pemahaman yang lebih mendalam tentang perkara ini.$nextTick!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!