关于vue中data需要使用闭包返回的原因

Vue.js: Why Components’ Data Properties Must Be Functions

Published on May 2, 2017 by Bo Andersen

I previously mentioned that with components, the data property must be a function and not an object as we are used to. I have opened up an example of a component which contains a button.

<div id="app">
	<counter></counter>
</div>
Vue.component('counter', {
	template: `
		<div>
			<button @click="counter++">{{ counter }}</button>
		</div>
	`
});

new Vue({
	el: '#app'
});

When clicking it, I want to increase a data property, which I haven’t added yet. Now I want to show you why adding an object for the data property won’t work, so I’ll just go ahead and add an object.

 

Vue.component('counter', {
	template: `
		<div>
			<button @click="counter++">{{ counter }}</button>
		</div>
	`,
	data: {
		counter: 0
	}
});

If we open the browser’s console, we can see that Vue issues a warning that the property must contain a function, and the component doesn’t work either.

Alright, so that clearly didn’t work. Let’s change the property to be a function instead, then.

Vue.component('counter', {
	template: `
		<div>
			<button @click="counter++">{{ counter }}</button>
		</div>
	`,
	data: function() {
		return {
			counter: 0
		};
	}
});

Now the component works. But let’s try to move the object out of the component and into a variable.

var data = {
	counter: 0
};

And then return this object within the data property’s function.

data: function() {
	return data;
}

Let’s run the code again.

Seems to work, doesn’t it? Clicking the button correctly increases the counter.

Let’s see what happens if we add the component to the page a couple of times more.

<div id="app">
	<counter></counter>
	<counter></counter>
	<counter></counter>
</div>

Let’s see what happens if I click one of the buttons now.

Notice how all of the numbers on the buttons changed. This is because all three instances of the component share the same data object, because when Vue invokes the function to retrieve the object, I return a reference to the same data object each time. This is what Vue tries to prevent by having us return an object within a function. In this case I just worked my way around it just to show you the problem.

Let’s now fix it by returning a new object within the function, so that every time it’s called, a fresh object is returned. This will mean that each component instance is self-contained as it should be and will contain its own internal state.

Vue.component('counter', {
	template: `
		<div>
			<button @click="counter++">{{ counter }}</button>
		</div>
	`,
	data: function() {
		return {
			counter: 0
		};
	}
});

Clicking the buttons verifies that it works as intended now.

So requiring that the data property contains a function, is really just a precaution that Vue takes for us to prevent us from messing up and doing bad things where components do not have their own state. And, unless you hack around it, Vue will catch you making the mistake.

So to summarize, the data property should be a function in the context of components, and this function should always return a fresh object.

 

转载于:https://my.oschina.net/u/2963099/blog/1791845

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值