组件的 data 为什么通常是函数?

先理解原理和示例,再练习完整口述与追问。

同一个组件定义会被创建为多个实例,每次返回新对象可以隔离状态。若每次返回的对象内部仍引用同一个外部对象,这部分依然可能共享。SSR 的状态还要按请求隔离。

组件定义会被多个实例复用,如果实例直接指向同一个状态对象,修改一份表单就会影响其他实例。data 函数在实例初始化时调用,返回新对象用于隔离状态。隔离必须覆盖需要独立的嵌套对象;只返回一个新外壳却继续引用模块顶层默认对象,仍会共享内部字段。

js
const createForm = () => ({ name: '', address: { city: '' } })
export default {
  data() { return { form: createForm() } },
  methods: { reset() { this.form = createForm() } }
}

每次创建或重置时都会生成独立 address。SSR 中 Vuex 的 state 也应按请求通过工厂创建,避免不同用户复用同一状态。

不要把 data:() => sharedForm 误认为已经隔离。JSON 深拷贝不是所有默认值的通用解决方案;定义清楚的初值工厂往往更简单。

组件可以创建多个实例,data 函数每次返回新对象,能让每个实例拥有独立状态。如果直接共用对象,一个实例编辑表单,另一个也可能被影响。这里关键是返回的对象及需要独立的嵌套数据确实重新创建,不能表面返回新壳,内部仍引用同一份模块级数据。SSR 的用户状态同样要每个请求独立创建。

面试官可能继续问追问与完整解答展开收起

把默认表单对象放到模块顶层,重置时直接赋给组件,为什么会串数据?

把模块级 defaultForm 直接赋给多个实例,会共享同一引用;只浅拷贝外层也可能共享地址等嵌套对象。可用 createDefaultForm() 每次生成完整初始结构,重置和新建时调用它;需要从已有记录生成草稿时,按真实字段结构复制。