亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解vue3的沙箱機(jī)制

 更新時(shí)間:2021年04月15日 10:19:32   作者:不知道寫(xiě)啥筆名  
這篇文章主要介紹了vue3的沙箱機(jī)制的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下

前言

vue3 沙箱主要分兩種

  1. 瀏覽器編譯版本,瀏覽器版本是使用with語(yǔ)法加上proxy代理攔截
  2. 本地預(yù)編譯版本,通過(guò)在模版預(yù)編譯階段轉(zhuǎn)換階段,使用轉(zhuǎn)換插件transformExpression將非白名單標(biāo)識(shí)符掛在在組件代理對(duì)象下

瀏覽器編譯版本

render 函數(shù)編譯結(jié)果

<div>{{test}}</div>
<div>{{Math.floor(1)}}</div>

to

const _Vue = Vue;

return function render(_ctx, _cache, $props, $setup, $data, $options) {
  with (_ctx) {
    const {
      toDisplayString: _toDisplayString,
      createVNode: _createVNode,
      Fragment: _Fragment,
      openBlock: _openBlock,
      createBlock: _createBlock,
    } = _Vue;

    return (
      _openBlock(),
      _createBlock(
        _Fragment,
        null,
        [
          _createVNode("div", null, _toDisplayString(test), 1 /* TEXT */),
          _createVNode(
            "div",
            null,
            _toDisplayString(Math.floor(1)),
            1 /* TEXT */
          ),
        ],
        64 /* STABLE_FRAGMENT */
      )
    );
  }
};

從上面的代碼,我們能發(fā)現(xiàn),變量標(biāo)識(shí)符沒(méi)有增加前綴,只是用with語(yǔ)法包裹了一下,延長(zhǎng)作用域鏈,那么是如何做到 js 沙箱攔截的呢?例如變量test, 理論上說(shuō),當(dāng)前作用域鏈沒(méi)有test變量,變量會(huì)從上一層作用域查找,直到查找到全局作用域,但是,實(shí)際上只會(huì)在_ctx上查找, 原理很簡(jiǎn)單,_ctx是一個(gè)代理對(duì)象,那么我們?nèi)绾问褂肞roxy做攔截,示例代碼如下:

const GLOBALS_WHITE_LISTED =
  "Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI," +
  "decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array," +
  "Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt";

const isGloballyWhitelisted = (key) => {
  return GLOBALS_WHITE_LISTED.split(",").includes(key);
};

const hasOwn = (obj, key) => {
  return Object.prototype.hasOwnProperty.call(obj, key);
};

const origin = {};
const _ctx = new Proxy(origin, {
  get(target, key, reciever) {
    if (hasOwn(target, key)) {
      Reflect.get(target, key, reciever);
    } else {
      console.warn(
        `Property ${JSON.stringify(key)} was accessed during render ` +
          `but is not defined on instance.`
      );
    }
  },
  has(target, key) {
    // 如果是 全局對(duì)象 返回false,不觸發(fā)get 攔截,從上一層作用域查找變量
    // 如果不是 全局對(duì)象 返回true,觸發(fā)get 攔截
    return !isGloballyWhitelisted(key);
  },
});

代碼很簡(jiǎn)單,為什么這么簡(jiǎn)單的代碼就能做到攔截? 因?yàn)?with 語(yǔ)句會(huì)觸發(fā) has 攔截,當(dāng) has 返回 true,就會(huì) 觸發(fā)代理對(duì)象 get 攔截,如果返回 false, 則代理對(duì)象 get 攔截不會(huì)觸發(fā),變量不在當(dāng)前代理對(duì)象查找,直接查找更上一層作用域

本地預(yù)編譯版本

<div>{{test}}</div>
<div>{{Math.floor(1)}}</div>

to

import {
  toDisplayString as _toDisplayString,
  createVNode as _createVNode,
  Fragment as _Fragment,
  openBlock as _openBlock,
  createBlock as _createBlock,
} from "vue";

export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (
    _openBlock(),
    _createBlock(
      _Fragment,
      null,
      [
        _createVNode("div", null, _toDisplayString(_ctx.a), 1 /* TEXT */),
        _createVNode(
          "div",
          null,
          _toDisplayString(Math.floor(1)),
          1 /* TEXT */
        ),
      ],
      64 /* STABLE_FRAGMENT */
    )
  );
}

從上面的代碼我們可以發(fā)現(xiàn),非白名單標(biāo)識(shí)符都添加了_ctx 變量前綴,那么是如何做到的呢?當(dāng)本地編譯 template 時(shí),處于轉(zhuǎn)換階段時(shí)會(huì)對(duì) 變量表達(dá)式節(jié)點(diǎn)NodeTypes.SIMPLE_EXPRESSION進(jìn)行添加前綴處理,示例代碼如下:

const GLOBALS_WHITE_LISTED =
  "Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI," +
  "decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array," +
  "Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt";

