これについてさらに詳しく説明しましょう。$nextTick!
もうすぐ 2023 年になりますが、これを行う方法がまだわかりません。$nextTick? Vue2 がリリースされてから約 10 年、Vue3 がリリースされてから 2 年以上が経ちます。それは正しい!恥ずかしいです。これしか知りません。nextTick now (正直に言うと) さて、まずは百度で検索してみましょう、クリック、クリック、クリック... すぐに Vue.js 公式 Web サイトのドキュメントにジャンプしました、突然ドキュメント内に文を見つけました? :
nextTick: 次の DOM 更新サイクルの終了後に遅延コールバックを実行します。データを変更した直後にこのメソッドを使用して、更新された DOM を取得します。これには 2 つのパラメータがあります: 最初のパラメータは
Callback function
で、渡されなかった場合に Promise 呼び出しを提供します; 2 番目のパラメータは実行環境コンテキスト
で、渡されなかった場合は自動的にバインドされます。呼び出されるインスタンス上で。 [関連する推奨事項: vuejs ビデオ チュートリアル 、Web フロントエンド開発 ]
まず、nextTick とは何なのか見てみましょう。
console.log(this.$nextTick); // 控制台打印 if(fn){ return nextTick(fn, this); }
nextTick がメソッドであることがわかります。このメソッドには、fn と this という 2 つのパラメータがあります。fn は、渡す必要があるコールバック関数です。thisいわゆる実行環境コンテキストです。そこで質問は、次の DOM 更新が完了するまで、Vue で遅延コールバックを実装するにはどうすればよいでしょうか? まず次の例を見てみましょう:
<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);// 你好,世界! }); },
上の例から、DOM は作成されたライフ サイクルで操作されますが、作成されたライフ サイクルはデータを初期化するだけであることは誰もが知っています。この期間中はレンダリングは行われません。DOM を直接操作すると、DOM 要素を見つけることができません。次に疑問が生じます。なぜ nextTick に DOM 要素を配置することで DOM 要素を取得できるのでしょうか? これは明らかではないでしょうか? DOM がレンダリングされるまで待ってから、DOM を呼び出して取得します。次に、DOM オペレーション コードを呼び出す前に、次回 DOM がレンダリングされるまで待機するために nextTick が使用されていることがわかります。 nextTick
。そこで、再び疑問が生じます。nextTick は正確に何をするのでしょうか? Vue2 および Vue3 バージョンの nextTick 原理をソース コード レベルから分析してみましょう。
nextTick の Vue2 バージョン
Vue は開発者に nextTick メソッドを公開しているため、このメソッドでは コールバック関数の追加 という 3 つの主な処理が行われます。 はコールバック関数 の実行を遅らせ、 は現在の nextTick がコールバック関数 に渡されるかどうかを決定します。渡されない場合は Promise、this.$nextTick.then(()=>{}) となり、Promise として処理されます。
- 現在のスコープ内に複数の nextTick 関数が存在する可能性があるため、コールバック関数がコールバック配列に追加されます。
- 現在の nextTick が pending=true としてマークされているかどうか、つまり実行中であるかどうかを確認します。そうでない場合は、timerFunc (非同期実行関数を使用します(flushCallbacks関数を非同期で呼び出します)。 timerFunc の実行により、現在の環境が Promise、MutationObserver、setImmediate、setTimeout をサポートしているかどうかが決まります。優先順位は前から後ろにあり、4 つの状況に分けられます:
- 最初に Promise を使用します。 , 現在の環境が Promise をサポートしている場合、NextTick はデフォルトで Promise を使用し、遅延コールバック関数を実行します。timerFunc は Promise を実行します。Promise は es6 での構文です。現在の環境が es6 での構文のみをサポートしている場合は、後のサポートのみを考慮できます。
- 支持MutationObserver,HTML5的api,中文意思是:修改的监听,MutationObserver
用来监听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
使用Vue2的nextTick
传入回调函数参数使用:
this.$nextTick(()=>{ // ...操作DOM的代码 })
ログイン後にコピー不传入回调函数参数使用:
// 方式一 this.$nextTick().then(()=>{ // ...操作DOM的代码 }) // 方式二 await this.$nextTick(); // 后写操作DOM的代码
ログイン後にコピー
Vue3版本的nextTick
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 }
使用Vue3的nextTick
传入回调函数使用
import { nextTick } from 'vue' // 引入 setup () { nextTick(()=>{ // ...操作DOM的代码 })
ログイン後にコピー不传入回调函数的使用
import { nextTick } from 'vue' // 引入 setup () { // 方式一 nextTick().then(()=>{ // ...操作DOM的代码 }) // 方式二 await nextTick(); // 后写操作DOM的代码 }
ログイン後にコピー总结
- nextTick可以通俗的当作一个Promise,所以nextTick属于微任务。
- nextTick在页面更新数据后,DOM更新,可以通俗理解为,nextTick就是用来支持操作DOM的代码及时更新渲染页面。也就是在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick()的回调函数中。
- 在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中。
以上がこれについてさらに詳しく説明しましょう。$nextTick!の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











vue.jsでBootstrapを使用すると、5つのステップに分かれています。ブートストラップをインストールします。 main.jsにブートストラップをインポートしますブートストラップコンポーネントをテンプレートで直接使用します。オプション:カスタムスタイル。オプション:プラグインを使用します。

HTMLテンプレートのボタンをメソッドにバインドすることにより、VUEボタンに関数を追加できます。 VUEインスタンスでメソッドを定義し、関数ロジックを書き込みます。

Vue.jsの監視オプションにより、開発者は特定のデータの変更をリッスンできます。データが変更されたら、Watchはコールバック関数をトリガーして更新ビューまたはその他のタスクを実行します。その構成オプションには、すぐにコールバックを実行するかどうかを指定する即時と、オブジェクトまたは配列の変更を再帰的に聴くかどうかを指定するDEEPが含まれます。

VUEマルチページ開発は、VUE.JSフレームワークを使用してアプリケーションを構築する方法です。アプリケーションは別々のページに分割されます。コードメンテナンス:アプリケーションを複数のページに分割すると、コードの管理とメンテナンスが容易になります。モジュール性:各ページは、簡単に再利用および交換するための別のモジュールとして使用できます。簡単なルーティング:ページ間のナビゲーションは、単純なルーティング構成を介して管理できます。 SEOの最適化:各ページには独自のURLがあり、SEOに役立ちます。

vue.jsでJSファイルを参照するには3つの方法があります。タグ;; mounted()ライフサイクルフックを使用した動的インポート。 Vuex State Management Libraryを介してインポートします。

vue.jsには、前のページに戻る4つの方法があります。$ router.go(-1)$ router.back()outes&lt; router-link to =&quot;/&quot; Component Window.history.back()、およびメソッド選択はシーンに依存します。

Vue.jsには配列とオブジェクトを通過するには3つの一般的な方法があります。V-Forディレクティブは、各要素をトラバースしてテンプレートをレンダリングするために使用されます。 V-BindディレクティブをV-Forで使用して、各要素の属性値を動的に設定できます。 .mapメソッドは、配列要素を新しい配列に変換できます。

VUEにDIV要素をジャンプするには、VUEルーターを使用してルーターリンクコンポーネントを追加するには、2つの方法があります。 @clickイベントリスナーを追加して、これを呼び出します。$ router.push()メソッドをジャンプします。
