这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战
问题
如果你正在写或者写过vue的组件,应该对组件下面的data不陌生,官方要求组件的data必须是函数。如果你使用的是对象,则控制台会报错。
export default {
data: {
name: '答案cp3'
},
mounted () {
console.log(this.name)
}
}
报错而且打印的name是undefined
。
export default {
data () {
return {
name: '答案cp3'
}
},
mounted () {
console.log(this.name)
}
}
为什么vue要对data限制为函数?
因为vue的组件是会复用的,如果你的data是对象的话,你在其中一个组件修改了data的值,另外一个组件获取到的data是修改后的值,并不是初始值。这样就不能保证组件的data数据的唯一性。
而如果你的data是函数的话,data函数执行后返回的是初始值,并不会受到影响。
下面通过一个模拟例子来说明:
模拟data是对象的情况:
const data = {i: 0}
class Component {
constructor () {
this.data = data
}
add () {
this.data.i++
}
show() {
console.log(this.data.i)
}
}
const componentA = new Component()
const componentB = new Component()
const componentC = new Component()
componentA.add()
componentB.add()
console.log(componentC.show()) // 2
模拟data是函数的情况:
const data = () => {return {i: 0}}
class Component {
constructor () {
this.data = data()
}
add () {
this.data.i++
}
show() {
console.log(this.data.i)
}
}
const componentA = new Component()
const componentB = new Component()
const componentC = new Component()
componentA.add()
componentB.add()
console.log(componentC.show()) // 0
可以看到
第一个受到了新建实例的影响,输出了叠加后的值。
第二个就没有受到影响,还是保持原始值。
额外补充
上面说的是组件的data定义的时候必须是函数类型,但是在根实例并不会有这个限制,它可以是对象类型。
<div id="app">
{{msg}}
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
msg: 'hello world'
}
})
console.log(vm)
</script>
这是因为vue中根实例是不会被复用的,只有组件才会被复用,所以根实例不会有这种情况。
在vue3中,不论是根实例还是组件, data都已经限制必须是函数了。