Vue-组件的data属性为什么必须是函数?

By
写代码

一般在公司环境使用中,各种前端框架都会用一下,因为不同框架理念和使用场景有些许区别,有的重规模化,有的追求轻便易上手;有的模块化程度很高,有的通常全部写一起;有的规则安排的明明白白,有的又需要各种语法糖……虽然最近几个月工作特别忙,但是还是拿出了一点点时间来扩充一下Vue的背景知识。

为什么组件的data属性必须是函数?

在自定义模块的新手上路部分,Vue文档是这么写的

通过 Vue 构造器传入的各种选项大多数都可以在组件里用。data 是一个例外,它必须是函数。如果定义了一个对象,那么 Vue 会停止,并在控制台发出警告,告诉你在组件中 data 必须是一个函数。

有一点觉得很奇怪,明明new Vue()的时候,data是可以传入一个对象的,为什么在组件这里,data就必须为函数了呢?

简而言之,组件的配置(options)和实例(instance)是需要分开的。最根本原因是js对于对象(以及数组等)是传引用的,因为如果直接写一个对象进去,那么当依此配置初始化了多个实例之后,这个对象必定是多个实例共享的。

举两个例子就明白了

例子1

例子2

为了加深印象,还是把相关部分都扯一点。

组件(Component)定义方式

写完hello world的同学都知道,组件在定义的时候,可以全局(Vue.component())或者局部注册

两种方法并没有本质区别,都需要在data属性里传入对象。局部注册只是放在了new Vueoptions处理部分,仍然是Vue.extend(definition)里判断。

下面以全局注册为例过一遍Vue源码。

前面说的报错位置在这里

这个函数简单来说,是负责data字段内容处理的,不管是new Vue的参数里data还是组件初始化的data,都要经过这里。

简单起见,从这个位置往上倒(二声)到开头:

到这一步结束,按照_assetTypes(包括'component','directive','filter')挂载方法。这里挂载了Vue.component的初始化方法,但还没调用。

经过一众其他内部操作。直到执行我们的代码(组件是从官方文档抄过来的)

definition内容:

写入组件的配置:

这一步就是前面报错的那一步,会判断data是否为函数,是则执行并挂载函数方法。否则返回父级属性。

vue-component-config

组件挂载结果
看起来3个_assetTypes加了s,是在代码里搞的

在实际使用时,才会初始化组件,即调用

初始化Vue实例时的处理

new Vue的时候,也会调用mergeOptions,不同的是这时候传入了vm实例。这时在mergeField('data')里走了另外一条路线:

您已经发表过意见了!

Comments: 1

  1. 非技术的路过。

    2019年08月08日

发表评论

您的电子邮箱地址不会被公开。

*

:razz: