序文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 コンテナが突然接続に失敗する問題のトラブルシューティング プロセス
目次序文最初のステップ:ステップ2: このmy.iniを変更する要約する序文問題の説明:不正な文字列...
この記事では、例を使用して、MySQL イベントの変更 (ALTER EVENT)、イベントの無効化...
目次1. はじめに2. 利点3. 使用手順1. Vuexをインストールする2. Vuexを参照する3...
この記事では、全選択または選択を反転する機能を実現するためのJavaScriptの具体的なコードを参...
一部の Web ページは大きく見えなくても開くのに非常に時間がかかる場合があります。一方、他の We...
この記事では、参考までに、NFC読み取り機能を実装するためのuni-appの具体的なコードを紹介しま...
CSS 3.0 とビデオを組み合わせて実現したクリエイティブなオープニングをご紹介します。効果は次の...
MySQLのインストール(4、5、6は省略可能)ステートメント: CentOS のバージョンは 7....
1. 問題の紹介ユーザー テーブルに 3 つのフィールドが含まれているシナリオを想定します。 id、...
最近、仕事中に問題が発生しました。Docker コンテナがホストの redis にアクセスできず、t...
CentOS7 のデフォルトのデータベースは mariadb ですが、mysql を使っている人も多...
序文: Vue プロジェクトで現在のマウスの座標を取得するにはどうすればよいでしょうか。ここで共有す...
目次1. フォームイベント2. マウスイベント3. キーボードイベント4. 共通イベントメソッド(ウ...
Docker の導入規模が大きくなると、コンテナを監視する必要があります。一般的に、Docker に...
<br />前のチュートリアル:Webデザインチュートリアル(2):模倣と盗作について。...