vue训练营2 --- Vue组件data选项为什么必须是个函数而Vue的根实例则没有此限制

源码中找答案:src\core\instance\state.js - initData()

function initData (vm: Component) {

  let data = vm.$options.data

  /*

      先判断 data 的类型

      如果data类型是 函数,则执行data函数,并将其结果作为data选项的值,

      否则使用用户设置的 data

  */

  data = vm._data = typeof data === 'function'

    ? getData(data, vm)

    : data || {}

  if (!isPlainObject(data)) {

    data = {}

    process.env.NODE_ENV !== 'production' && warn(

      'data functions should return an object:\n' +

      'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',

      vm

    )

  }

  // proxy data on instance

  // 代理这些数据到实例上

  const keys = Object.keys(data)

  const props = vm.$options.props

  const methods = vm.$options.methods

  let i = keys.length

  while (i--) {

    const key = keys[i]

    if (process.env.NODE_ENV !== 'production') {

      if (methods && hasOwn(methods, key)) {

        warn(

          `Method "${key}" has already been defined as a data property.`,

          vm

        )

      }

    }

    if (props && hasOwn(props, key)) {

      process.env.NODE_ENV !== 'production' && warn(

        `The data property "${key}" is already declared as a prop. ` +

        `Use prop default value instead.`,

        vm

      )

    } else if (!isReserved(key)) {

      proxy(vm, `_data`, key)

    }

  }

  // observe data

  // 执行递归处理

  observe(data, true /* asRootData */)

}

 

 

测试代码:

<body>

    <div id="demo">

        <h1>vue组件data为什么必须是个函数? </h1>
        <comp></comp>

        <comp></comp>

    </div>

    <script src="../../dist/vue.js"></script>

    <script>

        Vue.component('comp', {

            template:'<div @click="counter++">{{counter}}</div>',             data: {counter: 0}

        })

        // 创建实例

        const app = new Vue({

            el: '#demo',

        });

    </script>

</body>

 

结论: 

1. Vue.component 创建组件时,只会执行一次,当组件调用多次,多实例时,如果返回的是对象,则会导致多实例共用一个data对象,那么当状态变更时,会影响所有组件实例,造成数据污染。所以必须使用工厂函数返回数据。

2.根组件因为是单例,所以没有此限制,data直接返回对象就可以。

3.通过源码可以看到,在初始化数据时,会先判断 data 的类型, 如果data类型是 函数,则执行data函数,并将其结果作为data选项的值,否则使用用户设置的 data。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值