激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務(wù)器之家 - 編程語(yǔ)言 - JavaScript - vue.js - 詳解vue3沙箱機(jī)制

詳解vue3沙箱機(jī)制

2022-03-03 16:34不知道寫啥筆名 vue.js

這篇文章主要介紹了詳解vue3 沙箱機(jī)制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

vue3 沙箱主要分兩種

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

瀏覽器編譯版本

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

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

to

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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做攔截,示例代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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ù)編譯版本

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

to

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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)行添加前綴處理,示例代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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,減短變量查詢路徑,提高性能,還有通過(guò)babel編譯復(fù)雜表達(dá)式比如:箭頭函數(shù)。

總結(jié)

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

參考

Proxy handler.has
說(shuō)說(shuō) JS 中的沙箱
動(dòng)手寫 js 沙箱

 到此這篇關(guān)于詳解vue3 沙箱機(jī)制的文章就介紹到這了,更多相關(guān)vue3 沙箱機(jī)制內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://juejin.cn/post/6950969989608243231

延伸 · 閱讀

精彩推薦
  • vue.js用vite搭建vue3應(yīng)用的實(shí)現(xiàn)方法

    用vite搭建vue3應(yīng)用的實(shí)現(xiàn)方法

    這篇文章主要介紹了用vite搭建vue3應(yīng)用的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下...

    Asiter7912022-01-22
  • vue.js詳解vue 表單綁定與組件

    詳解vue 表單綁定與組件

    這篇文章主要介紹了vue 表單綁定與組件的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下...

    Latteitcjz6432022-02-12
  • vue.jsVue中引入svg圖標(biāo)的兩種方式

    Vue中引入svg圖標(biāo)的兩種方式

    這篇文章主要給大家介紹了關(guān)于Vue中引入svg圖標(biāo)的兩種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的...

    十里不故夢(mèng)10222021-12-31
  • vue.jsVue項(xiàng)目中實(shí)現(xiàn)帶參跳轉(zhuǎn)功能

    Vue項(xiàng)目中實(shí)現(xiàn)帶參跳轉(zhuǎn)功能

    最近做了一個(gè)手機(jī)端系統(tǒng),其中遇到了父頁(yè)面需要攜帶參數(shù)跳轉(zhuǎn)至子頁(yè)面的問(wèn)題,現(xiàn)已解決,下面分享一下實(shí)現(xiàn)過(guò)程,感興趣的朋友一起看看吧...

    YiluRen丶4302022-03-03
  • vue.jsVue多選列表組件深入詳解

    Vue多選列表組件深入詳解

    這篇文章主要介紹了Vue多選列表組件深入詳解,這個(gè)是vue的基本組件,有需要的同學(xué)可以研究下...

    yukiwu6752022-01-25
  • vue.jsVue2.x 項(xiàng)目性能優(yōu)化之代碼優(yōu)化的實(shí)現(xiàn)

    Vue2.x 項(xiàng)目性能優(yōu)化之代碼優(yōu)化的實(shí)現(xiàn)

    這篇文章主要介紹了Vue2.x 項(xiàng)目性能優(yōu)化之代碼優(yōu)化的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋...

    優(yōu)小U9632022-02-21
  • vue.jsVue2.x-使用防抖以及節(jié)流的示例

    Vue2.x-使用防抖以及節(jié)流的示例

    這篇文章主要介紹了Vue2.x-使用防抖以及節(jié)流的示例,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下...

    Kyara6372022-01-25
  • vue.js梳理一下vue中的生命周期

    梳理一下vue中的生命周期

    看過(guò)很多人講vue的生命周期,但總是被繞的云里霧里,尤其是自學(xué)的同學(xué),可能js的基礎(chǔ)也不是太牢固,聽起來(lái)更是吃力,那我就已個(gè)人之淺見,以大白話...

    CRMEB技術(shù)團(tuán)隊(duì)7992021-12-22
主站蜘蛛池模板: 国产三级午夜理伦三级 | 红杏网站永久免费视频入口 | 免费观看一级淫片 | 国产免费大片视频 | 蜜桃视频观看麻豆 | 本站只有精品 | 免费观看欧美一级片 | 色骚综合 | 成人国产精品久久久 | 亚洲第一页中文字幕 | www.狠狠插.com| 澳门一级淫片免费视频 | 亚洲精品一区国产精品丝瓜 | 72pao成人国产永久免费视频 | 欧美成人一区二区三区 | 美女亚洲 | 黄色免费网站在线播放 | 国产69精品久久久久9999不卡免费 | 成人毛片在线免费观看 | 久久αv | 视频一区二区三区在线播放 | 极品销魂一区二区三区 | 日本网站一区 | 国产免费黄色 | 国产高潮失禁喷水爽到抽搐视频 | 亚洲午夜久久久久 | 爽爽淫人综合网网站 | 亚洲综合视频在线播放 | 日韩午夜一区二区三区 | 午夜视频你懂的 | 亚洲欧美爱爱 | 久久精品污 | 国产高清美女一级毛片 | 特色一级黄色片 | 羞羞视频免费入口网站 | 久久人体 | 久久99国产精品二区护士 | 久久精品视频网址 | 小雪奶水翁胀公吸小说最新章节 | 午夜精品在线视频 | 国产精品久久久久久久久久免 |