Vue组件为什么必须是function
Vue组件为什么必须是function
在最初的Vue实例中,我们所定义的data都是以对象的形式定义,但是在组件中,Vue却告诉我们需要使用function来定义一个data,究竟组件中的data和平时所用的data有和区别呢?
组件data定义为对象会有什么问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vueApp</title>
</head>
<body>
<div id="app">
<counter></counter>
<counter></counter>
<counter></counter>
</div>
<template id="tmp1">
<div>
<input type="button" value="+1" @click="increment">
<h3>{{count}}</h3>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var dataObj = {
count: 0
};
Vue.component("counter", {
template: "#tmp1",
data: {
count: 0
},
// data: function () {
// // return dataObj;
// return {
// count: 0
// }
// },
methods: {
increment() {
this.count++;
}
}
});
var app = new Vue({
el: "#app",
data: {
},
methods: {
},
});
</script>
</body>
</html>
警告:
可以看到当我们直接在组件中定义data为对象时,会有警告说组件中的data应该是一个返回每个即时值的function函数,也就是说每个组件中的data都必须是一个函数,并且返回的值必须是即时生成的,而不是引用外部的。
data定义为函数,但是引用外部数据会有什么问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vueApp</title>
</head>
<body>
<div id="app">
<counter></counter>
<counter></counter>
<counter></counter>
</div>
<template id="tmp1">
<div>
<input type="button" value="+1" @click="increment">
<h3>{{count}}</h3>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var dataObj = {
count: 0
};
Vue.component("counter", {
template: "#tmp1",
// data: {
// count: 0
// },
data: function () {
return dataObj;
// return {
// count: 0
// }
},
methods: {
increment() {
this.count++;
}
}
});
var app = new Vue({
el: "#app",
data: {
},
methods: {
},
});
</script>
</body>
</html>
可以看到控制台没有报错,说明这么写语法上是没有问题的,但是当我们复用该组件的时候会发现,因为公用一个对象,所以他们的数据会保持同步,从而失去了使用组件的意义。我们使用组件就是为了同样的代码和不同的数据,从而提高开发的效率。因此在组件的数据就必须是即时生成的局部变量,而非引用同一个外部变量。
组件data的正确定义方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vueApp</title>
</head>
<body>
<div id="app">
<counter></counter>
<counter></counter>
<counter></counter>
</div>
<template id="tmp1">
<div>
<input type="button" value="+1" @click="increment">
<h3>{{count}}</h3>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var dataObj = {
count: 0
};
Vue.component("counter", {
template: "#tmp1",
// data: {
// count: 0
// },
data: function () {
// return dataObj;
return {
count: 0
}
},
methods: {
increment() {
this.count++;
}
}
});
var app = new Vue({
el: "#app",
data: {
},
methods: {
},
});
</script>
</body>
</html>
可以看到使用函数定义的data,就是一个局部变量,即使使用同一个组件模板在html中使用多次,内部的data也互不影响。因此,Vue组件中的data必须是一个function