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

        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號
        主站蜘蛛池模板: 国产精品国产三级国产AⅤ| 久久性精品| 国产精品片在线观看手机版| 亚洲AV无码精品色午夜在线观看| 国产va免费精品| 2022国产精品自产拍在线观看| 日韩熟女精品一区二区三区| 99久久亚洲综合精品网站| 国产精品特级毛片一区二区三区 | 亚洲韩精品欧美一区二区三区| 亚洲国产精品人久久| 99在线精品视频观看免费| 亚洲中文久久精品无码| 人妻少妇精品系列| 国产欧美日本精品| 91精品国产91久久| 久久精品www| 国内精品伊人久久久久| 无码人妻精品中文字幕免费| 久久久精品人妻无码专区不卡| 亚洲精品理论电影在线观看| 91麻豆精品视频| 97精品久久天干天天天按摩| 久久精品国产亚洲AV嫖农村妇女| 亚洲精品无码成人片久久| 日本精品一区二区三区在线视频| 久久精品国产亚洲av瑜伽| 精品福利一区二区三区| 国产精品乱伦| 国产精品福利电影一区二区三区四区欧美白嫩精品 | 亚洲国产精品ⅴa在线观看| 久久www免费人成精品香蕉| 国产亚洲精品不卡在线| 国产精品亚洲一区二区在线观看| 91久久精品国产免费直播| 91精品国产高清久久久久久91| 久久99精品国产麻豆宅宅| 日本精品在线视频| 国产福利电影一区二区三区,欧美国产成人精品一 | 国产美女久久精品香蕉69| 国产精品久久久久国产A级|