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

vue3中遇到reactive響應式失效的問題記錄

 更新時間:2023年06月06日 10:24:50   作者:柑橘烏云_  
這篇文章主要介紹了vue3中遇到reactive響應式失效的問題記錄,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

vue3中reactive響應式失效

情況簡述 

初始化了一個reactive的空數(shù)組,之后調用接口,將接口返回的數(shù)據(jù)賦值給這個reactive,此時發(fā)現(xiàn)頁面數(shù)據(jù)并沒有更新。(場景:ele-table的dataList)

const dataList = reactive([]);
const load = async () => {
? const res = await 接口函數(shù)(); //假設請求接口返回的數(shù)據(jù)
? // 方法1 失敗,直接賦值丟失了響應性
? // dataList = res;
? // 方法2 這樣也是失敗
? // dataList.concat(res);
};

原因

直接把一個新的數(shù)組賦值給dataList,導致reactive聲明的響應式對象由dataList代理

被新的數(shù)組所替代,因為在操作代理對象的時候需要有代理對象作為前提,所以失去了響應式

在vue3中不管是對象還是數(shù)組都不能直接將整個數(shù)據(jù)進行賦值,這樣會造成reactive定義的響應式失效

就像對象的地址被替換,就不是原來的那個對象了

解決辦法

方法1:創(chuàng)建一個響應式對象,對象的屬性是數(shù)組

let datalist = reactive({
? list: [],
})
let arr = [1,2,3]
datalist.list = arr

方法2:使用ref函數(shù)(ref可以創(chuàng)建任意數(shù)據(jù)類型,reactive只能創(chuàng)建對象或者數(shù)組)

const datalist = ref([])
datalist.value = [1, 2, 3]?

方法3:數(shù)組的push

let datalist = reactive([])
let arr = [1, 2, 3]
arr.forEach((item) => {?
?datalist.push(item)
})?

let datalist = reactive([])
let arr = [1, 2, 3]
datalist.push(...arr)

vue3解構響應式失效解析

在使用vue3時,我們發(fā)現(xiàn)不能使用解構來處理響應式數(shù)據(jù),今天我們來看看究竟是為什么。

在vue3中解構響應式數(shù)據(jù)

<div>{{counter}}</div>
<div>{{obj.value}}</div>
const reactiveObj = reactive({
? counter: 0,
? obj: {
? ? value: 1
? }
});
setInterval(() => {
? reactiveObj.counter++;
? reactiveObj.obj.value++;
}, 1000);
const { counter, obj } = reactiveObj;
return {
? counter,
? obj
};

在頁面上可以看到,counter的值不會變,obj.a的值倒是一直在遞增。

我們都知道vue3是使用ES6的proxy特性來實現(xiàn)響應式的,先來回顧一下proxy。

const obj = {
? ? value: 1
}
const proxy = new Proxy(obj, {
? ? get: function(target, key) {
? ? ? ? return Reflect.get(...arguments);
? ? },
? ? set: function(target, key, value) {
? ? ? ? return Reflect.set(...arguments)
? ? }
})
proxy.value++;
console.log(proxy.value); ? // 2

proxy本身就是對對象進行攔截,通過new Proxy的返回值,攔截obj對象,當操作對象中的值時,會觸發(fā)set或者get。

但是對于原始值(string、number這些),就需要在外部包裹一下變成一個對象,不然沒辦法使用new Proxy去攔截。

我們來看看vue3是如何處理的。

在vue3中,使用ref來為基本數(shù)據(jù)類型添加響應式。

export function ref(value?: unknown) {
? return createRef(value, false)
}
function createRef(rawValue: unknown, shallow: boolean) {
? if (isRef(rawValue)) {
? ? return rawValue
? }
? // 使用一個對象包裹基本數(shù)據(jù)類型數(shù)據(jù)
? return new RefImpl(rawValue, shallow)
}
class RefImpl<T> {
? private _value: T
? private _rawValue: T
? public dep?: Dep = undefined
? public readonly __v_isRef = true
? constructor(value: T, public readonly __v_isShallow: boolean) {
? ? this._rawValue = __v_isShallow ? value : toRaw(value)
? ? this._value = __v_isShallow ? value : toReactive(value)
? }
? get value() {
? ? trackRefValue(this)
? ? return this._value
? }
? set value(newVal) {
? ? newVal = this.__v_isShallow ? newVal : toRaw(newVal)
? ? if (hasChanged(newVal, this._rawValue)) {
? ? ? this._rawValue = newVal
? ? ? this._value = this.__v_isShallow ? newVal : toReactive(newVal)
? ? ? triggerRefValue(this, newVal)
? ? }
? }
}

從上面的代碼可以發(fā)現(xiàn),vue3把原始值包裝成一個對象,通過get value和set value方法來對原始值進行訪問,這樣在訪問值的時候就必須攜帶.value了。

而對于對象而言,使用ref的話內部還是調用reactive。

export const toReactive = <T extends unknown>(value: T): T =>
? isObject(value) ? reactive(value) : value
export function reactive(target: object) {
? if (isReadonly(target)) {
? ? return target
? }
? return createReactiveObject(
? ? target,
? ? false,
? ? mutableHandlers,
? ? mutableCollectionHandlers,
? ? reactiveMap
? )
}

