欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于vue2響應(yīng)式缺陷的問(wèn)題

 更新時(shí)間:2022年09月10日 10:49:03   作者:Qiemoer  
這篇文章主要介紹了關(guān)于vue2響應(yīng)式缺陷的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

vue2響應(yīng)式缺陷

響應(yīng)式 : 數(shù)據(jù)改變 ==> 視圖跟著改變

vue2響應(yīng)式缺陷

1.對(duì)象新增的屬性沒(méi)有響應(yīng)式

對(duì)象,新增屬性b,修改b的值,值改變但視圖并未更新

解決方案 : 使用vue提供的 api $set(對(duì)象,屬性名,值) 效果如屬性c

2.數(shù)組的部分操作沒(méi)有響應(yīng)式

數(shù)組中有7種操作有響應(yīng)式

  • array.pop()
  • array.push()
  • array.shift()
  • array.unshift()
  • array.sort()
  • arry.reverse()
  • array.splice()

以上7中API會(huì)修改原數(shù)組(vue2的內(nèi)部重寫(xiě)了這7個(gè)API)

其他的操作都不會(huì)有響應(yīng)式

示例:

1.修改數(shù)組的第一個(gè)元素的值

// 直接通過(guò)下標(biāo)來(lái)修改,沒(méi)有響應(yīng)式
fn1() {
    this.arr[0] = 100
}

通過(guò)下標(biāo)直接賦值,沒(méi)有響應(yīng)式

2.修改數(shù)組的長(zhǎng)度為0

//修改數(shù)組的length
fn2 () {
    this.arr.length = 0
}

修改數(shù)組的length,沒(méi)有響應(yīng)式

如何修改數(shù)組的值有響應(yīng)式

fn1 () {
    // 方法1: 先刪除,再添加
    this.arr.splice(0,1,100)
},
fn2 () {
    // 方法2: $set
    this.$set(this.arr, "0", 100)
}

vue2與vue3的響應(yīng)式原理

給大家分享一下Vue2和Vue3的響應(yīng)式原理;說(shuō)到響應(yīng)式無(wú)非就是監(jiān)聽(tīng)屬性的獲取,修改及刪除...,了解邏輯之后再去實(shí)現(xiàn)底層代碼豈不是快了許多=_=

vue2響應(yīng)式

原理:利用defineReactive方法,通過(guò)defineProperty對(duì)屬性進(jìn)行劫持,數(shù)組則是通過(guò)重寫(xiě)其方法來(lái)進(jìn)行劫持,每個(gè)屬性值都擁有自己的dep屬性,用來(lái)存取所依賴的watch,當(dāng)數(shù)據(jù)發(fā)生改變時(shí),觸發(fā)相應(yīng)的watch去更新數(shù)據(jù)

代碼實(shí)現(xiàn):

const { arrayMethods } = require('./array')
 
class Observer {
    constructor(value) {
        Object.defineProperty(value, '__ob__', {
            value: this,
            enumerable: false,
            writable: true,
            configurable: true
        })
        if(Array.isArray(value)) {
            value.__proto__ = arrayMethods
            this.observeArray(value)
        } else {
            this.walk(value)
        }
    }
 
    walk(data) {
        let keys = Object.keys(data)
        for(let i = 0; i < keys.length; i++) {
            const key = keys[i]
            const value = data[key]
            defineReactive(data, key, value)
        }
    }
 
    observeArray(items) {
        for(let i = 0; i < items.length; i++) {
            observe(items[i])
        }
    }
}
 
function defineReactive(data, key, value) {
    const childOb = observe(value)
 
    const dep = new Dep()
 
    Object.defineProperty(data, key, {
        get() {
            console.log('獲取值')
            if (Dep.target) {
                dep.depend()
 
                if (childOb) {
                    childOb.dep.depend()
 
                    if (Array.isArray(value)) {
                        dependArray(value)
                    }
                }
            }
            return value
        },
        set(newVal) {
            if (newVal === value) return
            observe(newVal)
            value = newVal
            dep.notify()
        }
    })
}
 
function observe(value) {
    if (Object.prototype.toString.call(value) === '[object Object]' || Array.isArray(value)) {
        return new Observer(value)
    }
}
 
