亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

一文帶你簡(jiǎn)單理解Vue的data為何只能是函數(shù)

 更新時(shí)間:2022年10月16日 09:15:17   作者:當(dāng)然是黑貓警長(zhǎng)啦  
如果data是一個(gè)函數(shù)的話,這樣每復(fù)用一次組件,就會(huì)返回一份新的data,下面這篇文章主要給大家介紹了關(guān)于簡(jiǎn)單理解Vue的data為啥只能是函數(shù)的相關(guān)資料,需要的朋友可以參考下

前言

在學(xué)習(xí)vue的時(shí)候vue2只有在組件中嚴(yán)格要求data必須是一個(gè)函數(shù),而在普通vue實(shí)例中,data可以是一個(gè)對(duì)象,但是在vue3出現(xiàn)后data必須一個(gè)函數(shù),當(dāng)時(shí)看著官方文檔說(shuō)的是好像是對(duì)象的引用問(wèn)題,但是內(nèi)部原理卻不是很了解,今天通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明為啥data必須是一個(gè)函數(shù)

參考 (vue2data描述)

參考: (vue3data描述)

1.Vue3中的data

const { createApp } = Vue
const app = {
    data: {
        a: 1
    },
    template: `
    <h1>{{a}}</h1>
    `
}
createApp(app).mount('#app')

可以看到上來(lái)vue就給了警告說(shuō)明data必須是一個(gè)函數(shù) 下面直接拋錯(cuò)

2.vue中的data

var app = new Vue({
    el: '#app',
    data: { a: 'hello world' }
})

這種寫(xiě)法是可以的,前面提過(guò)普通實(shí)例data可以是對(duì)象,但是在組件中必須是函數(shù), 那么在vue2中難道普通實(shí)例就沒(méi)有缺陷嘛?答案:是有缺陷的, 比如這樣

<div id="app1">{{ message }}</div>
<div id="app2">{{ message }}</div> 
const data = { message: 'hello world' }
const vue1 = new Vue({
    el: '#app1',
    data
})

const vue2 = new Vue({
    el: '#app2',
    data
})

這樣在頁(yè)面中會(huì)顯示2個(gè)內(nèi)容為hello world的div標(biāo)簽 那么當(dāng)我們通過(guò)實(shí)例去改變messag呢?

 vue1.message = 'hello Vue'

奇怪的事情發(fā)生了,我知識(shí)改變了vue1的實(shí)例中的數(shù)據(jù),但是其他實(shí)例的數(shù)據(jù)也發(fā)生了改變,相信很簡(jiǎn)單就能看出來(lái)這應(yīng)該是共用同一個(gè)對(duì)象的引用而導(dǎo)致的,這在開(kāi)放中是非常不友好的,開(kāi)發(fā)者很容易就產(chǎn)生連串的錯(cuò)誤,vue2也知道這種缺陷只是沒(méi)有在普通實(shí)例中去體現(xiàn)而已,只在組件中實(shí)現(xiàn)了對(duì)于data的約束

為了讓大家更好的立即為啥data必須是一個(gè)函數(shù),黑貓?jiān)诖撕?jiǎn)單實(shí)現(xiàn)一個(gè)vue的實(shí)例然后來(lái)證明為啥data是一個(gè)函數(shù),以及如果data不是一個(gè)函數(shù),我們應(yīng)該如何處理

3.證明data是函數(shù)以及原理實(shí)現(xiàn)

在實(shí)現(xiàn)簡(jiǎn)單原理之前,我們需要搞清楚Vue在創(chuàng)建實(shí)例之前,對(duì)于data到底做了什么事情簡(jiǎn)單來(lái)說(shuō)就是:

vue 在創(chuàng)建實(shí)例的過(guò)程中調(diào)用data函數(shù)返回實(shí)例對(duì)象通過(guò)響應(yīng)式包裝后存儲(chǔ)在實(shí)例的data上并且實(shí)例可以直接越過(guò)data上并且實(shí)例可以直接越過(guò)data上并且實(shí)例可以直接越過(guò)data訪問(wèn)屬性

1.通過(guò)這句描述可以知道Vue是一個(gè)構(gòu)造函數(shù),并且傳入的參數(shù)中有一個(gè)data的屬性,我們可以$data去訪問(wèn),也可以直接訪問(wèn)這個(gè)屬性,并且我們需要對(duì)這個(gè)data做代理
那么簡(jiǎn)單實(shí)現(xiàn)如下

function Vue(options) {
    this.$data = proxy(options.data())
}
function proxy(options) {
    return new Proxy(options, {
        get(target, key, value, receiver) {
            return Reflect.get(target, key, value, receiver)
        },
        set(target, key, newValue, receiver) {
            Reflect.set(target, key, newValue, receiver)
        }
    })
}
const data = function () {
    return {
        a: 'hello world'
    }
}
const vue1 = new Vue({
    data
})
const vue2 = new Vue({
    data
})
vue1.$data.a = 'hello Vue'
console.log(vue1.$data.a) // hello Vue
console.log(vue2.$data.a) // hello world

通過(guò)簡(jiǎn)單實(shí)現(xiàn)可與看出來(lái),當(dāng)我們的data是一個(gè)函數(shù)的時(shí)候,在Vue的構(gòu)造函數(shù)中,只有有實(shí)例創(chuàng)建就有執(zhí)行data函數(shù),然后返回一個(gè)特別的對(duì)象,所以當(dāng)我們修改其中一個(gè)實(shí)例的時(shí)候并不會(huì)對(duì)其他實(shí)例的數(shù)據(jù)產(chǎn)生變化

那么當(dāng)data不是一個(gè)函數(shù)呢 ,我們簡(jiǎn)單改下代碼,代碼如下

function Vue(options) {
    this.$data = proxy(options.data)
}
function proxy(options) {
    return new Proxy(options, {
        get(target, key, value, receiver) {
            return Reflect.get(target, key, value, receiver)
        },
        set(target, key, newValue, receiver) {
            Reflect.set(target, key, newValue, receiver)
        }
    })
}
const data = {
    a: 'hello world'
}
const vue1 = new Vue({
    data
})
const vue2 = new Vue({
    data
})
vue1.$data.a = 'hello Vue'
console.log(vue1.$data.a) // hello Vue
console.log(vue2.$data.a) // hello Vue

可以看出,由于共用一個(gè)對(duì)象,當(dāng)代理的時(shí)候也是對(duì)同一個(gè)對(duì)象進(jìn)行代理,那么當(dāng)我們通過(guò)一個(gè)實(shí)例去改變數(shù)據(jù)的時(shí)候,就會(huì)影響其他實(shí)例的狀態(tài)

4.如果data必須是一個(gè)對(duì)象呢?

假如有人提出如果data是一個(gè)對(duì)象,那么我們應(yīng)該如何處理呢,其實(shí)也非常簡(jiǎn)單,在代理的時(shí)候我們可以將傳入的data對(duì)象通過(guò)深拷貝即可,這樣我們就不會(huì)使用相同引用的對(duì)象啦。
[深拷貝封裝參考我以前的文章](不一樣的深拷貝)

總結(jié)

到此這篇關(guān)于Vue的data為何只能是函數(shù)的文章就介紹到這了,更多相關(guān)Vue data為何只能是函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論