但是還是需要通過.value去訪問內部的響應式數(shù)據(jù).

let reactiveObj = ref({
? counter: 0,
? obj: {
? ? a: 1
? }
});
console.log(reactiveObj.value.obj.a);

為什么解構會破壞響應式?

解構賦值,區(qū)分基本數(shù)據(jù)類型和引用類型的賦值,原始類型的賦值相當于按值傳遞,引用類型的值就相當于按引用傳遞。

const obj = {
? value: 1,
? obj1: {
? ? value: 1
? }
}
const val = obj.value;
const obj1 = obj.obj1;

上方的val雖然是obj.value的值,但是當訪問val時,已經(jīng)繞過了obj對象的get方法,也就是本文討論的失去響應式。

而obj1在解構出來的值是按引用傳遞的,內部的指針依然指向obj.obj1,所以去訪問其中的內容并不會失去響應式。

總結

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Vue CLI3 開啟gzip壓縮文件的方式

    Vue CLI3 開啟gzip壓縮文件的方式

    gizp壓縮是一種http請求優(yōu)化方式,通過減少文件體積來提高加載速度。這篇文章主要介紹了Vue CLI3 開啟gzip壓縮,需要的朋友可以參考下
    2018-09-09
  • vue實現(xiàn)下拉多選、可搜索、全選功能(示例代碼)

    vue實現(xiàn)下拉多選、可搜索、全選功能(示例代碼)

    本文介紹了如何在Vue中實現(xiàn)一個樹形結構的下拉多選組件,支持任意一級選項的選擇,全選功能,以及搜索功能,通過在mounted生命周期中獲取數(shù)據(jù),并使用handleTree函數(shù)將接口返回的數(shù)據(jù)整理成樹形結構,實現(xiàn)了這一功能,感興趣的朋友一起看看吧
    2025-01-01
  • Vue指令實現(xiàn)OutClick的示例

    Vue指令實現(xiàn)OutClick的示例

    在一般業(yè)務中監(jiān)聽的最多的就是 Click 事件,但是在一些業(yè)務比如 Alert 和 Pop 效果時,需要監(jiān)聽在元素外部的點擊來關閉彈窗。
    2020-11-11
  • vue實現(xiàn)下拉框的多選功能(附后端處理參數(shù))

    vue實現(xiàn)下拉框的多選功能(附后端處理參數(shù))

    本文介紹了如何使用Vue實現(xiàn)下拉框的多選功能,實現(xiàn)了在選擇框中選擇多個選項的功能,文章詳細介紹了實現(xiàn)步驟和示例代碼,對于想要了解如何使用Vue實現(xiàn)下拉框多選功能的讀者具有一定的參考價值
    2023-08-08
  • 關于vue中對window.openner的使用指南

    關于vue中對window.openner的使用指南

    opener屬性是一個可讀可寫的屬性,可返回對創(chuàng)建該窗口的Window對象的引用,下面這篇文章主要給大家介紹了關于vue中對window.openner使用的相關資料,需要的朋友可以參考下
    2022-11-11
  • ant design vue 清空upload組件圖片緩存的問題

    ant design vue 清空upload組件圖片緩存的問題

    這篇文章主要介紹了ant design vue 清空upload組件圖片緩存的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 基于elementUI實現(xiàn)圖片預覽組件的示例代碼

    基于elementUI實現(xiàn)圖片預覽組件的示例代碼

    這篇文章主要介紹了基于elementUI實現(xiàn)圖片預覽組件的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • Vue.js如何實現(xiàn)路由懶加載淺析

    Vue.js如何實現(xiàn)路由懶加載淺析

    Vue是可以自定義指令的,最近學習過程中遇見了一個需要懶加載的功能,發(fā)現(xiàn)網(wǎng)上這方面的資料較少,所以下面這篇文章主要給大家介紹了關于Vue.js如何實現(xiàn)路由懶加載的相關資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-08-08
  • 如何在Vue中使localStorage具有響應式(思想實驗)

    如何在Vue中使localStorage具有響應式(思想實驗)

    這篇文章主要介紹了如何在Vue中使localStorage具有響應式,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • vue3+vite使用postcss-pxtorem、autoprefixer自適應和自動添加前綴

    vue3+vite使用postcss-pxtorem、autoprefixer自適應和自動添加前綴

    這篇文章主要介紹了vue3+vite使用postcss-pxtorem、autoprefixer自適應和自動添加前綴方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10

最新評論

沽源县| 广灵县| 罗甸县| 奉贤区| 民和| 武城县| 茌平县| 永昌县| 姚安县| 扎兰屯市| 建宁县| 通化市| 华容县| 威宁| 杭锦后旗| 沈丘县| 田林县| 巨野县| 宝山区| 罗甸县| 内黄县| 连城县| 萨嘎县| 恩平市| 绥中县| 沧源| 灵山县| 长治县| 简阳市| 岫岩| 阜城县| 江北区| 唐山市| 谷城县| 岢岚县| 遂溪县| 宿迁市| 仁化县| 津市市| 纳雍县| 福海县|