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

詳細(xì)聊聊Vue中的MVVM模式原理

 更新時(shí)間:2023年03月03日 09:15:53   作者:周興  
MVVM旨在利用WPF中的數(shù)據(jù)綁定函數(shù),通過從視圖層中幾乎刪除所有GUI代碼(代碼隱藏),更好地促進(jìn)視圖層開發(fā)與模式其余部分的分離,這篇文章主要給大家介紹了關(guān)于Vue.js中MVVM的相關(guān)資料,需要的朋友可以參考下

1. MVVM模式

傳統(tǒng)的組件是靜態(tài)渲染,數(shù)據(jù)更新需要操作DOM。Vue框架采用了MVVM(Model-View-ViewModel)模式來管理應(yīng)用程序的數(shù)據(jù)模型(Model)和視圖界面(View)的交互,即數(shù)據(jù)驅(qū)動(dòng)視圖,從而避免了操作DOM。

MVVM的基本思想是將模型數(shù)據(jù)和用戶視圖解耦(Decoupling),即Model和View分離開來,使得它們之間的依賴關(guān)系降到最小。然后通過ViewModel來協(xié)調(diào)它們之間的通信。當(dāng)Model發(fā)生變化時(shí),我們不需要手動(dòng)更新View,而是可以通過Vue的響應(yīng)式機(jī)制,讓Vue自動(dòng)更新View。同樣,當(dāng)用戶與View交互時(shí),我們也不需要手動(dòng)修改Model,而是可以通過Vue的指令和事件機(jī)制,讓Vue自動(dòng)更新Model。這種解耦機(jī)制使得我們可以更加專注于業(yè)務(wù)邏輯的實(shí)現(xiàn),而不需要過多地關(guān)注View和Model之間的細(xì)節(jié)。

  • Model:Vue應(yīng)用程序中的數(shù)據(jù)模型,通常是一個(gè)JavaScript對(duì)象或數(shù)組。這些數(shù)據(jù)模型被存儲(chǔ)在Vue實(shí)例的data屬性中。
  • View:Vue應(yīng)用程序中的視圖界面,通常是由HTML模板和Vue指令組成的。Vue的模板語法允許開發(fā)人員在HTML中綁定數(shù)據(jù)和表達(dá)式,以實(shí)現(xiàn)動(dòng)態(tài)更新。
  • ViewModel:ViewModel是Vue應(yīng)用程序的核心,它是一個(gè)Vue實(shí)例,它充當(dāng)Model和View之間的橋梁。ViewModel負(fù)責(zé)管理數(shù)據(jù)和行為,它可以將Model數(shù)據(jù)綁定到View上,同時(shí)也可以響應(yīng)View上的事件和用戶交互。ViewModel中包含了一個(gè)Watcher和Directive,它們可以監(jiān)聽Model數(shù)據(jù)的變化,并自動(dòng)更新View。

2. Vue響應(yīng)式

Vue的響應(yīng)式機(jī)制是指當(dāng)Vue實(shí)例中的數(shù)據(jù)發(fā)生變化時(shí),與之關(guān)聯(lián)的視圖會(huì)自動(dòng)更新。實(shí)現(xiàn)Vue響應(yīng)式機(jī)制需要借助ES5的Object.defineProperty()方法,使用該方法監(jiān)聽對(duì)象屬性的變化。

Object.defineProperty(obj, prop, descriptor)用來定義對(duì)象的屬性。函數(shù)中傳入三個(gè)參數(shù),obj表示要定義屬性的對(duì)象,prop表示要定義的屬性名,descriptor是一個(gè)包含屬性描述符的對(duì)象。下面這段代碼是該函數(shù)的基本使用:

let data = {};
let name = '小明';
Object.defineProperty(data, "name", {
    get: function(){
        console.log('get')
        return name
    },
    set: function(newValue){
        console.log('set')
        name = newValue
    }
})
// 測試
console.log(data.name)
data.name = '小紅'
console.log(data.name)

3. Vue監(jiān)聽對(duì)象

3.1 監(jiān)聽普通對(duì)象

以下代碼模擬了的監(jiān)聽對(duì)象的過程,當(dāng)data對(duì)象中的數(shù)據(jù)發(fā)生變化時(shí),就會(huì)調(diào)用updateView()函數(shù),觸發(fā)視圖更新。