const isGloballyWhitelisted = (key) => {
  return GLOBALS_WHITE_LISTED.split(",").includes(key);
};
const isLiteralWhitelisted = (key)=>{
  return 'true,false,null,this'.split(',').includes(key)
}
export function processExpression(
  node
) {
  const rewriteIdentifier = (raw) => {
    return `_ctx.${raw}`
  }
  const rawExp = node.content
  if (isSimpleIdentifier(rawExp)) {
    const isAllowedGlobal = isGloballyWhitelisted(rawExp)
    const isLiteral = isLiteralWhitelisted(rawExp)
    if (!isAllowedGlobal && !isLiteral) {
      node.content = rewriteIdentifier(rawExp)
    }
    return node
  }

當(dāng)然上面的代碼只是簡(jiǎn)化版本,原版插件還做了精確到了__props $setup,減短變量查詢(xún)路徑,提高性能,還有通過(guò)babel編譯復(fù)雜表達(dá)式比如:箭頭函數(shù)。

總結(jié)

整個(gè) vue3 js 沙箱機(jī)制就解釋結(jié)束了,當(dāng)初瀏覽器編譯版本困擾了我很久,因?yàn)椴恢?has 可以攔截 with 語(yǔ)句變量查詢(xún)

以上就是詳解vue3的沙箱機(jī)制的詳細(xì)內(nèi)容,更多關(guān)于vue3 沙箱機(jī)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 利用vue3+ts實(shí)現(xiàn)管理后臺(tái)(增刪改查)

    利用vue3+ts實(shí)現(xiàn)管理后臺(tái)(增刪改查)

    這篇文章主要介紹了利用vue3+ts實(shí)現(xiàn)管理后臺(tái)(增刪改查),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Vue項(xiàng)目中解決數(shù)字精度丟失問(wèn)題

    Vue項(xiàng)目中解決數(shù)字精度丟失問(wèn)題

    我們知道,浮點(diǎn)類(lèi)型的數(shù)據(jù),在計(jì)算機(jī)中是以二進(jìn)制的方式存儲(chǔ)的,但是表示的數(shù)據(jù)也有個(gè)上限和下限,當(dāng)超過(guò)限制?,在計(jì)算機(jī)上顯示只能取最接近的限值,?數(shù)字解析精度丟失說(shuō)的就是這個(gè)現(xiàn)象,所以本文給大家介紹了Vue項(xiàng)目中解決數(shù)字精度丟失問(wèn)題的解決,需要的朋友可以參考下
    2024-02-02
  • Vue3 的響應(yīng)式和以前有什么區(qū)別,Proxy 無(wú)敵?

    Vue3 的響應(yīng)式和以前有什么區(qū)別,Proxy 無(wú)敵?

    這篇文章主要介紹了Vue3 的響應(yīng)式和以前有什么區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • 淺談Vue的加載順序探討

    淺談Vue的加載順序探討

    本篇文章主要介紹了Vue的加載順序探討,詳細(xì)的介紹了加載順序以及如何判斷所有的子組件加載完成。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • vue用FileSaverJs導(dǎo)出文件

    vue用FileSaverJs導(dǎo)出文件

    FileSaver.js?是在客戶(hù)端保存文件的解決方案,非常適合?在客戶(hù)端上生成文件的?Web?應(yīng)用,它是?HTML5?版本的?saveAs()?FileSaver?實(shí)現(xiàn),這篇文章主要介紹了vue用FileSaverJs導(dǎo)出文件,需要的朋友可以參考下
    2023-09-09
  • vue+antd實(shí)現(xiàn)折疊與展開(kāi)組件

    vue+antd實(shí)現(xiàn)折疊與展開(kāi)組件

    這篇文章主要為大家詳細(xì)介紹了vue+antd實(shí)現(xiàn)折疊與展開(kāi)組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • 從Echarts報(bào)錯(cuò)中學(xué)習(xí)Vue3?ref和shallowRef區(qū)別及其組件二次封裝demo

    從Echarts報(bào)錯(cuò)中學(xué)習(xí)Vue3?ref和shallowRef區(qū)別及其組件二次封裝demo

    這篇文章主要介紹了從Echarts報(bào)錯(cuò)中學(xué)習(xí)Vue3?ref和shallowRef區(qū)別及其組件二次封裝demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Vue使用Element折疊面板Collapse如何設(shè)置默認(rèn)全部展開(kāi)

    Vue使用Element折疊面板Collapse如何設(shè)置默認(rèn)全部展開(kāi)

    這篇文章主要介紹了Vue使用Element折疊面板Collapse如何設(shè)置默認(rèn)全部展開(kāi),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • Vue出現(xiàn)did you register the component correctly?解決方案

    Vue出現(xiàn)did you register the component 

    這篇文章主要介紹了Vue出現(xiàn)did you register the component correctly?解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 使用webstorm配置vue+element開(kāi)發(fā)環(huán)境

    使用webstorm配置vue+element開(kāi)發(fā)環(huán)境

    這篇文章主要介紹了使用webstorm配置vue+element開(kāi)發(fā)環(huán)境,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10

最新評(píng)論