0%

【009】Vue基础学习:组件基础(一)

基本示例

  1. 在Vue中,组件是一个很强大的功能,组件可以扩展HTML元素,封装可重用的代码。比如在页面中的某一部分需要在多个场景中使用,那么我们可以将需要部分提取出来,从而提高代码的复用率。
  2. 所有的Vue组件都是Vue的实列,因此它可以接受Vue中的所有的生命周期钩子。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>组件基础</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</head>
<body>
<div id="app">
<v-btn></v-btn>
<hr />
<v-btn></v-btn>
</div>
<script type="text/javascript">
// 自定义组件
Vue.component('v-btn', {
data: function () {
return {
count: 0
}
},
template: `
<div>
<h1>{{ count }}</h1>
<button @click='count++'>点击我试试</button>
</div>
`
})
// 实例化
new Vue({ el: '#app' });
</script>
</body>
</html>

data 必须是一个函数

在上面的示例代码中,我们可以看到有一段代码是这样的:

1
2
3
4
5
data: function () {
return {
count: 0
}
},

那么,为什么data中的数据需要使用函数return回来,而不直接使用Object形式呢?

  1. vue组件中data值不能为对象,因为对象是引用类型,组件可能会被多个实例同时引用。如果data值为对象,将导致多个实例共享一个对象,其中一个组件改变data属性值,其它实例也会受到影响。
  2. data为函数,通过return 返回对象的拷贝,致使每个实例都有自己独立的对象,实例之间可以互不影响的改变data属性值。

例子一【引用类型】:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>例子</title>
</head>
<body>
<div id="app"></div>
<script>
const fn = function() {};
fn.prototype.data = { a: 1 };
const demo01 = new fn();
const demo02 = new fn();
demo01.data.a = 5;
document.getElementById('app').innerHTML = `
<div>[demo02.data.a]:${demo02.data.a}</div>
`;

</script>
</body>
</html>

打开浏览器运行上面的代码:可以看到页面显示内容为:

1
[demo02.data.a]:5

为什么demo02.data.a不是1呢?

  • 因为每个组件的data都在内存的同一个地址中,一个数据改变了其他也会跟着改变。

例子二【函数】:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>例子</title>
</head>
<body>
<div id="app"></div>
<script>
const fn = function() {
this.data = this.data();
};
fn.prototype.data = function() {
return { a: 1 };
};
const demo01 = new fn();
const demo02 = new fn();
demo01.data.a = 5;
document.getElementById('app').innerHTML = `
<div>[demo02.data.a]:${demo02.data.a}</div>
`;

</script>
</body>
</html>

打开浏览器运行上面的代码:可以看到页面显示内容为:

1
[demo02.data.a]:1

为什么demo02.data.a1呢?

  • 因为data是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响