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

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

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

vue2響應(yīng)式缺陷

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

vue2響應(yīng)式缺陷

1.對象新增的屬性沒有響應(yīng)式

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

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

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

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

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

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

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

示例:

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

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

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

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

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

修改數(shù)組的length,沒有響應(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)式原理;說到響應(yīng)式無非就是監(jiān)聽屬性的獲取,修改及刪除...,了解邏輯之后再去實現(xiàn)底層代碼豈不是快了許多=_=

vue2響應(yīng)式

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

代碼實現(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.對象新增屬性,刪除屬性界面不會更新 2.通過數(shù)組下標(biāo)修改數(shù)組內(nèi)容界面不會更新

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

2.通過數(shù)組下標(biāo)修改數(shù)組不會觸發(fā)響應(yīng),因為尤雨溪用了重寫數(shù)組的方法來實現(xiàn)數(shù)據(jù)的響應(yīng)綁定,當(dāng)vue遇到push pop shift unshift splice sort reverse 的時候數(shù)組才會改變

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

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

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

vue3響應(yīng)式雛形

原理:利用了Proxy和Reflect來代替Vue2的Object.defineProperty()方法來重寫響應(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指的是整個person,propName指的是person中的某個屬性,value指的是新值。

運行結(jié)果:

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

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

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

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

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

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

Proxy 可以直接監(jiān)聽對象而非屬性

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

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

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

Proxy 不需要初始化的時候遍歷所有屬性,另外有多層屬性嵌套的話,只有訪問某個屬性的時候,才會遞歸處理下一級的屬性 

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Vue路由router詳解

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

最新評論