序文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 です。理論上、現在のスコープ チェーンにはテスト変数はありません。変数は、グローバル スコープが見つかるまで、前のスコープから検索されます。ただし、実際には _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); }, }); コードは非常にシンプルですが、なぜこのようなシンプルなコードで傍受が実現できるのでしょうか? ローカルプリコンパイルバージョン<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 の過去の記事を検索するか、以下の関連記事を引き続きご覧ください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 |
<<: Windows 環境での MySQL の解凍、インストール、バックアップ、復元
>>: ポートマッピング後に Docker コンテナが突然接続に失敗する問題のトラブルシューティング プロセス
1. 親divは疑似クラスafterとzoomを定義します <スタイル タイプ="...
よくある質問から議論を始めましょう。CSS を使用して要素の高さを [ブラウザ コンテンツ ウィンド...
ベースイメージベースイメージには 2 つの意味があります。他のイメージに依存せず、ゼロから構築します...
Nginx はバージョン番号を非表示にする実稼働環境では、セキュリティ上の脆弱性の漏洩を避けるために...
最近、友人が私に質問をしました。ページをレイアウトすると、画像の下に 1 ~ 2 ピクセルの空白があ...
システムヘルプを表示help contents mysql> ヘルプコンテンツ; ヘルプ カテ...
目次BOM (ブラウザ オブジェクト モデル) 1. ウィンドウブラウザのウィンドウサイズを取得する...
MySQL では、IF()、IFNULL()、NULLIF()、および ISNULL() 関数を使用...
問題の説明最近、ホストから次のカーネル情報が報告されました。 7月8日 10:47:42 cztes...
目次1. エラー現象2. エラー分析3. エラー解決1. エラー現象仮想マシンでLVGLエミュレータ...
問題:あるサーバー上の PHP プログラムは、localhost アドレス経由でデータベースに接続で...
1. Logrotateツールの紹介Logrotate はログファイル管理ツールです。Linux に...
トムキャット公式サイトtomcatはローカルサーバーと同等であり、Webページを開くことができます設...
この記事では、例を使用して、MySQL ストアド プロシージャの概念、原則、および一般的な使用法につ...
<base> タグは、ページ上のすべてのリンクのデフォルトのアドレスまたはデフォルトの...