function dependArray(value) {
    for(let e, i = 0, l = value.length; i < l; i++) {
        e = value[i]
 
        e && e.__ob__ && e.__ob__.dep.depend()
 
        if (Array.isArray(e)) {
            dependArray(e)
        }
    }
}
 
// array.js
const arrayProto = Array.prototype
 
const arrayMethods = Object.create(arrayProto)
 
const methodsToPatch = [
    'push',
    'pop',
    'shift',
    'unshift',
    'splice',
    'reverse',
    'sort'
]
 
methodsToPatch.forEach(method => {
    arrayMethods[method] = function (...args) {
        const result = arrayProto[method].apply(this, args)
 
        const ob = this.__ob__
 
        var inserted
 
        switch (method) {
            case 'push':
            case 'unshift':
                inserted = args
                break;
            case 'splice':
                inserted = args.slice(2)
            default:
                break;
        }
 
        if (inserted) ob.observeArray(inserted)
 
        ob.dep.notify()
 
        return result
    }
})
 

但是呢,Vue2的響應(yīng)式還存在一些缺陷:1.對(duì)象新增屬性,刪除屬性界面不會(huì)更新 2.通過(guò)數(shù)組下標(biāo)修改數(shù)組內(nèi)容界面不會(huì)更新

原因:1.Vue 無(wú)法檢測(cè) property 的添加或移除。由于 Vue 會(huì)在初始化實(shí)例時(shí)對(duì) property 執(zhí)行 getter/setter 轉(zhuǎn)化,所以 property 必須在 data 對(duì)象上存在才能讓 Vue 將它轉(zhuǎn)換為響應(yīng)式的

2.通過(guò)數(shù)組下標(biāo)修改數(shù)組不會(huì)觸發(fā)響應(yīng),因?yàn)橛扔晗昧酥貙?xiě)數(shù)組的方法來(lái)實(shí)現(xiàn)數(shù)據(jù)的響應(yīng)綁定,當(dāng)vue遇到push pop shift unshift splice sort reverse 的時(shí)候數(shù)組才會(huì)改變

 解決方案:1.對(duì)象:對(duì)象新增屬性無(wú)法更新視圖,通過(guò)Vue.$set(obj,key,value),組件中通過(guò)this.$set(obj,key,value)

2.數(shù)組:通過(guò)數(shù)組下標(biāo)修改數(shù)組不會(huì)觸發(fā)視圖更新,可以通過(guò)Vue.$set(obj,key,value),也可以通過(guò)push pop shift unshift splice sort reverse方法來(lái)實(shí)現(xiàn)響應(yīng)

 Vue3的響應(yīng)式彌補(bǔ)了Vue2響應(yīng)式的缺陷,并且還帶來(lái)了許多優(yōu)化,下面讓我們來(lái)了解一下Vue3響應(yīng)式的基本雛形

vue3響應(yīng)式雛形

原理:利用了Proxy和Reflect來(lái)代替Vue2的Object.defineProperty()方法來(lái)重寫(xiě)響應(yīng)式

這只是基本的代碼:

        let person = {
            name: '張三',
            age: 18
        }
        const p = new Proxy(person, {
            get(target, propName) {
                console.log(`我的${propName}值被獲取了`);
                return Reflect.get(target, propName)
            },
            set(target, propName, value) {
                console.log(`我的${propName}值被修改了`);
                Reflect.set(target, propName, value)
            },
            deleteProperty(target, propName) {
                console.log(`我的${propName}值被刪除了`);
                Reflect.deleteProperty(target, propName)
            }
        })

target指的是整個(gè)person,propName指的是person中的某個(gè)屬性,value指的是新值。

運(yùn)行結(jié)果:

vue3的響應(yīng)式相較于vue2的優(yōu)勢(shì)

用 Proxy 和 Reflect 來(lái)代替 vue2 中的 Object.definepeoperty()方法來(lái)重寫(xiě)響應(yīng)式

vue3 中可以監(jiān)聽(tīng)動(dòng)態(tài)新增的屬性

vue3 中可以監(jiān)聽(tīng)刪除的屬性