// 觸發(fā)視圖更新,模擬Model變化后,View發(fā)生改變,簡單起見就直接打印一個(gè)結(jié)果
function updateView(){
	console.log('視圖更新')
}
// 重新定義屬性,實(shí)現(xiàn)對(duì)數(shù)據(jù)的監(jiān)聽
function defineReactive(target, key, value){
	// 核心 API
	Object.defineProperty(target, key, {
		get(){
			return value
		},
		set(newValue){
			if(newValue !== value){
				value = newValue
				updateView()
			}
		}
	})
}
// 監(jiān)聽對(duì)象屬性
function observer(target){
	// 如果監(jiān)聽的數(shù)據(jù)類型不是對(duì)象,直接返回原數(shù)據(jù)
	if(typeof target !== 'object' || target === null){
		return target
	}
	// 重新定義對(duì)象的每個(gè)屬性
	for(let key in target){
		defineReactive(target, key, target[key])
	}
}
// 數(shù)據(jù)
let data = {
	name: '小明',
	age: 20,
	info: {
		address: '北京'
	}
}
// 監(jiān)聽數(shù)據(jù)
observer(data)
// 測試
data.name = '小紅'
data.age = 21
data.name  // 會(huì)觸發(fā)getter函數(shù)
data.age 

3.2 監(jiān)聽復(fù)雜對(duì)象(深度監(jiān)聽)

假如數(shù)據(jù)對(duì)象中還包含對(duì)象,此時(shí)就需要進(jìn)行深度監(jiān)聽,例如data中的info數(shù)據(jù)。只需要在上述的defineReactive()函數(shù)中,再次調(diào)用observer()函數(shù),對(duì)傳入的對(duì)象的屬性值value進(jìn)行監(jiān)聽。

設(shè)置新值時(shí),如果設(shè)置的值還是一個(gè)對(duì)象類型,此時(shí)還需要對(duì)新值進(jìn)行監(jiān)聽。

function updateView(){
	console.log('視圖更新')
}
// 重新定義屬性,實(shí)現(xiàn)對(duì)數(shù)據(jù)的監(jiān)聽
function defineReactive(target, key, value){
	// 再次對(duì)傳入的對(duì)象的屬性值調(diào)用監(jiān)聽函數(shù)
	observer(value)
	// 核心 API
	Object.defineProperty(target, key, {
		get(){
			return value
		},
		set(newValue){
			// 對(duì)新設(shè)置的值進(jìn)行監(jiān)聽
			observer(newValue)
			if(newValue !== value){
				value = newValue
				updateView()
			}
		}
	})
}
// 監(jiān)聽對(duì)象屬性
function observer(target){
	// 如果監(jiān)聽的數(shù)據(jù)類型不是對(duì)象,直接返回原數(shù)據(jù)
	if(typeof target !== 'object' || target === null){
		return target
	}
	// 重新定義對(duì)象的每個(gè)屬性
	for(let key in target){
		defineReactive(target, key, target[key])
	}
}
// 數(shù)據(jù)
let data = {
	name: '小明',
	age: 20,
	info: {
		address: '北京'
	}
}
// 監(jiān)聽數(shù)據(jù)
observer(data)
// 測試
data.name = '小紅'
data.age = {num: 21}
data.age.num = 22  
data.info.address = '上海'

4. Vue監(jiān)聽數(shù)組

// 觸發(fā)更新視圖
function updateView() {
    console.log('視圖更新')
}
// // 重新定義數(shù)組原型
const oldArrayProperty = Array.prototype
// 創(chuàng)建新對(duì)象,原型指向 oldArrayProperty ,再擴(kuò)展新的方法不會(huì)影響原型
const arrProto = Object.create(oldArrayProperty);
// 對(duì)數(shù)常用的方法進(jìn)行擴(kuò)展
['push', 'pop', 'shift', 'unshift', 'splice'].forEach(methodName => {
    arrProto[methodName] = function () {
        oldArrayProperty[methodName].call(this, ...arguments)
        updateView() // 觸發(fā)視圖更新
        Array.prototype[methodName].call(this, ...arguments)
    }
})
// 重新定義屬性,監(jiān)聽起來
function defineReactive(target, key, value) {
    // 深度監(jiān)聽
    observer(value)
    // 核心 API
    Object.defineProperty(target, key, {
        get() {
            return value
        },
        set(newValue) {
            if (newValue !== value) {
                // // 深度監(jiān)聽
                observer(newValue)
                // 設(shè)置新值
                // 注意,value 一直在閉包中,此處設(shè)置完之后,再 get 時(shí)也是會(huì)獲取最新的值
                value = newValue
                // 觸發(fā)更新視圖
                updateView()
            }
        }
    })
}
// 監(jiān)聽對(duì)象屬性
function observer(target) {
    if (typeof target !== 'object' || target === null) {
        // 不是對(duì)象或數(shù)組
        return target
    }
    // 修改數(shù)組的原型
    if (Array.isArray(target)) {
        target.__proto__ = arrProto
    }
    // 重新定義各個(gè)屬性(for in 也可以遍歷數(shù)組)
    for (let key in target) {
        defineReactive(target, key, target[key])
    }
}
// 準(zhǔn)備數(shù)據(jù)
const data = {
    // name: '小明',
    // age: 20,
    // info: {
    //     address: '北京' // 需要深度監(jiān)聽
    // },
    nums: [10, 20, 30]
}
// 監(jiān)聽數(shù)據(jù)
observer(data)
// 測試
data.nums.push(4) // 監(jiān)聽數(shù)組

