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

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

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

前言

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

參考 (vue2data描述)

參考: (vue3data描述)

1.Vue3中的data

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

可以看到上來vue就給了警告說明data必須是一個函數(shù) 下面直接拋錯

2.vue中的data

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

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

<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
})

這樣在頁面中會顯示2個內(nèi)容為hello world的div標簽 那么當我們通過實例去改變messag呢?

 vue1.message = 'hello Vue'

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

為了讓大家更好的立即為啥data必須是一個函數(shù),黑貓在此簡單實現(xiàn)一個vue的實例然后來證明為啥data是一個函數(shù),以及如果data不是一個函數(shù),我們應該如何處理

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

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

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

1.通過這句描述可以知道Vue是一個構(gòu)造函數(shù),并且傳入的參數(shù)中有一個data的屬性,我們可以$data去訪問,也可以直接訪問這個屬性,并且我們需要對這個data做代理
那么簡單實現(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

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

那么當data不是一個函數(shù)呢 ,我們簡單改下代碼,代碼如下

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

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

4.如果data必須是一個對象呢?

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

總結(jié)

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

相關(guān)文章

  • vue3+ts 兄弟組件之間傳值的實現(xiàn)

    vue3+ts 兄弟組件之間傳值的實現(xiàn)

    Vue3是一款流行的前端框架,它支持多種傳值方式,包括兄弟組件之間的傳值,本文主要介紹了vue3+ts 兄弟組件之間傳值的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2023-11-11
  • 淺談vue3在項目中的邏輯抽離和字段顯示

    淺談vue3在項目中的邏輯抽離和字段顯示

    本文主要介紹了vue3在項目中的邏輯抽離和字段顯示,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Nuxt3項目搭建過程(Nuxt3+element-plus+scss詳細步驟)

    Nuxt3項目搭建過程(Nuxt3+element-plus+scss詳細步驟)

    這篇文章主要介紹了Nuxt3項目搭建(Nuxt3+element-plus+scss詳細步驟),本次記錄一次使用Nuxt3搭建前端項目的過程,內(nèi)容包含Nuxt3的安裝,基于Vite腳手架(默認)構(gòu)建的vue3項目,element-plus的安裝配置,scss的安裝,目錄結(jié)構(gòu)的創(chuàng)建和解釋,需要的朋友可以參考下
    2022-12-12
  • vuex mutations 同步操作方法詳解

    vuex mutations 同步操作方法詳解

    這篇文章主要介紹了vuex mutations 同步操作方法,需要的朋友可以參考下
    2023-10-10
  • Ant Design Vue pro 動態(tài)路由的實現(xiàn)和打包方式

    Ant Design Vue pro 動態(tài)路由的實現(xiàn)和打包方式

    這篇文章主要介紹了Ant Design Vue pro 動態(tài)路由的實現(xiàn)和打包方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • vue遠程加載sfc組件思路詳解

    vue遠程加載sfc組件思路詳解

    這篇文章主要介紹了vue遠程加載sfc組件思路詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-12-12
  • vue開發(fā)中數(shù)據(jù)更新但視圖不刷新的解決方法

    vue開發(fā)中數(shù)據(jù)更新但視圖不刷新的解決方法

    在開發(fā)中我們處理數(shù)據(jù)時會遇到數(shù)據(jù)更新了,但視圖并沒有更新,這種情況往往是數(shù)據(jù)嵌套層數(shù)過多導致的問題,下面這篇文章主要給大家介紹了關(guān)于vue開發(fā)中數(shù)據(jù)更新但視圖不刷新的解決方法,需要的朋友可以參考下
    2022-11-11
  • 詳解Vue + Vuex 如何使用 vm.$nextTick

    詳解Vue + Vuex 如何使用 vm.$nextTick

    這篇文章主要介紹了詳解Vue + Vuex 如何使用 vm.$nextTick,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • Vue MVVM模型超詳細講解

    Vue MVVM模型超詳細講解

    MVVM是Model-View-ViewModel的縮寫,MVVM是一種設計思想,這篇文章主要介紹了Vue生命周期和MVVM框架,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-11-11
  • Vue寶典之this.$refs屬性的使用

    Vue寶典之this.$refs屬性的使用

    Vue.js中的refs屬性是一個非常有用的特性,它允許我們在組件中操作 DOM 元素和組件實例,本文來介紹一下Vue寶典之this.$refs屬性的使用,感興趣的可以了解一下
    2023-12-12

最新評論

宜兰市| 毕节市| 渭南市| 都江堰市| 出国| 松阳县| 梁河县| 秦皇岛市| 建宁县| 新邵县| 五华县| 会东县| 蒲江县| 琼海市| 大余县| 资源县| 昆山市| 乌拉特中旗| 宁阳县| 房产| 越西县| 拜城县| 白玉县| 黄冈市| 大石桥市| 龙江县| 宝坻区| 来宾市| 土默特右旗| 青冈县| 屏东县| 永兴县| 卓资县| 紫金县| 岢岚县| 巴中市| 兴隆县| 阳新县| 行唐县| 永新县| 尼木县|