站長資訊網(wǎng)
        最全最豐富的資訊網(wǎng)站

        vue組件中data為啥是函數(shù)

        原因:防止多個組件實例對象之間共用一個data,產(chǎn)生數(shù)據(jù)污染;采用函數(shù)的形式,initData時會將其作為工廠函數(shù)都會返回全新data對象。當將組件中的data寫成一個函數(shù),數(shù)據(jù)以函數(shù)返回值形式定義,這樣每復用一次組件,就會返回一份新的data,擁有自己的作用域,類似于給每個組件實例創(chuàng)建一個私有的數(shù)據(jù)空間,讓各個組件實例維護各自的數(shù)據(jù)。

        vue組件中data為啥是函數(shù)

        前端(vue)入門到精通課程,老師在線輔導:聯(lián)系老師
        Apipost = Postman + Swagger + Mock + Jmeter 超好用的API調(diào)試工具:點擊使用

        本教程操作環(huán)境:windows7系統(tǒng)、vue3版,DELL G3電腦。

        一、實例和組件定義data的區(qū)別

        vue實例的時候定義data屬性既可以是一個對象,也可以是一個函數(shù)

        const app = new Vue({     el:"#app",     // 對象格式     data:{         foo:"foo"     },     // 函數(shù)格式     data(){         return {              foo:"foo"         }     } })
        登錄后復制

        組件中定義data屬性,只能是一個函數(shù)

        如果為組件data直接定義為一個對象

        Vue.component('component1',{     template:`<div>組件</div>`,     data:{         foo:"foo"     }})
        登錄后復制

        則會得到警告信息

        vue組件中data為啥是函數(shù)

        警告說明:返回的data應(yīng)該是一個函數(shù)在每一個組件實例中

        二、組件data定義函數(shù)與對象的區(qū)別

        上面講到組件data必須是一個函數(shù),不知道大家有沒有思考過這是為什么呢?

        在我們定義好一個組件的時候,vue最終都會通過Vue.extend()構(gòu)成組件實例

        這里我們模仿組件構(gòu)造函數(shù),定義data屬性,采用對象的形式

        function Component(){   } Component.prototype.data = { 	count : 0 }
        登錄后復制

        創(chuàng)建兩個組件實例

        const componentA = new Component() const componentB = new Component()
        登錄后復制

        修改componentA組件data屬性的值,componentB中的值也發(fā)生了改變

        console.log(componentB.data.count)  // 0 componentA.data.count = 1 console.log(componentB.data.count)  // 1
        登錄后復制

        產(chǎn)生這樣的原因這是兩者共用了同一個內(nèi)存地址,componentA修改的內(nèi)容,同樣對componentB產(chǎn)生了影響。【學習視頻分享:vue視頻教程、web前端視頻】

        如果我們采用函數(shù)的形式,則不會出現(xiàn)這種情況(函數(shù)返回的對象內(nèi)存地址并不相同)

        function Component(){ this.data = this.data() } Component.prototype.data = function (){     return {    count : 0     } }
        登錄后復制

        修改componentA組件data屬性的值,componentB中的值不受影響

        console.log(componentB.data.count)  // 0 componentA.data.count = 1 console.log(componentB.data.count)  // 0
        登錄后復制

        vue組件可能會有很多個實例,采用函數(shù)返回一個全新data形式,使每個實例對象的數(shù)據(jù)不會受到其他實例對象數(shù)據(jù)的污染

        三、原理分析

        首先可以看看vue初始化data的代碼,data的定義可以是函數(shù)也可以是對象

        源碼位置:/vue-dev/src/core/instance/state.js

        function initData (vm: Component) {   let data = vm.$options.data   data = vm._data = typeof data === 'function'     ? getData(data, vm)     : data || {}     ... }
        登錄后復制

        data既能是object也能是function,那為什么還會出現(xiàn)上文警告呢?

        別急,繼續(xù)看下文

        組件在創(chuàng)建的時候,會進行選項的合并

        源碼位置:/vue-dev/src/core/util/options.js

        自定義組件會進入mergeOptions進行選項合并

        Vue.prototype._init = function (options?: Object) {     ...     // merge options     if (options && options._isComponent) {       // optimize internal component instantiation       // since dynamic options merging is pretty slow, and none of the       // internal component options needs special treatment.       initInternalComponent(vm, options)     } else {       vm.$options = mergeOptions(         resolveConstructorOptions(vm.constructor),         options || {},         vm       )     }     ...   }
        登錄后復制

        定義data會進行數(shù)據(jù)校驗

        源碼位置:/vue-dev/src/core/instance/init.js

        這時候vm實例為undefined,進入if判斷,若data類型不是function,則出現(xiàn)警告提示

        strats.data = function (   parentVal: any,   childVal: any,   vm?: Component ): ?Function {   if (!vm) {     if (childVal && typeof childVal !== "function") {       process.env.NODE_ENV !== "production" &&         warn(           'The "data" option should be a function ' +             "that returns a per-instance value in component " +             "definitions.",           vm         );       return parentVal;     }     return mergeDataOrFn(parentVal, childVal);   }   return mergeDataOrFn(parentVal, childVal, vm); };
        登錄后復制

        四、結(jié)論

        根實例對象data可以是對象也可以是函數(shù)(根實例是單例),不會產(chǎn)生數(shù)據(jù)污染情況

        組件實例對象data必須為函數(shù),目的是為了防止多個組件實例對象之間共用一個data,產(chǎn)生數(shù)據(jù)污染。采用函數(shù)的形式,initData時會將其作為工廠函數(shù)都會返回全新data對象

        說明:

        • vue中組件是用來復用的,為了防止data復用,將其定義為函數(shù)。

        • vue組件中的data數(shù)據(jù)都應(yīng)該是相互隔離,互不影響的,組件每復用一次,data數(shù)據(jù)就應(yīng)該被復制一次,之后,當某一處復用的地方組件內(nèi)data數(shù)據(jù)被改變時,其他復用地方組件的data數(shù)據(jù)不受影響,就需要通過data函數(shù)返回一個對象作為組件的狀態(tài)。

        • 當我們將組件中的data寫成一個函數(shù),數(shù)據(jù)以函數(shù)返回值形式定義,這樣每復用一次組件,就會返回一份新的data,擁有自己的作用域,類似于給每個組件實例創(chuàng)建一個私有的數(shù)據(jù)空間,讓各個組件實例維護各自的數(shù)據(jù)。

        • 當我們組件的date單純的寫成對象形式,這些實例用的是同一個構(gòu)造函數(shù),由于JavaScript的特性所導致,所有的組件實例共用了一個data,就會造成一個變了全都會變的結(jié)果。

        (學習視頻分享:web前端開發(fā)、編程基礎(chǔ)視頻)

        贊(0)
        分享到: 更多 (0)
        網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
        主站蜘蛛池模板: 国产精品亚洲аv无码播放| 欧美+亚洲+精品+三区| 国产精品视频一区二区三区四 | 91人妻人人澡人人爽人人精品| 日韩精品少妇无码受不了| 欧美日韩国产精品| 国产精品狼人久久久久影院| 51视频国产精品一区二区| 日韩精品一区二区亚洲AV观看 | 国产欧美日本亚洲精品一5| 99视频在线观看精品| 久久久久久夜精品精品免费啦| 国产成人精品亚洲精品| 精品视频无码一区二区三区| 亚洲А∨精品天堂在线| 精品福利一区二区三区| 欧美国产日韩精品| 55夜色66夜色国产精品视频| 久久99精品久久久久久久久久| 亚洲精品自在在线观看| 亚洲精品视频免费| 欧美日韩国产精品系列| 久久久亚洲精品蜜桃臀| 久久精品国产亚洲AV不卡| 精品国产一级在线观看| 久久99精品九九九久久婷婷| 国产在线精品一区二区夜色 | 久久精品人人槡人妻人人玩AV| 亚洲精品成人区在线观看| 女人高潮内射99精品| 欧美日韩国产中文精品字幕自在自线 | 精品一卡2卡三卡4卡免费视频| 国产成人亚洲合集青青草原精品 | 久久久无码精品午夜| 欧美午夜精品久久久久久浪潮| 精品国产免费一区二区三区| 国产精品亚洲美女久久久| 国产精品青草视频免费播放| 国产三级精品三级在线观看| 精品中文高清欧美| 四虎精品影库4HUTV四虎|