vue3 中可以監(jiān)聽(tīng)數(shù)組的索引和 length 屬性

代碼的執(zhí)行效果更快

Proxy 可以直接監(jiān)聽(tīng)對(duì)象而非屬性

Proxy 可以直接監(jiān)聽(tīng)數(shù)組的變化

Proxy 有多達(dá) 13 種攔截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具備的

Proxy 返回的是一個(gè)新對(duì)象,我們可以只操作新的對(duì)象達(dá)到目的,而 Object.defineProperty 只能遍歷對(duì)象屬性直接修改

Proxy 不需要初始化的時(shí)候遍歷所有屬性,另外有多層屬性嵌套的話,只有訪問(wèn)某個(gè)屬性的時(shí)候,才會(huì)遞歸處理下一級(jí)的屬性 

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

相關(guān)文章

  • 基于Vue實(shí)現(xiàn)可以拖拽的樹(shù)形表格實(shí)例詳解

    基于Vue實(shí)現(xiàn)可以拖拽的樹(shù)形表格實(shí)例詳解

    因業(yè)務(wù)需求,需要一個(gè)樹(shù)形表格,并且支持拖拽排序,任意未知插入,github搜了下,真不到合適的,大部分樹(shù)形表格都沒(méi)有拖拽功能,所以決定自己實(shí)現(xiàn)一個(gè)。這里分享一下實(shí)現(xiàn)過(guò)程,需要的朋友可以參考下
    2018-10-10
  • 快速修改antd?vue單個(gè)組件的默認(rèn)樣式

    快速修改antd?vue單個(gè)組件的默認(rèn)樣式

    這篇文章主要介紹了快速修改antd?vue單個(gè)組件的默認(rèn)樣式方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。
    2022-08-08
  • vue如何循環(huán)給對(duì)象賦值

    vue如何循環(huán)給對(duì)象賦值

    這篇文章主要介紹了vue如何循環(huán)給對(duì)象賦值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • 用vue構(gòu)建多頁(yè)面應(yīng)用的示例代碼

    用vue構(gòu)建多頁(yè)面應(yīng)用的示例代碼

    這篇文章主要介紹了用vue構(gòu)建多頁(yè)面應(yīng)用的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • vue-treeselect及el-tree點(diǎn)擊節(jié)點(diǎn)獲取上級(jí)節(jié)點(diǎn)的數(shù)據(jù)方式

    vue-treeselect及el-tree點(diǎn)擊節(jié)點(diǎn)獲取上級(jí)節(jié)點(diǎn)的數(shù)據(jù)方式

    這篇文章主要介紹了vue-treeselect及el-tree點(diǎn)擊節(jié)點(diǎn)獲取上級(jí)節(jié)點(diǎn)的數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 詳解vue組件通信的三種方式

    詳解vue組件通信的三種方式

    本篇文章主要介紹了詳解vue組件通信的三種方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • Vue3使用路由及配置vite.alias簡(jiǎn)化導(dǎo)入寫(xiě)法的過(guò)程詳解

    Vue3使用路由及配置vite.alias簡(jiǎn)化導(dǎo)入寫(xiě)法的過(guò)程詳解

    這篇文章主要介紹了Vue3使用路由及配置vite.alias簡(jiǎn)化導(dǎo)入寫(xiě)法,本文通過(guò)實(shí)例代碼給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-11-11
  • Vue 3.0x中的Suspense和異步組件詳解

    Vue 3.0x中的Suspense和異步組件詳解

    這篇文章主要介紹了Vue 3.0x中的Suspense和異步組件,我們將討論新的defineAsyncComponent函數(shù),以及如何利用Suspense組件來(lái)更好地處理異步組件的加載和顯示,需要的朋友可以參考下
    2023-08-08
  • 淺談vue項(xiàng)目用到的mock數(shù)據(jù)接口的兩種方式

    淺談vue項(xiàng)目用到的mock數(shù)據(jù)接口的兩種方式

    這篇文章主要介紹了淺談vue項(xiàng)目用到的mock數(shù)據(jù)接口的兩種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Vue路由router詳解

    Vue路由router詳解

    這篇文章主要介紹了vue router 配置路由的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2021-10-10

最新評(píng)論