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 属性原理:为当前组件的全部元素都添加一个相同的属性
样式击穿
当修改第三方组件库默认样式的时候,需要使用 ::v-deep
组件使用
- 导入组件
1 2
| import complateName from '@/complate/complateName.vue'
|
- 注册组件
1 2 3
| components: { comolateName },
|
- 使用组件
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
| 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 更新周期之后执行