Vue2 组件

组件就是对结构和功能的复用
以 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
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png" />
</div>
</template>

<script>
export default {
/* 当前组件名称 */
name: "Home",
/* 组件注册 */
components: {},
/* 当前组件数据源 */
data() {
return {};
},
/* 当前组件方法 */
methods: {},
/* 当前组件监听器 */
watch: {},
/* 当前组件计算属性 */
computed: {},
/* 当前组件过滤器 */
filters: {},
};
</script>

<style lang="scss" scoped>
</style>

组件中的 data 不能指向对象,而是函数

组件中的 this 指向当前组件的实例对象

组成部分

template

模板结构

1
2
3
<tamplate>
<div></div>
</tamplate>

template节点中只能有一个根元素

script

JavaScript 行为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
export default {
/* 当前组件名称 */
name: "Home",
/* 组件注册 */
components: {},
/* 当前组件数据源 */
data() {
return {};
},
/* 当前组件方法 */
methods: {},
/* 当前组件监听器 */
watch: {},
/* 当前组件计算属性 */
computed: {},
/* 当前组件过滤器 */
filters: {},
};
</script>

export default {} 默认导出

style

样式

1
<style lang="scss" scoped></style>

lang 属性设置样式文件类型,默认为 css

scoped 属性表示样式封装,样式只作用于当前组件

scoped 属性原理:为当前组件的全部元素都添加一个相同的属性

样式击穿

1
::v-deep div {}

当修改第三方组件库默认样式的时候,需要使用 ::v-deep

组件使用

  1. 导入组件
1
2
import complateName from '@/complate/complateName.vue'
// @ 代替 src
  1. 注册组件
1
2
3
components: {
comolateName
},
  1. 使用组件
1
<complateName></complateName>

全局注册组件

1
Vue.component('组件标签名', 组件名)

main.js入口文件中注册

自定义属性 props

程序员通过自定义属性(props),为当前组件传值

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
<script>
export default {
/* 当前组件名称 */
name: "Home",
/* 自定义属性 */
/*
props: ['init']
数组形式的自定义属性不能设置数据类型和默认值
*/
props: {
init: {
/* 数据类型 */
type: Number,
/* 默认值 */
default: 0,
/* 必填项 */
required: false
/*
true: 必填
false: 非必填
*/
}
},
/* 当前组件数据源 */
data() {
return {
content: this.init,
};
},

};
</script>
1
2
3
4
5
<template>
<div>
<Home :init="10"></Home>
</div>
</template>

自定义属性中的数据使用方式与 data 中的数据相同

props 是“只读”的,不推荐直接修改 props 中的数据

需要修改 props 中的数据的话,可以通过将 props 中的值传给 data 中的数据

data中的数据可以通过 this获取 props 中的值

组件之间的数据共享

父子关系

  • 父组件向子组件共享数据

通过自定义属性(props)传值

  • 子组件向父组件共享数据

自定义事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* 子组件 */
<script>
export default {
data() {
return {
count: 0,
};
},
methods: {
push() {
this.$emit("change", this.count);
// 第一个参数为自定义事件名称
// 第二个参数为传给父组件的数据
},
},
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* 父组件 */
<template>
<div>
<son @change="getSonCount"></son>
<!-- 当子组件的 $emit 被执行,父组件的自定义事件就会被触发 -->
</div>
</template>

<script>
export default {
data() {
return {
num: 0,
};
},
methods: {
getSonCount(val) {
this.num = val;
}
},
};
</script>

兄弟关系

EventBus 解决方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* 数据发送方 */
<script>
import bus from './eventBus.js'
export default {
data() {
return {
msg: '发送数据',
};
},
methods: {
push() {
bus.$emit('share', this.msg);
}
},
};
</script>
1
2
3
/* EventBus */
import Vue from 'vue'
export default new Vue()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* 数据接收方 */
<script>
import bus from './eventBus.js'
export default {
data() {
return {
msg: '',
};
},
methods: {
getMsg() {
bus.$on('share', (val) => {
this.msg = val;
})
}
},
created() {
this.getMsg();
}
};
</script>

内置方法

$mount

Vue 实例提供的$mount(id)方法,手动将组件挂载指定的元素中

$nextTick

Vue 实例提供的$nextTick(fn) 方法,会把 fn 回调推迟到下一个 DOM 更新周期之后执行