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

Vue2?響應式系統(tǒng)之深度響應

 更新時間:2022年04月12日 20:17:54   作者:windliang  
這篇文章主要介紹了Vue2?響應式系統(tǒng)之深度響應,文章基于Vue2?響應式系統(tǒng)的相關資料展開對Vue2?深度響應的介紹,需要的小伙伴可以參考一下

1、場景

import { observe } from "./reactive";
import Watcher from "./watcher";
const data = {
    text: {
        innerText: {
            childText: "hello",
        },
    },
};
observe(data);
const updateComponent = () => {
    console.log(data.text.innerText.childText);
};

new Watcher(updateComponent);
data.text.innerText.childText = "liang";

我們的響應式系統(tǒng)到現(xiàn)在還沒有支持屬性是對象時候的響應,因此我們改變 的時候不會有任何輸出。childText

我們只收集了 的依賴,所以如果想要響應的話必須給 整個賦值為一個新對象。data.textdata.text

import { observe } from "./reactive";
import Watcher from "./watcher";
const data = {
    text: {
        innerText: {
            childText: "hello",
        },
    },
};
observe(data);
const updateComponent = () => {
    console.log(data.text.innerText.childText);
};

new Watcher(updateComponent);
data.text = {
    innerText: {
        childText: "liang",
    },
};

image-20220405115503890

我們當然不希望每次都賦值整個對象,我們需要做一些修改,把嵌套的對象也變成響應式的。

2、方案

我們只需要在給某個 重寫 和 之前,把它的 就像上邊給 調(diào)用 函數(shù)一樣,也調(diào)用一次 函數(shù)即可。keygetsetvaluedataobserveobserve

同時提供 參數(shù),留下擴展,讓外界決定是否需要深度響應。shallow

/*******************新增 shallow*******************/
export function defineReactive(obj, key, val, shallow) {
/****************************************************/
    const property = Object.getOwnPropertyDescriptor(obj, key);
    // 讀取用戶可能自己定義了的 get、set
    const getter = property && property.get;
    const setter = property && property.set;
    // val 沒有傳進來話進行手動賦值
    if ((!getter || setter) && arguments.length === 2) {
        val = obj[key];
    }
    const dep = new Dep(); // 持有一個 Dep 對象,用來保存所有依賴于該變量的 Watcher
    /*******************新增****************************/
    !shallow && observe(val);
  	/******************************************************/
    Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get: function reactiveGetter() {
            const value = getter ? getter.call(obj) : val;
            if (Dep.target) {
                dep.depend();
            }
            return value;
        },
        set: function reactiveSetter(newVal) {
            const value = getter ? getter.call(obj) : val;

            if (setter) {
                setter.call(obj, newVal);
            } else {
                val = newVal;
            }
            dep.notify();
        },
    });
}

同時,在 函數(shù)中,傳進來的 不是對象的話我們直接 。observevaluereturn

/*
util.js
export function isObject(obj) {
    return obj !== null && typeof obj === "object";
}
*/
export function observe(value) {
    if (!isObject(value)) {
        return;
    }
    let ob = new Observer(value);
    return ob;
}

3、場景2

import { observe } from "./reactive";
import Watcher from "./watcher";
const data = {
    text: {
        innerText: {
            childText: "hello",
        },
    },
};
observe(data);
const updateComponent = () => {
    console.log(data.text.innerText.childText);
};

new Watcher(updateComponent);

data.text.innerText.childText = "liang";
data.text = {
    innerText: {
        childText: "liang2",
    },
};

data.text.innerText.childText = "liang3";

可以一分鐘想一下上邊會輸出什么。

new Watcher(updateComponent); ,執(zhí)行一次 輸出 。updateComponenthello

data.text.innerText.childText = "liang"; ,我們已經(jīng)解決了屬性是對象的情況,因此這里也會輸出 。liang

data.text = {
    innerText: {
        childText: "liang2",
    },
};

上邊代碼就是文章最開頭的方法,因此也會觸發(fā)函數(shù)執(zhí)行,輸出 。liang2

data.text.innerText.childText = "liang3"; 最后這句會執(zhí)行嗎?

答案是否定的了,因為我們的 賦值為了一個新對象,但這個新對象我們并沒有將其設置為響應式的。data.text

因此我們需要在 的時候把對象也設置為響應式的。set

/**
 * Define a reactive property on an Object.
 */
