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

        vue初始化data方法有哪些

        vue初始化data方法有兩種:1、object方式,語法“var data = { 鍵值對 }”;2、function方式,語法“data: function () {return { 鍵值對 }}”。需要注意組件和extend中的data初始化不能是Object,否則會報錯。組件中data用function方式是為了防止多個組件實(shí)例對象之間共用一個data,產(chǎn)生數(shù)據(jù)污染。

        vue初始化data方法有哪些

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

        vue data有兩種初始化的方式,function和object,但是這兩種情況適用場景有哪些?能不能通用?帶著這兩個問題咱們一起分析下

        data初始化

        // 代碼來源于官網(wǎng)示例  // 第一種定義方式 var data = { a: 1 }  // 直接創(chuàng)建一個實(shí)例 var vm = new Vue({   data: data })  // Vue.extend() 中 data 必須是函數(shù) var Component = Vue.extend({ // 第二種定義方式   data: function () {     return { a: 1 }   } })
        登錄后復(fù)制

        上述代碼簡單描述了data定義的兩種方式

        • function

        • object

        官網(wǎng)demo中也著重說了extend中data初始化不能用object。那么為什么呢?

        源碼分析

        按照官網(wǎng)demo,Vue.extend中的data初始化不能是Object,如果我們強(qiáng)制寫成Object會出現(xiàn)什么?

        var Component = Vue.extend({   data: { a: 1 } })
        登錄后復(fù)制

        運(yùn)行以后chrome的consolo直接報錯,信息如下

        vue.esm.js?efeb:591 [Vue warn]: The "data" option should be a function that returns a per-instance value in component definitions.
        登錄后復(fù)制

        通過分析源碼以及報錯信息,當(dāng)觸發(fā)Vue.extend的時候,他會做一個合并操作,把一個基礎(chǔ)組件(里面vmode, transtion等)和你定義在extend內(nèi)的信息,通過mergeField往options上合并,當(dāng)合并到data的時候,他會觸發(fā)strats.data,在這個里面會check data是不是一個function,這里需要注意的是filter、components等和data走的是兩套合并流程,詳細(xì)的請看代碼注釋,如下

        // vue.extend 源碼地址https://github.com/vuejs/vue/blob/dev/src/core/global-api/extend.js    Vue.extend = function (extendOptions: Object): Function {   ...   // 在這里會觸發(fā)mergeOptions方法   Sub.options = mergeOptions(       Super.options,       extendOptions     )   ... }  // mergeOptions 源碼地址https://github.com/vuejs/vue/blob/dev/src/core/util/options.js  export function mergeOptions (   parent: Object,   child: Object,   vm?: Component ): Object {   ...    const options = {}   let key   // parent對象內(nèi)包含components、filter,、directive   for (key in parent) {     mergeField(key)   }   // child對象內(nèi)對應(yīng)的是Vue.extend內(nèi)定義的參數(shù)   for (key in child) {     if (!hasOwn(parent, key)) {       mergeField(key)     }   }   function mergeField (key) {   // 這一步是根據(jù)傳入的key找到不同的合并策略filter、components、directives用到合并策略是這個方法mergeAssets和data用到的不一樣,當(dāng)合并到data的時候會進(jìn)入專屬的合并策略方法內(nèi)     const strat = strats[key] || defaultStrat     options[key] = strat(parent[key], child[key], vm, key)   } }  // strats.data  源碼地址https://github.com/vuejs/vue/blob/dev/src/core/util/options.js strats.data = function (   parentVal,   childVal,   vm ) {   if (!vm) {   // 如果data不是function的話會直接走下面的報錯信息     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) };
        登錄后復(fù)制

        其他情況

        其實(shí)我們上述代碼只是一個簡單的流程,在實(shí)際開發(fā)中同類情況有:子組件內(nèi)、路由內(nèi)都不可以把data定義為一個對象,因?yàn)樗麄兊讓佣颊{(diào)用了mergeOptions方法

        什么時候可以定義成一個對象

        在vue初始化的時候,如下

        new Vue({   data: {     linke: '//sinker.club'   } })
        登錄后復(fù)制

        意義

        ok,上面說了那么多,那么這么做的意義是什么?為什么那幾種情況不可以定義為對象? 其實(shí)回答這個問題,需要回到j(luò)s本身,眾所周知js數(shù)據(jù)類型分為引用和基本,引用類型包含Object, Array, Function,何為引用類型就不在這里闡述了

          var obj = {link: '//www.sinker.club'}   var obj2 = obj   var obj3 = obj   obj2.link = "//gitlab.sinker.club"   console.log(obj3.link) // "//gitlab.sinker.club"
        登錄后復(fù)制

        上述代碼反應(yīng)了一個問題,由于obj3和obj2在內(nèi)存中都是指向一個地址,那么obj2的修改會影響到obj3,當(dāng)然處理這種問題可以用深copy來做到

        • JSON.parse(JSON.stringify(obj))

        • deepClone(obj)

        但是這兩種做法需要開發(fā)或者框架每一次都要深copy一次,當(dāng)數(shù)據(jù)量大的時候?qū)π阅苁裁炊疾挥押茫敲碫ue怎么做的呢?把data定義成一個function

        function data() {   return {    link: '//sinker.club'   } }  var obj = test() var obj2 = test()  obj2.link ="//gitlab.sinker.club" console.log(obj.link) '//sinker.club'
        登錄后復(fù)制

        為什么這么做?解決的場景是什么呢?

        比如我定一個子組件,data是按照對象的方式定義的,這個組件在多個地方引用,如果其中一個引用此組件的data修改了,那么就會造成其余引用此組件的data同時改變, end.

        擴(kuò)展知識:

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

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

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

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

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

        則會得到警告信息

        vue初始化data方法有哪些

        說明:

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

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

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

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

        贊(0)
        分享到: 更多 (0)
        網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
        主站蜘蛛池模板: 国产三级国产精品国产普男人 | 蜜臀AV无码国产精品色午夜麻豆| 亚洲高清专区日韩精品| 影音先锋国产精品国语对白| 亚洲精品V欧洲精品V日韩精品 | 中文字幕一区二区精品区| 久久久久成人精品无码中文字幕| 国产精品麻豆VA在线播放| 国产日韩精品中文字无码| 亚洲国产精品成人久久蜜臀 | 久久精品国产99国产精偷| 国产精品天干天干综合网| 无夜精品久久久久久| 国产精品第1页| 国产精品天天影视久久综合网| 亚洲精品乱码久久久久久久久久久久| 日韩麻豆国产精品欧美| 久久99热只有频精品8| 无翼乌无遮挡全彩老师挤奶爱爱帝国综合社区精品 | 夜夜爽一区二区三区精品| 亚洲精品视频在线| 99精品国产在热久久| 一本久久a久久精品vr综合| 国产精品无码国模私拍视频 | 欧美精品色精品一区二区三区| 欧美日韩精品乱国产538| 精品无码国产自产拍在线观看| 无码精品人妻一区二区三区AV| 国产精品.XX视频.XXTV| 东京热TOKYO综合久久精品| 久久精品国产亚洲av影院 | 国产精品视频全国免费观看| 亚洲AV成人精品日韩一区18p| 91精品国产自产在线观看| 国产成人精品视频一区二区不卡 | 四虎国产精品永久地址51| 精品一区二区三区东京热| 亚洲国产精品自在拍在线播放 | 凹凸69堂国产成人精品视频| 无码精品国产VA在线观看| 日韩人妻无码精品一专区|