Vue3学习之第五节: 组件通信

一、props(父子组件传值)

父子组件传值要使用setup函数中的参数来实现。
setup 主要有两个参数:
    第一个参数:props :父组件传递过来的属性会被放到props对象中
    第二个参数:context:包含3个属性,如下:
        attrs:所有的非prop的attribute
        slots:父组件传递过来的插槽
        emit:当我们组件内部需要发出事件时会用到emit

父组件向子组件传值

父组件中:

<template>
    // 通过自定义属性的方式给子组件传递数据
	<message title="父组件中的值"></message>
</template>

子组件中:

<template>
    <h2> {{title}} </h2>
</template>
<script>
	export default {
		// 通过props 接收父组件传递过来的数据,模板中可以直接使用
		props: ['title'],

		setup(props, context) {
			// setup函数中要使用的话,要接收一下
			console.log(props.title)
        }
</script>
子组件props接收时一些注意细节⚠️:

细节一:props中属性可以指定的类型

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

细节二:props中不同类型的写法

props: {
	// 基础类型指定
	propA: Number,
	
	// 指定多个类型
	propB: [String, Number],
	
	// 指定必传类型
	propC: {
		type: String,
		required: true
    },
    
    // 带有默认值的基本类型
    propD: {
		type: Number,
		default: 100
	},
	
	// 带有默认值的对象
	propE: {
		type: Object,
		// 对象或数组默认值必须从一个工厂函数获取
		default() {
			return { mes: 'lihua'}
		}
	},
	
	// 自定义验证函数
	propF: {
		validator(value) {
			return ['warning', 'success'].includes(value)
		}
	},
	
	// 具有默认值的函数
	prorG: {
		type: Function,
		default() {
			return 'default function'
		}
	}
}

细节三:Props的大小写命名
   HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 。

子组件给父组件传值

子组件中:

<template>
    <button @click="increment"></button>
</template>
<script>
	export default {
		// 1. 通过第二个参数 context 接收父组件传递过来的方法
		setup(props, context) {
          const increment = () => {
            // 通过 context.emit触发父组件的方法,第二个参数为传递的参数,可以传递多个
			context.emit('add', 100)
			context.emit('add', 100, 'aaa', 'bbb')
          }
      
          // 导出方法提供给模板使用
          return {
            increment
          }
        }

        // 2. 通过第二个参数 解构 emits 接收父组件传递过来的函数
		setup(props, { emit }) {
          const increment = () => {
            // 通过emit触发父组件的方法,第二个参数为传递的参数,可以传递多个
			emit('add', 100)
			emit('add', 100, 'aaa', 'bbb')
          }
 
          return {
            increment
          }
        }
	}
</script>

父组件中:

<template>
	<message @add="addNum"></message>
</template>
<script>
	export default {
		components: {
			message
		}
		setup() {
          const addNum = (value) => {
            // 接收子组件传递过来的值
			console.log(value)
          }
      
        // 导出方法提供给模板使用
        return {
          addNum
        }
	}
</script>

二、provide与inject(跨层级组件传值)

provide 和 inject 作用:无论组件层次结构有多深,父组件都可以作为其所有子组件的依赖提供者。
用法:父组件有一个 provide选项来提供数据,子组件有一个 inject 选项来开始使用这些数据。

在这里插入图片描述

具体写法

父组件中:

import { reactive, provide } from 'vue
setup(){
	let baseInfo = reactive({
		name: '章三',
		age: 18
	})
	provide('baseInfo', baseInfo)
	
	return { 
		baseInfo
	}
}

后代组件中:

import { inject } from 'vue
setup(){
	let baseInfo = inject('baseInfo')
	
	return { 
		baseInfo
	}
}

三、集成 Bus,总线传值 mitt

  • Vue到3.0之后的Bus的方式变成了使用mitt(第三方插件)。Vue2是通过创建一个空的Vue来作为总线。
  • 使用emit来注册,emit(“type”,“event”)。第一个参数事件名称,第二个参数通常是参数。
  • 使用on来监听,on(“type”,“handler”=>{这里是具体操作逻辑})。第一个参数同上的第一个参数要对应上,才说明一个事件。
  • emit和on是成对出现,一个发起,一个接收。
  • Vue2.0之前是$emit,$on,Vue3.0去掉了$,后面会给出例子。
  • 接收方可以是多个组件,只要第一个参数匹配都可以获取到想要的数据,这样确实很方便,也是Vue的一个优势。

方式一:全局总线

  1. vue入口文件main.ts中挂载全局属性
//导入插件mitt
import mitt from "mitt"
//创建Vue应用实例
const app = createApp(App)
//挂载事务总线为全局属性
app.config.globalProperties.$mybus = new mitt()

方式二:组件总线

1. 安装
 npm install --save mitt
2. 新建 utils/eventBus.ts
import mitt from 'mitt'
const VueEvent = mitt();
 
export default VueEvent;
3. a.vue组件
import VueEvent from './eventBus'
VueEvent.emit('tabsName', name)
// tabsName 自定义事件名, name 参数
4. b.vue组件
import VueEvent from './eventBus'
VueEvent.on('tabsName', (msg: any) => {
   console.log(msg, 'msg输出参数')
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值