序文vue3サンドボックスには主に2つの種類があります
ブラウザコンパイル版レンダリング関数のコンパイル結果 <div>{{テスト}}</div> <div>{{Math.floor(1)}}</div> に Vue を継承します。 関数 render(_ctx, _cache, $props, $setup, $data, $options) を返します { (_ctx) で{ 定数{ 表示文字列: _表示文字列、 作成VNode: _createVNode、 フラグメント: _Fragment、 オープンブロック: _openBlock, ブロックの作成: _createBlock、 } = _Vue; 戻る ( _openBlock(), _createブロック( _断片、 ヌル、 [ _createVNode("div", null, _toDisplayString(test), 1 /* テキスト */), _createVNode( "div", ヌル、 _toDisplayString(Math.floor(1))、 1 /* テキスト */ )、 ]、 64 /* 安定フラグメント */ ) ); } }; 上記のコードから、変数識別子にプレフィックスが追加されておらず、スコープ チェーンを拡張するために with 構文でラップされているだけであることがわかります。では、js サンドボックス インターセプションはどのように実現されるのでしょうか。たとえば、変数 test です。理論的には、現在のスコープ チェーンには test 変数はありません。変数は、グローバル スコープが見つかるまで、前のスコープから検索されます。ただし、実際には、_ctx でのみ検索されます。原理は非常に単純です。_ctx はプロキシ オブジェクトです。では、Proxy を使用してインターセプトするにはどうすればよいでしょうか。サンプル コードは次のとおりです。 定数 GLOBALS_WHITE_LISTED = 「無限大、未定義、NaN、isFinite、isNaN、parseFloat、parseInt、decodeURI」+ 「decodeURIComponent、encodeURI、encodeURIComponent、Math、Number、Date、Array」+ "オブジェクト、ブール値、文字列、正規表現、マップ、セット、JSON、Intl、BigInt"; const isGloballyWhitelisted = (キー) => { GLOBALS_WHITE_LISTED.split(",").includes(key); を返します。 }; const hasOwn = (obj, キー) => { Object.prototype.hasOwnProperty.call(obj, key) を返します。 }; 定数 origin = {}; const _ctx = 新しいプロキシ(origin, { get(ターゲット、キー、受信者) { if (hasOwn(ターゲット、キー)) { Reflect.get(ターゲット、キー、レシーバー); } それ以外 { コンソール.警告( `レンダリング中にプロパティ ${JSON.stringify(key)} がアクセスされました ` + `ただし、インスタンスでは定義されていません。` ); } }, has(ターゲット, キー) { // グローバル オブジェクトの場合は false を返し、get インターセプションをトリガーせず、前のスコープから変数を検索します。// グローバル オブジェクトでない場合は true を返し、get インターセプションをトリガーします。 return !isGloballyWhitelisted(key); }, }); コードは非常にシンプルですが、なぜこのようなシンプルなコードで傍受が実現できるのでしょうか? with ステートメントは has インターセプションをトリガーするため、has が true を返すと、プロキシ オブジェクトの get インターセプションがトリガーされます。false を返すと、プロキシ オブジェクトの get インターセプションはトリガーされず、変数は現在のプロキシ オブジェクトで検索されず、上位スコープで直接検索されます。 ローカルプリコンパイルバージョン<div>{{テスト}}</div> <div>{{Math.floor(1)}}</div> に 輸入 { toDisplayString を _toDisplayString として、 createVNode を _createVNode として、 フラグメントとしての_Fragment、 openBlock を _openBlock として、 createBlock を _createBlock として、 } から "vue" へ; エクスポート関数 render(_ctx, _cache, $props, $setup, $data, $options) { 戻る ( _openBlock(), _createブロック( _断片、 ヌル、 [ _createVNode("div", null, _toDisplayString(_ctx.a), 1 /* テキスト */), _createVNode( "div", ヌル、 _toDisplayString(Math.floor(1))、 1 /* テキスト */ )、 ]、 64 /* 安定フラグメント */ ) ); } 上記のコードから、ホワイトリストに含まれない識別子には _ctx 変数がプレフィックスとして付けられていることがわかります。では、これはどのように行われるのでしょうか?テンプレートをローカルでコンパイルすると、変換フェーズ中に変数式ノード NodeTypes.SIMPLE_EXPRESSION がプレフィックスとして付加されます。サンプル コードは次のとおりです。 定数 GLOBALS_WHITE_LISTED = 「無限大、未定義、NaN、isFinite、isNaN、parseFloat、parseInt、decodeURI」+ 「decodeURIComponent、encodeURI、encodeURIComponent、Math、Number、Date、Array」+ "オブジェクト、ブール値、文字列、正規表現、マップ、セット、JSON、Intl、BigInt"; const isGloballyWhitelisted = (キー) => { GLOBALS_WHITE_LISTED.split(",").includes(key); を返します。 }; const isLiteralWhitelisted = (キー)=>{ 'true,false,null,this'.split(',').includes(key) を返します。 } エクスポート関数 processExpression( ノード ){ const rewriteIdentifier = (raw) => { `_ctx.${raw}` を返す } 定数rawExp = ノード.content if (isSimpleIdentifier(rawExp)) { const isAllowedGlobal = isGloballyWhitelisted(rawExp) 定数 isLiteral = isLiteralWhitelisted(rawExp) if (!isAllowedGlobal && !isLiteral) { ノードのコンテンツ = rewriteIdentifier(rawExp) } 戻りノード } もちろん、上記のコードは簡略化されたバージョンにすぎません。元のプラグインでは、__props $setup を正確にしたり、変数クエリパスを短縮したり、パフォーマンスを向上させたり、矢印関数などの複雑な式を babel 経由でコンパイルしたりもしています。 要約するvue3 js サンドボックスのメカニズム全体が説明されています。ブラウザーでコンパイルされたバージョンは、ステートメント変数クエリでインターセプトできることを知らなかったため、長い間私を悩ませていました。 以上がvue3のサンドボックスの仕組みの詳しい説明です。vue3のサンドボックスの仕組みについてさらに詳しく知りたい方は、123WORDPRESS.COM内の他の関連記事もぜひご覧ください! 以下もご興味があるかもしれません:
|
>>: MySQL で浮動小数点データを文字データに変換するときに起こりうる問題の詳細な説明
テキストシャドウテキストシャドウ: 水平オフセット 垂直オフセット ぼかし色互換性: IE10+ &...
目次背景メインコンテンツ1. コンポーネントの比較2. 実装のアイデア3. キーメソッドソースコード...
この記事では、例を使用して、MySQL の非主キーの自己増分の使用方法を説明します。ご参考までに、詳...
序文:インターネット技術の継続的な発展に伴い、MySQL 関連のエコシステムはますます充実し、ますま...
私のは: <!DOCTYPE html>ブログガーデン: <!DOCTYPE HT...
目次1. 概要1. 原則2. 実装3. スレーブインスタンスを作成する4. マスタースレーブ構成要約...
1. まずパゴダを設置するインストール要件: Python バージョン: 2.6/2.7 (Pago...
プログラマーが日常的に TypeScript/JavaScript 開発を行う場合、複雑な Java...
方法1: SET PASSWORDコマンドを使用するまずMySQLにログインします。フォーマット: ...
主な機能は次のとおりです。製品情報を追加する製品情報を変更する単一の製品を削除する複数の製品を削除す...
目次序文記述子getとsetの詳細な説明オブジェクトの属性の乗っ取りオブジェクトのすべてのプロパティ...
画像をプルする root@EricZhou-MateBookProX: docker pull je...
CentOS 8 がリリースされてから随分経ちました。Linux 仮想マシンをいじっている人間として...
序文このチュートリアルでは最新バージョンをインストールします。 NAS は非常に安定して動作するので...
目次DOMContentLoadedとロードjs ブロッキングとは何ですか? CSS ブロッキングと...