export function defineReactive(obj, key, val, shallow) {
    const property = Object.getOwnPropertyDescriptor(obj, key);
    // 讀取用戶可能自己定義了的 get、set
    const getter = property && property.get;
    const setter = property && property.set;
    // val 沒有傳進來話進行手動賦值
    if ((!getter || setter) && arguments.length === 2) {
        val = obj[key];
    }
    const dep = new Dep(); // 持有一個 Dep 對象,用來保存所有依賴于該變量的 Watcher

    let childOb = !shallow && observe(val);
    Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get: function reactiveGetter() {
            const value = getter ? getter.call(obj) : val;
            if (Dep.target) {
                dep.depend();
            }
            return value;
        },
        set: function reactiveSetter(newVal) {
            const value = getter ? getter.call(obj) : val;

            if (setter) {
                setter.call(obj, newVal);
            } else {
                val = newVal;
            }
          /******新增 *************************/
            childOb = !shallow && observe(newVal);
           /************************************/
            dep.notify();
        },
    });
}

4、總結

通過遞歸解決了屬性是對象的依賴,可以為未來數(shù)組的依賴留下基礎。

到此這篇關于Vue2 響應式系統(tǒng)之深度響應的文章就介紹到這了,更多相關Vue2 深度響應內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • vue中useVModel()的使用方法(通俗易懂)

    vue中useVModel()的使用方法(通俗易懂)

    useVModel()用來實現(xiàn)父子組件間數(shù)據(jù)的雙向綁定,若不想使用默認回調(diào),也可以自己使用emit實現(xiàn)回調(diào),這篇文章主要給大家介紹了關于vue中useVModel()使用方法的相關資料,需要的朋友可以參考下
    2024-03-03
  • vue項目中實現(xiàn)el-dialog組件可拖拽效果

    vue項目中實現(xiàn)el-dialog組件可拖拽效果

    本文主要介紹了vue項目中實現(xiàn)el-dialog組件可拖拽效果,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • vue實現(xiàn).md文件預覽功能的兩種方法詳解

    vue實現(xiàn).md文件預覽功能的兩種方法詳解

    這篇文章主要介紹了Vue預覽.md文件的兩種方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2025-04-04
  • 在Vue中使用動態(tài)import()語法動態(tài)加載組件

    在Vue中使用動態(tài)import()語法動態(tài)加載組件

    在Vue中,你可以使用動態(tài)import()語法來動態(tài)加載組件,動態(tài)導入允許你在需要時異步加載組件,這樣可以提高應用程序的初始加載性能,本文給大家介紹在Vue中使用動態(tài)import()語法動態(tài)加載組件,感興趣的朋友一起看看吧
    2023-11-11
  • vuejs2.0運用原生js實現(xiàn)簡單的拖拽元素功能示例

    vuejs2.0運用原生js實現(xiàn)簡單的拖拽元素功能示例

    本篇文章主要介紹了vuejs2.0運用原生js實現(xiàn)簡單的拖拽元素功能示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-02-02
  • vue-router單頁面路由

    vue-router單頁面路由

    這篇文章主要為大家詳細介紹了vue-router單頁面路由的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 關于vue.js彈窗組件的知識點總結

    關于vue.js彈窗組件的知識點總結

    最近在開發(fā)過程對對于組件化的開發(fā)有一些感想,于是開始記錄下這些。彈窗組件一直是 web 開發(fā)中必備的,使用頻率相當高,最常見的莫過于 alert,confirm和prompt這些,不同的組件庫對于彈窗的處理也是不一樣的,下面來一起看看吧。
    2016-09-09
  • Vue實現(xiàn)訂單支付倒計時功能

    Vue實現(xiàn)訂單支付倒計時功能

    這篇文章主要給大家介紹了Vue實現(xiàn)訂單支付倒計時功能,倒計時這要運用在創(chuàng)建訂單后15分鐘內(nèi)進行支付,否則訂單取消,本文結合示例代碼給大家詳細講解,需要的朋友可以參考下
    2023-08-08
  • 詳解element-ui中表單驗證的三種方式

    詳解element-ui中表單驗證的三種方式

    這篇文章主要介紹了詳解element-ui中表單驗證的三種方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09
  • vue element-ui table組件動態(tài)生成表頭和數(shù)據(jù)并修改單元格格式 父子組件通信

    vue element-ui table組件動態(tài)生成表頭和數(shù)據(jù)并修改單元格格式 父子組件通信

    這篇文章主要介紹了vue element-ui table組件動態(tài)生成表頭和數(shù)據(jù)并修改單元格格式 父子組件通信,需要的朋友可以參考下
    2019-08-08

最新評論

武平县| 高平市| 钦州市| 织金县| 巴青县| 麻城市| 巩义市| 曲阜市| 贵定县| 台中县| 延庆县| 兴仁县| 依兰县| 安康市| 新田县| 福建省| 广饶县| 桐城市| 宁海县| 威宁| 精河县| 龙南县| 金山区| 涪陵区| 太仆寺旗| 宁陕县| 连云港市| 深州市| 新建县| 萨迦县| 运城市| 高安市| 长顺县| 舟曲县| 新源县| 潞城市| 绥滨县| 集贤县| 霍林郭勒市| 柯坪县| 台前县|