4.Vue2 data为什么是一个函数而不是一个对象?

本文详细比较了Vue实例与组件在data定义上的区别,涉及实例挂载、组件通信方式,以及组件数据的函数式与对象式定义原理。还探讨了组件创建时的数据合并和数据检验过程。
摘要由CSDN通过智能技术生成

1.实例与组件定义data的区别

1.1首先我们得分清楚啥是Vue实例,啥是组件?

vue 实例代表着整个 Vue 应用程序。它可以管理整个应用程序的状态,包括所有的组件、模板等。而 vue 组件实例只代表一个组件。每个组件都拥有自己的独立作用域,这意味着我们必须在组件之间传递参数来共享状态。

vue 实例可以挂载到任何 HTML 元素上,并绑定该元素上的事件。 而组件实例不能够直接被挂载,只能放在组件标签中使用。
在 vue 组件中,父组件可以通过 props 属性将数据传递给子组件进行渲染,并在子组件触发事件时更新父组件的数据。而在 vue 实例中,没有父子关系,但是不同的实例之间可以通过 EventBus 或 Vuex 等方式进行通信。

总的说就是实例中有el属性挂载指定的元素,而组件没有,只能通过调用组件名渲染

vue实例的html元素是直接渲染到页面中,而组件的html元素是定义在template上,通过调用再渲染到页面

1.2 定义data的区别

实例定义data可以是一个函数,也可以是一个对象

组件定义data只能是一个函数,否则会报错

2.组件函数式与对象式data的区别

在我们定义一个组件时,vue最终都会通过vue.extend()构成组件实例,由于一个组件可能会有多个实例,采用函数返回一个全新的data形式,使得每个实例对象之间的数据相互间不受影响。而根实例是单例,不会出现多个实例对象,因此不存在数据污染情况。

3.原理分析

源码位置:/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 || {}
    ...
}

组件在创建的时候,会进行选项的合并

源码位置:/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时会进行数据检验

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

这时候vm实例是undefined,进入if判断,若data不是函数类型,则报错

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);
};
  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值