最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue?Proxy數(shù)據(jù)代理進(jìn)行校驗(yàn)部分源碼實(shí)例解析

 更新時(shí)間:2022年01月10日 14:29:42   作者:神奇大叔  
Proxy提供了強(qiáng)大的Javascript元編程,有許多功能,包括運(yùn)算符重載,對(duì)象模擬,簡(jiǎn)潔而靈活的API創(chuàng)建,對(duì)象變化事件,甚至Vue 3背后的內(nèi)部響應(yīng)系統(tǒng)提供動(dòng)力,這篇文章主要給大家介紹了關(guān)于vue?Proxy數(shù)據(jù)代理進(jìn)行校驗(yàn)部分源碼解析的相關(guān)資料,需要的朋友可以參考下

initProxy

數(shù)據(jù)攔截的思想除了為構(gòu)建響應(yīng)式系統(tǒng)準(zhǔn)備,它也可以為數(shù)據(jù)進(jìn)行篩選過(guò)濾,我們接著往下看初始化的代碼,在合并選項(xiàng)后,vue接下來(lái)會(huì)為vm實(shí)例設(shè)置一層代理,這層代理可以為vue在模板渲染時(shí)進(jìn)行一層數(shù)據(jù)篩選

Vue.prototype._init = function(options) {
    // 選項(xiàng)合并
    ...
    {
        // 對(duì)vm實(shí)例進(jìn)行一層代理
        initProxy(vm);
    }
    ...
}

initProxy

// 代理函數(shù)
var initProxy = function initProxy (vm) {
    //是否支持Proxy
    if (hasProxy) {
        var options = vm.$options;
        //當(dāng)使用類似webpack這樣的打包工具時(shí),通常會(huì)使用vue-loader插件進(jìn)行模板的編譯,這個(gè)時(shí)候options.render是存在的,并且_withStripped的屬性也會(huì)設(shè)置為true(關(guān)于編譯版本和運(yùn)行時(shí)版本的區(qū)別可以參考后面章節(jié)),所以此時(shí)代理的選項(xiàng)是hasHandler
        //在其他場(chǎng)景下,代理的選項(xiàng)是getHandler
        var handlers = options.render && options.render._withStripped
            ? getHandler
            : hasHandler;
        // 代理vm實(shí)例到vm屬性_renderProxy
        vm._renderProxy = new Proxy(vm, handlers);
    } else {
        vm._renderProxy = vm;
    }
};

hasProxy

var hasProxy =
      typeof Proxy !== 'undefined' && isNative(Proxy);

hasHandler

var hasHandler = {
    // key in obj或者with作用域時(shí),會(huì)觸發(fā)has的鉤子
    has: function has (target, key) {
        ···
    }
};

觸發(fā)代理

源碼中vm._renderProxy的使用出現(xiàn)在Vue實(shí)例的_render方法中,Vue.prototype._render是將渲染函數(shù)轉(zhuǎn)換成Virtual DOM的方法,這部分是關(guān)于實(shí)例的掛載和模板引擎的解析

當(dāng)我們調(diào)用render函數(shù)時(shí),代理的vm._renderProxy對(duì)象便會(huì)訪問(wèn)到

而這個(gè)render函數(shù)就是包裝成with的執(zhí)行語(yǔ)句,在執(zhí)行with語(yǔ)句的過(guò)程中,該作用域下變量的訪問(wèn)都會(huì)觸發(fā)has鉤子,這也是模板渲染時(shí)之所有會(huì)觸發(fā)代理攔截的原因

之所以會(huì)觸發(fā)數(shù)據(jù)代理攔截是因?yàn)槟0逯惺褂昧俗兞?,例?lt;div>{{message}}}

Vue.prototype._render = function () {
    ···
    // 調(diào)用vm._renderProxy
    vnode = render.call(vm._renderProxy, vm.$createElement);
}
=========================================
var vm = new Vue({
    el: '#app'     
})
console.log(vm.$options.render)
???????//輸出, 模板渲染使用with語(yǔ)句
? anonymous() {
    with(this){return _c('div',{attrs:{"id":"app"}},[_v(_s(message)+_s(_test))])}
}

數(shù)據(jù)過(guò)濾

