站長資訊網
最全最豐富的資訊網站

vue初始化data方法有哪些

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

vue初始化data方法有哪些

本教程操作環境:windows7系統、vue3版,DELL G3電腦。

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

data初始化

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

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

  • function

  • object

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

源碼分析

按照官網demo,Vue.extend中的data初始化不能是Object,如果我們強制寫成Object會出現什么?

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

運行以后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.
登錄后復制

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

// vue.extend 源碼地址https://github.com/vuejs/vue/blob/dev/src/core/global-api/extend.js    Vue.extend = function (extendOptions: Object): Function {   ...   // 在這里會觸發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對象內包含components、filter,、directive   for (key in parent) {     mergeField(key)   }   // child對象內對應的是Vue.extend內定義的參數   for (key in child) {     if (!hasOwn(parent, key)) {       mergeField(key)     }   }   function mergeField (key) {   // 這一步是根據傳入的key找到不同的合并策略filter、components、directives用到合并策略是這個方法mergeAssets和data用到的不一樣,當合并到data的時候會進入專屬的合并策略方法內     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) };
登錄后復制

其他情況

其實我們上述代碼只是一個簡單的流程,在實際開發中同類情況有:子組件內、路由內都不可以把data定義為一個對象,因為他們底層都調用了mergeOptions方法

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

在vue初始化的時候,如下

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

意義

ok,上面說了那么多,那么這么做的意義是什么?為什么那幾種情況不可以定義為對象? 其實回答這個問題,需要回到js本身,眾所周知js數據類型分為引用和基本,引用類型包含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"
登錄后復制

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

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

  • deepClone(obj)

但是這兩種做法需要開發或者框架每一次都要深copy一次,當數據量大的時候對性能什么都不友好,那么Vue怎么做的呢?把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'
登錄后復制

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

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

擴展知識:

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

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

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

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

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

則會得到警告信息

vue初始化data方法有哪些

說明:

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

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

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

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

贊(0)
分享到: 更多 (0)
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
日韩成视频在线观看| 2022国产精品福利在线观看| 一区精品麻豆入口| 日韩人妻无码精品久久免费一 | 国产亚洲精品欧洲在线观看| 精品无码久久久久久国产 | 亚洲国产日韩精品| 国产精品观看在线亚洲人成网| 亚洲国产成人久久精品软件| 国产成人精品怡红院| 国产成人精品男人的天堂538| 91精品国产肉丝高跟在线| 久久精品天天中文字幕人妻 | 欧美精品久久天天躁| 伊人久久精品无码麻豆一区| 亚洲精品国产日韩| 亚洲精品无码久久久久久久 | 亚洲日韩中文无码久久| 日韩网站在线观看| 国产精品亚洲A∨天堂不卡| 日韩深夜福利视频| 欧美日韩精品SUV| 国产精品无码日韩欧| 国产精品白丝在线观看有码| 精品国产日韩亚洲一区| 亚洲欧洲精品成人久久奇米网| 国产在热线精品视频| 亚洲午夜久久久精品影院| 精品999久久久久久中文字幕| 国产麻豆9l精品三级站| 一本一本久久A久久综合精品| 国产成人精品日本亚洲专区61| 中文字幕九七精品乱码| 亚洲欧洲成人精品香蕉网| 久久国产精品-国产精品| 亚洲国产精品SSS在线观看AV| 久久精品国产99精品国产2021| 国产精品日韩欧美一区二区三区| 国产精品国语对白露脸在线播放| 亚洲a∨无码精品色午夜| 亚洲国产精品成人AV在线|