Vue の紹介現在のビッグフロントエンドの時代は、混乱と衝突の時代です。世界は多くの派閥に分かれており、主にVue、React、Angularが主導し、フロントエンドフレームワークの三つ巴の状況を形成しています。フロントエンドフレームワークにおけるVueの位置づけは、かつてのjQueryのようなものであり、そのシンプルさと開発効率の高さから、フロントエンドエンジニアにとって必須のスキルの一つとなっています。 Vue は、サードパーティのプラグインと UI コンポーネント ライブラリを完全に統合するプログレッシブ JavaScript フレームワークです。jQuery との最大の違いは、開発者が DOM ノードを直接操作しなくても、Vue ではページのレンダリング コンテンツを変更できることです。アプリケーション開発者は、特定の HTML、CSS、JavaScript を基盤として、すぐに使い始めて、エレガントで簡潔なアプリケーション モジュールを開発できます。 序文カスタム命令は、コンポーネントの次に Vue で 2 番目に頻繁に使用され、5 つのライフサイクル フック (
基本的な使い方公式サイトの場合: <div id='アプリ'> <入力タイプ="テキスト" v-model="入力値" v-focus> </div> <スクリプト> Vue.directive('focus', { // 要素を初めてバインドするときにbind()を呼び出す { コンソールログ('バインド') }, // バインドされた要素が DOM に挿入されると... 挿入: 関数 (el) { console.log('挿入されました') el.フォーカス() }, // コンポーネント VNode が更新されたら update() を呼び出す { コンソールログ('更新') }, // 命令が配置されているコンポーネントのすべての VNode とその子 VNode が更新された後に、componentUpdated() を呼び出します { console.log('コンポーネントが更新されました') }, // 一度だけ呼び出される unbind() は、命令が要素からアンバインドされたときに呼び出されます { console.log('アンバインド') } }) 新しいVue({ データ: { 入力値: '' } }).$mount('#app') </スクリプト> コマンドの動作初期化グローバル API を初期化するときに、 // src/core/vdom/patch.js const フック = ['create'、'activate'、'update'、'remove'、'destroy'] エクスポート関数createPatchFunction(バックエンド){ i,jとします 定数 cbs = {} const { モジュール、 nodeOps } = バックエンド (i = 0; i < hooks.length; ++i) の場合 { cbs[フック[i]] = [] // モジュールは、class、style、domListener、domProps、attrs、directive、ref、transition などの Vue のモジュールに対応します。 (j = 0; j < モジュールの長さ; ++j) { if (isDef(モジュール[j][フック[i]])) { // 最後にフックを{hookEvent: [cb1, cb2 ...], ...}形式に変換します。cbs[hooks[i]].push(modules[j][hooks[i]]) } } } // .... 関数 patch (oldVnode, vnode, hydrating, removeOnly) を返す { // ... } } テンプレートのコンパイルテンプレートのコンパイルは、命令パラメータを解析することです。具体的に分解された { タグ: '入力', 親: ASTElement、 ディレクティブ: [ { arg: null、// パラメータ終了: 56、// 命令の終了文字位置 isDynamicArg: false、// 動的パラメータ、v-xxx[dynamicParams]='xxx' フォーム呼び出し修飾子: undefined、// 命令修飾子名: "model"、 rawName: "v-model", // 命令名開始: 36, // 命令開始文字位置値: "inputValue" // テンプレート }, { 引数: null、 終了: 67, isDynamicArg: false、 修飾子: 未定義、 名前: "フォーカス"、 生の名前: "v-focus", 開始: 57, 価値: "" } ]、 // ... } レンダリング方法の生成Vue では、DOM を操作するためにディレクティブを使用することを推奨しています。カスタム ディレクティブは DOM や属性を変更する可能性があるため、テンプレートの解析に対するディレクティブの影響を避けてください。レンダリング メソッドを生成するときに最初に処理されるのは、本質的には構文糖である (これ){ _c('div', { を返す 属性: { 「id」: 「アプリ」 } }, [_c('入力', { ディレクティブ: [{ 名前: "モデル", 生の名前: "v-model", 値: (入力値) 式: "inputValue" }, { 名前: "フォーカス"、 生の名前: "v-focus" }], 属性: { "タイプ": "テキスト" }, domProps: { "value": (inputValue) // v-model命令を処理するときに追加される属性}, の上: { "input": function($event) { // v-model ディレクティブを処理するときにカスタムイベントが追加されます if ($event.target.composing) 戻る; 入力値 = $event.target.value } } })]) } VNode を生成するvue のディレクティブは、DOM の操作を容易にするように設計されています。VNode を生成するとき、ディレクティブは追加の処理を行いません。 実際のDOMを生成するvue の初期化プロセスでは、次の 2 つの点を覚えておく必要があります。
パッチ処理中、実際の DOM を生成するために createElm が呼び出されるたびに、現在の VNode にデータ属性があるかどうかを検出します。データ属性がある場合は、invokeCreateHooks が呼び出され、最初に作成されたフック関数が実行されます。コア コードは次のとおりです。 // src/core/vdom/patch.js 関数createElm( vノード、 挿入されたVnodeQueue、 親エルム、 refElm、 ネストされた、 所有者配列、 索引 ){ // ... // createComponent には戻り値があり、これはコンポーネントを作成するメソッドです。戻り値がない場合は、次のメソッドに進みます if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) { 戻る } 定数データ = vnode.data // .... if (isDef(データ)) { // 実際のノードが作成された後、命令を含むノード属性を更新します // 命令は最初に bind メソッドを呼び出し、次に命令の以降のフック メソッドを初期化します。invokeCreateHooks(vnode, insertedVnodeQueue) } // 下から上へ、insert(parentElm, vnode.elm, refElm) // ... } 上記は、ディレクティブフックメソッドの最初のエントリです。directive.js // src/core/vdom/modules/directives.js // デフォルトでは、スローされるすべてのメソッドは updateDirectives メソッドです export default { 作成: updateDirectives、 更新: updateDirectives、 破棄: 関数 unbindDirectives (vnode: VNodeWithData) { // 破棄されると、vnode === emptyNode 更新ディレクティブ(vnode、空ノード) } } 関数 updateDirectives (oldVnode: VNodeWithData, vnode: VNodeWithData) { if (oldVnode.data.directives || vnode.data.directives) { _update(古いVnode、vnode) } } 関数_update(oldVnode, vnode) { const isCreate = oldVnode === 空のノード const isDestroy = vnode === 空のノード 定数 oldDirs = normalizeDirectives(oldVnode.data.directives、oldVnode.context) 定数 newDirs = normalizeDirectives(vnode.data.directives, vnode.context) // 挿入後のコールバック const dirsWithInsert = [ // 更新が完了した後のコールバック const dirsWithPostpatch = [] キー、oldDir、dir を入力します。 for (newDirsのキー) { oldDir = oldDirs[キー] dir = newDirs[キー] // 新しい要素の命令。挿入されたフックメソッドを 1 回実行します。if (!oldDir) { // 新しいディレクティブ、バインド callHook(dir, 'bind', vnode, oldVnode) dir.def が挿入されている場合 dirsWithInsert.push(dir) } } それ以外 { // 既存のディレクティブを更新 // 要素がすでに存在する場合、componentUpdatedフックメソッド dir.oldValue = oldDir.value が1回実行されます。 dir.oldArg = 古いDir.arg callHook(dir, 'update', vnode, oldVnode) dir.def がコンポーネント更新された場合 dirsWithPostpatch.push(dir) } } } (dirsWithInsert.length)の場合{ // 実際のDOMがページに挿入され、このコールバックメソッドが呼び出されます const callInsert = () => { (i = 0 とします; i < dirsWithInsert.length; i++) { callHook(dirsWithInsert[i], '挿入済み', vnode, oldVnode) } } // VNode マージ挿入フック if (isCreated) { mergeVNodeHook(vnode、'挿入'、callInsert) } それ以外 { 挿入()を呼び出す } } (dirsWithPostpatch.length)の場合{ mergeVNodeHook(vnode, 'postpatch', () => { (i = 0 とします; i < dirsWithPostpatch.length; i++) { callHook(dirsWithPostpatch[i], 'componentUpdated', vnode, oldVnode) } }) } 作成する場合 for (キー in oldDirs) { if (!newDirs[キー]) { // 存在しないので、バインドを解除します callHook(oldDirs[key], 'unbind', oldVnode, oldVnode, isDestroy) } } } } 初めて作成する場合の実行プロセスは次のとおりです。
通常、最初の作成には
コアコードは次のとおりです。 // src/core/vdom/patch.js 関数 patchVnode ( 古いVノード、 vノード、 挿入されたVnodeQueue、 所有者配列、 索引、 削除のみ ){ // ... 定数 oldCh = oldVnode.children 定数ch = vnode.children // ノード属性を完全に更新します if (isDef(data) && isPatchable(vnode)) { (i = 0; i < cbs.update.length; ++i) の場合、cbs.update[i](oldVnode, vnode) if (isDef(i = data.hook) && isDef(i = i.update)) i(oldVnode, vnode) } // ... if (isDef(データ)) { // postpatchフックを呼び出す if (isDef(i = data.hook) && isDef(i = i.postpatch)) i(oldVnode, vnode) } } unbind メソッドは、ノードが破棄されるときに 予防カスタム命令を使用する場合、v-model は通常のテンプレートデータバインディングとは異なります。たとえば、渡すパラメータ ( v-xxx='param' ) は参照型ですが、データが変更されたときに命令の bind または inserted をトリガーすることはできません。これは、命令の宣言サイクルで、bind と inserted は初期化時に 1 回だけ呼び出され、その後は ディレクティブの宣言ライフサイクルの実行順序は、 Vue では、フック メソッド、イベント コールバックなど、多くのメソッドがループで呼び出されます。通常、呼び出しは try catch で囲まれます。これは、処理メソッドがエラーを報告してプログラム全体がクラッシュするのを防ぐためです。これは、開発プロセスのリファレンスとして使用できます。 まとめVue のソースコード全体を見始めたときは、詳細や方法の多くが理解できませんでした。特定の機能ごとの実装を整理することで、徐々に Vue の全体像が見えてくると同時に、開発や使用における落とし穴を回避することができました。 GitHub 上記は、Vue ディレクティブの動作原理の実装方法の詳細な内容です。Vue ディレクティブの原理の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
<<: Ubuntu 18.04 に VMware Tools をインストールする際のエラーを解決する
>>: MySQLのinnodb_data_file_pathパラメータを変更する際の注意事項
序文JavaScript は、キーワードを使用してプライベート変数を宣言できる他の言語とは異なります...
ウェブサイトのアクセス速度を向上させるための徹底的な最適化に関するヒント。ウェブサイトのアクセス速度...
序文CSS を使用して点線を生成するのは、フロントエンド開発者にとっては簡単です。一般的に、これを実...
序文:場合によっては、MySQL に接続されたセッションが異常終了することが多く、エラー ログに「通...
事前に言っておく気まぐれですが、MySQL の order by sorting にどのようなルール...
ピクセル解決通常、モニター解像度と呼ばれるものは、実際にはモニターの物理的な解像度ではなく、デスクト...
目次開発環境ゲームエンジンのコンセプトCocos Creatorについてプロジェクト構造コード編集環...
123WORDPRESS.COM HTML チュートリアル セクションに戻るには、ここをクリックして...
Linux システムでは、環境変数は適用範囲に応じて、システムレベルの環境変数とユーザーレベルの環境...
Apache Tomcat は、Java Servlet および Java Server Pages...
1.前面に書きます:軽量仮想化テクノロジーとして、Docker には継続的インテグレーション、バージ...
目次1. 時計の新しい使い方1.1. ウォッチの使用構文1.2. 複数の属性値を監視する1.3. 参...
RDF と OWL は、2 つの重要なセマンティック ウェブ テクノロジーです。 RDF と OWL...
この記事では、vue+element-uiでヘッドナビゲーションバーコンポーネントを実装するための具...
質問: index.html で、iframe が son.html を導入します。son.html...