什么是父子组件
- 在脚手架项目中,单文件组件的
父子组件关系
可以简单的认为是使用关系
,如A组件中使用了B组件,那么就可以认为A是父组件,B是子组件 - 所谓父组件和子组件都是单独的单文件组件,它们更多是的引入使用关系
在脚手架中创建和渲染父子组件
-
创建父组件与两个子组件
- 在父组件中引入,注册,使用这两个子组件
<template>
<div>
<p>我是爸爸</p>
<!-- 使用子组件 -->
<son :mymoney="'money'"></son>
<sister></sister>
</div>
</template>
<script>
// 引入两个子组件
import son from "./son";
import sister from "./sister";
export default {
data() {
return {};
},
// 注册子组件
components: {
son,
sister,
},
};
</script>
- 渲染父组件
注意:由于父组件中使用了子组件,所以只需要渲染父组件
就可以了
实现父组件向子组件传递数据
实现方式:父组件通过 v-bind 属性绑定向子组件共享数据。同时,子组件需要使用 props 接收数据
- 子组件props的声明
- 数组形式
- 对象形式
props: {
// 值为类型,也不能加引号
// mymoney: Number,
mymoney: {
// 通过type属性指定类型
type: [Number, String],
// 添加必填项设置,如果值为true,说明这个属性父组件一定要传递
required: true,
// 设置默认值,在没有传值的情况下使用默认值
default: 1000,
},
},
- 父组件中在使用子组件的位置为props成员赋值
- 可以直接赋值固定值
- 如果赋值变量,则需要使用v-bind
<!-- 在父组件中使用子组件的位置为子组件的prop成员赋值 -->
<son :mymoney="money"></son>
组件的 props
- 数组类型:通过数组的方式定义props成员,用于接收父组件传递的数据
// 添加props 用于接收父组件中传递的数据
// 1. 定义为数组,里面就是定义的用于接收父组件数据的成员名称,字符串类型
props: ["mymoney"],
它的缺点:无法为每个 prop 指定具体的数据类型,也无法进行相应的校验
- 对象类型:通过对象的方式定义props成员,可以为每个prop成员制定规则(类型,校验...),常用的如下:
① 基础的类型检查
② 多个可能的类型
③ 必填项校验
④ 属性默认值
⑤ 自定义验证函数
props: {
// 值为类型,也不能加引号
// mymoney: Number,
mymoney: {
// 通过type属性指定类型
type: [Number, String],
// 添加必填项设置,如果值为true,说明这个属性父组件一定要传递
// required: true,
// 设置默认值,在没有传值的情况下使用默认值
default: 1000,
// 自定义验证函数:在封装组件时,
// 可以为 prop 属性指定自定义的验证函数,
// 从而对 prop 属性的值进行更加精确的控制
validator(value) {
if (value < 0 || value > 1000000) {
return false;
} else {
return true;
}
},
},
},
详细的 props 验证方案,请参考 vue 的官方文档:
https://v3.vuejs.org/guide/component-props.html#prop-validation
实现子组件向父组件传递数据
- 子组件使用
this.$emit
发出事件并传递数据- 语法:
this.$emit
(自定义事件类型,传递的数据)
- 语法:
methods: {
tellname() {
// 通过this.$emit函数发出一个事件,并传递数据
// this.$emit(自定义事件类型,数据)
// 通过this所发出的事件,只能由父组件监听
this.$emit("getName", this.mygfname);
},
},
- 父组件中在使用子组件的位置监听子组件所发出的事件
- 监听事件,调用函数处理
- 处理函数的参数就是子组件所传递的数据
<!-- 在父组件中使用子组件的位置,监听子组件所发出的事件,并调用函数处理 -->
<!-- 如果子组件发出的事件 和内置事件同名,
那么在父组件中优先监听子组件所发出的同名事件 -->
<son :mymoney="money" @getName="getname"></son>
methods: {
// 子组件发出的事件的处理函数有一个参数,就是子组件所传递的数据
getname(data) {
this.mysongfname = data;
},
},
兄弟组件之间的数据传递
1. 创建全局的事件总线
- 全局Vue实例的创建
-
暴露全局的Vue实例
2. 子组件A使用 事件总线.$emit 发出事件并传递数据
- 引入事件总线
// 引入事件总线 , 用于两个事件之间的数据传递
import bus from "../../../utils/eventBus.js";
- 发出事件并传递数据
methods: {
tellnameToo() {
bus.$emit("getgfname", this.mygfname);
},
},
3. 子组件B中在mounted钩子函数中使用 事件总线.$on 监听子组件A所发出的事件
- 监听事件,调用函数处理
- 处理函数的参数就是组件A所传递的数据
// 组件已加载完成就监听事件的发出
mounted() {
// 当监听到其他组件所发出的事件,调用指定的回调函数进行处理,
// 回调函数的参数就是其他组件发出事件时所传递的参数
// bus.#on(组件所发出的事件类型,处理函数)
// 处理函数一定要定义为箭头函数
bus.$on("getgfname", (data) => {
console.log(data);
this.mybtgfname = data;
});
},