1. v-bindの主要ソースコードの分析1. v-bind属性はどこに均一に保存されるか: attrsMapとattrsList<p v-bind:title="vBindTitle"></p> p タグの この HTML タグを取得した後、Vue は title 属性を処理し、次の手順を実行します。
作成後に 2. HTMLを解析し、属性セットattrsを解析して、開始コールバックで返します。関数handleStartTag(一致){ ... 定数 l = マッチ.属性.長さ const attrs = 新しい配列(l) (i = 0; i < l; i++ とします) { 定数args = match.attrs[i] ... 属性[i] = { 名前: 引数[1], 値: decodeAttr(値、shouldDecodeNewlines) } } ... if (オプション.開始) { // ここで開始関数にアップロードします options.start(tagName, attrs, unary, match.start, match.end) } } 3. 開始コールバックで ASTElement を作成します (createASTElement(... ,attrs, ...))// HTML の解析 parseHTML(テンプレート、{ ... 開始(タグ、属性、単項、開始、終了) { let element: ASTElement = createASTElement(tag, attrs, currentParent) // ここでの attrs に注意してください } }) 4. 作成後、ASTElementはattrsListとattrsMapを生成します。// AST要素エクスポート関数createASTElement (を作成する タグ: 文字列、 attrs: Array<ASTAttr>, // 属性オブジェクト配列 parent: ASTElement | void // 親要素も ASTElement です ): ASTElement { // ASTElementを返す 戻る { タイプ: 1, タグ、 attrsList: attrs、 attrsMap: makeAttrsMap(attrs)、 生の属性マップ: {}, 親、 子供たち: [] } } 5. attrsのデータ型定義//ASTAttr属性抽象構文木オブジェクトデータ型を宣言するdeclare type ASTAttr = { name: string; // 属性名value: any; // 属性値dynamic?: boolean; // 動的な属性かどうかstart?: number; 終了?: 番号 }; 6. バインディング属性取得関数バインディング属性取得関数 getBindingAttr と属性操作関数 getAndRemoveAttr エクスポート関数 getBindingAttr ( el: AST要素、 名前: 文字列、 getStatic?: ブール値 ): ?弦 { 定数動的値 = getAndRemoveAttr(el, ':' + 名前) || getAndRemoveAttr(el, 'v-bind:' + 名前) 動的値 != null の場合 parseFilters(dynamicValue) を返す } そうでない場合 (getStatic !== false) { const staticValue = getAndRemoveAttr(el, 名前) 静的値 != null の場合 { JSON.stringify(staticValue) を返す } } } // 注意: これは配列(attrsList)から属性のみを削除するので、 // processAttrs によって処理されません。 // デフォルトではマップ(attrsMap)から削除されません。マップは // コード生成中に必要です。 エクスポート関数 getAndRemoveAttr ( el: AST要素、 名前: 文字列、 マップから削除しますか?: ブール値 ): ?弦 { valを el.attrsMap[name] が null の場合 定数リスト = el.attrsList (i = 0, l = list.length; i < l; i++) の場合 { if (リスト[i].name === name) { list.splice(i, 1) // attrsList から属性を削除しますが、attrsMap から break は削除されません } } } if (マップから削除) { el.attrsMap[名前]を削除します } 戻り値 } 2. v-bindの値を取得する方法次のコードを例にして、 いくつかのシーンを書き出して分析してみます。
vBind:{ キー: +新しい日付()、 タイトル: "これは HTML 属性 v-bind です", クラス: "{ borderRadius: isBorderRadius }" スタイル: "{ minHeight: 100 + 'px' , maxHeight}" テキストコンテンツ: "hello vue v-bind" } <div v-bind:key="vBind.key" v-bind:title="vBind.title" v-bind:class="vBind.class" v-bind:style="vBind.style" v-bind:text-content.prop="vBind.textContent" /> </div> 1. v-bind:key ソースコード分析関数 processKey (el) { const exp = getBindingAttr(el, 'キー') if(式){ ... el.key = exp; } }
2. v-bind:title ソースコード分析
関数 processAttrs(el){ const リスト = el.attrsList; ... if (bindRE.test(name)) { // v-bind 名前 = 名前.replace(bindRE, '') 値 = parseFilters(値) ... addAttr(el, 名前, 値, リスト[i], ...) } } エクスポート const bindRE = /^:|^\.|^v-bind:/ エクスポート関数 addAttr(el: ASTElement、名前: 文字列、値: 任意、範囲?: 範囲、動的?: ブール値) { const attrs = 動的 ? (el.dynamicAttrs || (el.dynamicAttrs = [])) : (el.attrs || (el.attrs = [])) attrs.push(rangeSetItem({ 名前、値、動的 }、範囲)) el.plain = 偽 } ソースコードを読むと、title などのネイティブ属性の場合、vue は最初に 3. v-bind:class ソースコード分析
関数 transformNode (el: ASTElement, オプション: CompilerOptions) { const 警告 = options.warn || baseWarn const staticClass = getAndRemoveAttr(el, 'class') if (静的クラス) { el.staticClass = JSON.stringify(staticClass) } const classBinding = getBindingAttr(el, 'class', false /* getStatic */) if (クラスバインディング) { el.classBinding = クラスバインディング } }
4. v-bind:style ソースコード解析スタイルは、スタイルを直接操作する 関数 transformNode (el: ASTElement, オプション: CompilerOptions) { const 警告 = options.warn || baseWarn const staticStyle = getAndRemoveAttr(el, 'style') 静的スタイルの場合{ el.staticStyle = JSON.stringify(parseStyleText(staticStyle)) } const styleBinding = getBindingAttr(el, 'style', false /* getStatic */) if (スタイルバインディング) { el.styleBinding = スタイルバインディング } }
5. v-bind:text-content.prop ソースコード分析
ソースコードを見てみましょう。 関数 processAttrs(el) { 定数リスト = el.attrsList ... if (bindRE.test(name)) { // v-bind if (修飾子) { modifiers.prop が !isDynamic の場合 { 名前 = キャメル化(名前) if (name === 'innerHtml') name = 'innerHTML' } } if (modifiers && modifiers.prop) { addProp(el, 名前, 値, リスト[i], isDynamic) } } } エクスポート関数 addProp (el: ASTElement、名前: 文字列、値: 文字列、範囲?: 範囲、動的?: ブール値) { (el.props || (el.props = [])).push(rangeSetItem({ 名前、値、動的 }、範囲)) el.plain = 偽 } プロパティ?: Array<ASTAttr>; 上記のソースコードから、 考えてみる価値のある疑問があります。なぜこれをするのでしょうか? HTML 属性との類似点と相違点は何ですか?
6. v-bind modifier.camel.sync ソースコード分析. 実際、.sync 修飾子を初めて見たとき、私は戸惑いましたが、コンポーネントの .sync を注意深く読み、実際の作業と組み合わせることで、その威力がわかりました。 <親 v-bind:foo="parent.foo" v-on:updateFoo="parent.foo = $event" </親> Vue では、親コンポーネントから子コンポーネントに渡される もっと簡潔に書く方法はありますか? ? ? それがここにある .sync 演算子です。 次のように短縮できます。 <親 v-bind:foo.sync="parent.foo"></親> 次に、 ソースコードを見てみましょう: (modifiers.camel && !isDynamic)の場合{ 名前 = キャメル化(名前) } (modifiers.sync)の場合{ syncGen = genAssignmentCode(値、`$event`) if (!isDynamic) { addHandler(el,`update:${camelize(name)}`,syncGen,null,false,warn,list[i]) // Hyphenate はハイフネーション関数で、camelize はキャメルケース関数です。if (hyphenate(name) !== camelize(name)) { addHandler(el,`update:${hyphenate(name)}`,syncGen,null,false,warn,list[i]) } } それ以外 { // 動的イベント名を持つハンドラー addHandler(el,`"update:"+(${name})`,syncGen,null,false,warn,list[i],true) } } ソースコードを読むと、次のことがわかります。 これで、vue の v-bind を理解するためのこの記事は終わりです。vue の v-bind に関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、次の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: Tomcat をサービスとして登録する際に注意すべき点のまとめ
>>: Linux でファイルを削除するさまざまな方法の効率の比較
マイグレーションアドバンテージ:小型、高速、総所有コストが低い、オープンソース。複数のオペレーティン...
この記事では、WeChatミニプログラムのビデオ弾幕の位置をランダム化するための具体的なコードを紹介...
目次1. 要素の表示と非表示を制御する show() hide() 2. 要素の透明度を制御する f...
CSS3 カテゴリ メニューの効果は次のとおりです。 html <html> <ヘ...
この記事では、要素をドラッグするときにプレビューを追加する小さなデモを紹介します。効果は次のとおりで...
1. MySQLに接続するフォーマット: mysql -h ホストアドレス -u ユーザー名 -p ...
1. ウェブページの基本構造: XML/HTML コードコンテンツをクリップボードにコピー<...
これを応用することで、ウェブサイトの一部の公開領域を独立したページにすることができ、その後、この技術...
入力サブシステムフレームワークLinux 入力サブシステムは、上から下に向かって、入力サブシステム ...
序文WeChat アプレットでは、App.js の globalData を中間ブリッジとして使用し...
序文現在、私の会社で使用しているオペレーティングシステムはすべて CentOS7.4 で、アプリケー...
目次概要1. 簡単な例1.サブコンポーネントの<ng-content>ディレクティブを使...
MySQL でカーソルを宣言する方法: 1. 変数とカーソルを宣言する 結果をvarchar(300...
この記事では主に、NUXT の validate メソッドに基づいてフォーム検証を実装する方法につい...
Dockerデーモンのアクセラレータを構成する設定ファイルから Docker を起動し、/etc/d...