浅析vue2中data是函数的原因
2024-12-09 11:13:16

vue玩家的经典面试题,之前入职面试时候回答的还不错,但事后感觉我自己感觉不太详细,于是这里仔细整理一下。

正文

其实,所有的回答只绕着一句话来回答。

1
data是函数,是为了解决vue组件复用时,实例中声明的变量会混乱。

官方定义

Vue 实例的数据对象。

Vue 会递归地把 data 的 property 转换为 getter/setter,从而让 data 的 property 能够响应数据变化。

当一个组件被定义,data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。

说的挺明白的,但是毕竟不是自己的理解。

个人理解

在正式开始之前,我们先附上官网提供的经典例子,这个例子其实足够直观的可以让我们明白,为什么data必须是一个函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var data = { a: 1 }

// 直接创建一个实例
var vm = new Vue({
data: data
})
vm.a // => 1
vm.$data === data // => true

// Vue.extend() 中 data 必须是函数
var Component = Vue.extend({
data: function () {
return { a: 1 }
}
})

为什么不用属性

首先我们需要了解data两种不同的类型有什么区别:

  • 当我们组件中的data写成一个函数时,数据是以函数返回值形式定义的,这样每复用一次data,都会返回一份新的data,拥有自己的作用域,不会产生数据污染。
  • 当我们组件中的data写成一个对象时,对象是引用数据类型,它就会共用一个内存地址,在多次使用该组件时,改变其中一个组件的值会影响全部使用该组件的值。

使用函数就是用闭包独立了变量的作用域,在函数的作用域中声明的变量,自然不会混用,所以不会被修改。

而如果是属性,一个组件可能会被其他的组件引用,为了防止多个组件实例对象之间共用一个data,产生数据污染。

vue文件,在被编译后,每个vue文件都是声明出的实例,每个实例都有自己的作用域。

而在vue中将data定义成一个函数,每个组件实例在每次声明之后,都会用函数声明自己的独立作用域,每个实例相互独立,不会相互影响initData时会将其作为工厂函数都会返回全新data对象。

为什么不用箭头函数

箭头函数的作用域是指向上级对象,本质上还是会将声明的变量指到实例根部。

data通过箭头函数声明出来,实际上和直接挂在vue实例上没什么区别,依旧会造成数据污染。

因此,我们拒绝使用箭头函数的原因,实际上和对象如此。

结语

这是一个经典面试题,经典到从vue出来的时代中就会被问到,只要对前端稍微熟练的开发者,都能明白怎么回答。

但是经典不代表没有花样,我这里也是根据自己的理解浅浅写了一下,可能说的不够简单,希望轻喷。

参考

vue2官网_data属性

组件中的 data 为什么必须是一个函数呢?

前端面试:vue组件中data为什么是函数?对象不行吗?你应该这么说……