通過(guò)data選項(xiàng)去設(shè)置實(shí)例數(shù)據(jù),那么這些數(shù)據(jù)可以隨著個(gè)人的習(xí)慣任意命名嗎?顯然不是的,如果你使用js的關(guān)鍵字(像Object,Array,NaN)去命名,這是不被允許的。另一方面,Vue源碼內(nèi)部使用了以$,_作為開頭的內(nèi)部變量,所以以$,_開頭的變量名也是不被允許的,這就構(gòu)成了數(shù)據(jù)過(guò)濾監(jiān)測(cè)的前提。

var hasHandler = {
    has: function has (target, key) {
        var has = key in target;
        // isAllowed用來(lái)判斷模板上出現(xiàn)的變量是否合法。
        var isAllowed = allowedGlobals(key) ||
            (typeof key === 'string' && key.charAt(0) === '_' && !(key in target.$data));
            // _和$開頭的變量不允許出現(xiàn)在定義的數(shù)據(jù)中,因?yàn)樗莢ue內(nèi)部保留屬性的開頭。
            
        // 1. warnReservedPrefix: 警告不能以$ _開頭的變量
        // 2. warnNonPresent: 警告模板出現(xiàn)的變量在vue實(shí)例中未定義
        //has判斷是否是target對(duì)象中的變量
        if (!has && !isAllowed) {
            if (key in target.$data) { warnReservedPrefix(target, key); }
            else { warnNonPresent(target, key); }
        }
        return has || !isAllowed
    }
};
// 模板中允許出現(xiàn)的非vue實(shí)例定義的變量
var allowedGlobals = makeMap(
    'Infinity,undefined,NaN,isFinite,isNaN,' +
    'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
    'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +
    'require' // for Webpack/Browserify
);

在瀏覽器不支持proxy的情況下的數(shù)據(jù)過(guò)濾

在沒(méi)有經(jīng)過(guò)代理的情況下,使用_開頭的變量依舊會(huì) 報(bào)錯(cuò),但是它變成了js語(yǔ)言層面的錯(cuò)誤。但是這個(gè)報(bào)錯(cuò)無(wú)法在Vue這一層知道錯(cuò)誤的詳細(xì)信息,而這就是能使用Proxy的好處。

在初始化數(shù)據(jù)階段,Vue已經(jīng)為數(shù)據(jù)進(jìn)行了一層篩選的代理。具體看initData對(duì)數(shù)據(jù)的代理

有了isReserved的篩選,即使this._data._test存在,我們依舊無(wú)法在訪問(wèn)this._test時(shí)拿到_test變量

function initData(vm) {
    vm._data = typeof data === 'function' ? getData(data, vm) : data || {}
    if (!isReserved(key)) {
        // 數(shù)據(jù)代理,用戶可直接通過(guò)vm實(shí)例獲取返回data數(shù)據(jù)
        proxy(vm, "_data", key);
    }
}

function isReserved (str) {
    var c = (str + '').charCodeAt(0);
    // 首字符是$, _的字符串
    return c === 0x24 || c === 0x5F
  }

proxy

function proxy (target, sourceKey, key) {
    sharedPropertyDefinition.get = function proxyGetter () {
        // 當(dāng)訪問(wèn)this[key]時(shí),會(huì)代理訪問(wèn)this._data[key]的值
        return this[sourceKey][key]
    };
    sharedPropertyDefinition.set = function proxySetter (val) {
        this[sourceKey][key] = val;
    };
    Object.defineProperty(target, key, sharedPropertyDefinition);
}

總結(jié) 