5. 使用 Object.defineProperty 監(jiān)聽數(shù)據(jù)的缺點(diǎn)

  • 深度監(jiān)聽需要對(duì)數(shù)據(jù)對(duì)象遞歸到底,一次性計(jì)算量大。
  • 如果數(shù)據(jù)新增屬性和刪除屬性,則無法監(jiān)聽到,需要使用 Vue.set()Vue.delete() 方法。
  • 無法原生監(jiān)聽數(shù)組,需要特殊處理。

到此這篇關(guān)于詳細(xì)聊聊Vue中的MVVM模式原理的文章就介紹到這了,更多相關(guān)Vue中MVVM內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vite打包優(yōu)化CDN壓縮的分析實(shí)現(xiàn)

    vite打包優(yōu)化CDN壓縮的分析實(shí)現(xiàn)

    我們?cè)谌粘5墓ぷ髦锌隙〞?huì)遇到項(xiàng)目打包優(yōu)化等問題,本文主要介紹了vite打包優(yōu)化CDN壓縮的分析實(shí)現(xiàn),具有一定的參加價(jià)值,感興趣的可以了解一下
    2024-07-07
  • vue通過video.js解決m3u8視頻播放格式的方法

    vue通過video.js解決m3u8視頻播放格式的方法

    這篇文章主要給大家介紹了關(guān)于vue通過video.js解決m3u8視頻播放格式的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • vue上傳圖片組件編寫代碼

    vue上傳圖片組件編寫代碼

    這篇文章主要為大家詳細(xì)介紹了vue上傳圖片組件的編寫代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Vue 3自定義指令開發(fā)的相關(guān)總結(jié)

    Vue 3自定義指令開發(fā)的相關(guān)總結(jié)

    這篇文章主要介紹了Vue 3自定義指令開發(fā)的相關(guān)總結(jié),幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下
    2021-01-01
  • vue使用axios訪問本地json文件404問題及解決

    vue使用axios訪問本地json文件404問題及解決

    這篇文章主要介紹了vue使用axios訪問本地json文件404問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Vue.js組件通信的幾種姿勢

    Vue.js組件通信的幾種姿勢

    組件 (Component) 是 Vue.js 最強(qiáng)大的功能之一。組件可以擴(kuò)展 HTML 元素,封裝可重用的代碼。下面通過本文給大家分享Vue.js組件通信的幾種姿勢,感興趣的朋友一起看看吧
    2017-10-10
  • Vue3組合式API中如何優(yōu)化列表渲染性能

    Vue3組合式API中如何優(yōu)化列表渲染性能

    這篇文章主要為大家詳細(xì)介紹了在Vue3組合式API中如何優(yōu)化列表渲染性能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12
  • 詳解vue3中websocket的封裝與使用

    詳解vue3中websocket的封裝與使用

    這篇文章主要為大家詳細(xì)介紹了vue3中websocket的封裝與使用的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12
  • vue3 與 vue2 優(yōu)點(diǎn)對(duì)比匯總

    vue3 與 vue2 優(yōu)點(diǎn)對(duì)比匯總

    隨著用vue3 的開發(fā)者越來越多,其必定是又她一定的有帶你,接下來這篇文章小編就為大家介紹vue3 對(duì)比 vue2 有什么優(yōu)點(diǎn)?感興趣的小伙伴請(qǐng)跟小編一起閱讀下文吧
    2021-09-09
  • mpvue+vant app搭建微信小程序的方法步驟

    mpvue+vant app搭建微信小程序的方法步驟

    這篇文章主要介紹了mpvue+vant app搭建微信小程序的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-02-02

最新評(píng)論

阿荣旗| 来安县| 美姑县| 巴里| 甘洛县| 大名县| 曲阳县| 江安县| 慈利县| 胶南市| 荥阳市| 涡阳县| 平安县| 黑水县| 玉环县| 万州区| 万全县| 鲜城| 辽源市| 韶山市| 襄樊市| 教育| 历史| 广河县| 海兴县| 公安县| 福贡县| 富源县| 沁源县| 遵义县| 双柏县| 五家渠市| 明光市| 称多县| 博野县| 锦州市| 馆陶县| 平山县| 云南省| 桃源县| 门头沟区|