到此這篇關(guān)于vue Proxy數(shù)據(jù)代理進(jìn)行校驗(yàn)部分源碼解析的文章就介紹到這了,更多相關(guān)vue Proxy數(shù)據(jù)代理校驗(yàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue中使用iframe嵌入網(wǎng)頁(yè),頁(yè)面可自適應(yīng)問(wèn)題

    vue中使用iframe嵌入網(wǎng)頁(yè),頁(yè)面可自適應(yīng)問(wèn)題

    這篇文章主要介紹了vue中使用iframe嵌入網(wǎng)頁(yè),頁(yè)面可自適應(yīng)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vue3下watch的使用方法示例

    vue3下watch的使用方法示例

    vue3中的watch是一個(gè)組合式的API使用時(shí)需要引入,下面這篇文章主要給大家介紹了關(guān)于vue3下watch使用的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • vue阻止重復(fù)請(qǐng)求實(shí)現(xiàn)示例詳解

    vue阻止重復(fù)請(qǐng)求實(shí)現(xiàn)示例詳解

    這篇文章主要為大家介紹了vue阻止重復(fù)請(qǐng)求實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • vue實(shí)現(xiàn)滑動(dòng)和滾動(dòng)效果

    vue實(shí)現(xiàn)滑動(dòng)和滾動(dòng)效果

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)滑動(dòng)和滾動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Vue2響應(yīng)式系統(tǒng)之嵌套

    Vue2響應(yīng)式系統(tǒng)之嵌套

    這篇文章主要介紹了Vue響應(yīng)式系統(tǒng)之嵌套,我們?cè)陂_發(fā)中肯定存在組件嵌套組件的情況,下文將舉例說(shuō)明情況,需要的小伙伴可以參考一下
    2022-04-04
  • vue3中使用vuedraggable實(shí)現(xiàn)拖拽el-tree數(shù)據(jù)分組功能

    vue3中使用vuedraggable實(shí)現(xiàn)拖拽el-tree數(shù)據(jù)分組功能

    這篇文章主要介紹了vue3中使用vuedraggable實(shí)現(xiàn)拖拽el-tree數(shù)據(jù)分組功能,可以實(shí)現(xiàn)單個(gè)拖拽、雙擊添加、按住ctrl鍵實(shí)現(xiàn)多個(gè)添加,或者按住shift鍵實(shí)現(xiàn)范圍添加,添加到框中的數(shù)據(jù),還能拖拽排序,需要的朋友可以參考下
    2024-02-02
  • Vue標(biāo)簽屬性動(dòng)態(tài)傳參并拼接字符串的操作方法

    Vue標(biāo)簽屬性動(dòng)態(tài)傳參并拼接字符串的操作方法

    這篇文章主要介紹了Vue標(biāo)簽屬性動(dòng)態(tài)傳參并拼接字符串的操作方法,我們需要根據(jù)傳入值的類型,在placeholder屬性賦值"請(qǐng)輸入長(zhǎng)度",“請(qǐng)輸入寬度”,"請(qǐng)輸入厚度"等提示字符,本文通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友參考下吧
    2023-11-11
  • vue中實(shí)現(xiàn)div可編輯并插入指定元素與樣式

    vue中實(shí)現(xiàn)div可編輯并插入指定元素與樣式

    這篇文章主要給大家介紹了關(guān)于vue中實(shí)現(xiàn)div可編輯并插入指定元素與樣式的相關(guān)資料,文中通過(guò)代碼以及圖文將實(shí)現(xiàn)的方法介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • Vue編譯器AST抽象語(yǔ)法樹源碼分析

    Vue編譯器AST抽象語(yǔ)法樹源碼分析

    這篇文章主要為大家介紹了Vue編譯器AST抽象語(yǔ)法樹源碼分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • vue自定義穿梭框支持遠(yuǎn)程滾動(dòng)加載的實(shí)現(xiàn)方法

    vue自定義穿梭框支持遠(yuǎn)程滾動(dòng)加載的實(shí)現(xiàn)方法

    這篇文章主要介紹了vue自定義穿梭框支持遠(yuǎn)程滾動(dòng)加載,iview是全局注入,基本使用原先的類名進(jìn)行二次創(chuàng)建公共組件,修改基礎(chǔ)js實(shí)現(xiàn)邏輯,本文結(jié)合實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08

最新評(píng)論

湾仔区| 兴和县| 临高县| 隆昌县| 仲巴县| 海城市| 拜泉县| 项城市| 高州市| 南涧| 湖口县| 泾阳县| 布尔津县| 伽师县| 桃园县| 都安| 呼伦贝尔市| 北票市| 准格尔旗| 乐业县| 札达县| 牟定县| 资溪县| 阳西县| 名山县| 锦州市| 昂仁县| 逊克县| 安西县| 太和县| 墨竹工卡县| 武汉市| 仙游县| 射洪县| 东丽区| 沾化县| 吴江市| 洪江市| 安龙县| 渭源县| 旅游|