目录
父子组件
1.props(父传子)
props是最常见的父子组件通信的方式
父组件:
<Demo09b msg="我是父组件!!!"></Demo09b>
子组件:(Demo09b组件)
在单文件中使用<script setup> ,props可以使用defineProps( )来定义
import {defineProps} from "vue";
//为传过来的属性设置类型与默认值
const props =defineProps({
msg:{
type:String,
default:'我是默认值'
}
}
//或者只限定类型
const props = defineProps({
msg: String,
xx属性: xx类型
})
)
//或者直接接受,不设定类型与默认值
const props = defineProps(['msg'])
对于取值:setup中要通过props.msg取到,模板中直接msg取到
2.emit(子传父)
emit是最常见的用于子组件向父组件传递消息的方法。
vue3使用使用defineEmits来声明emit,它接收内容与emit选项是一致的。
(1)用法一:给父组件发送自定义事件
// ----------子组件--------
<button @click="btn">点击</button>
<script setup>
import {defineEmits} from 'vue'
const emit = defineEmits(['emit']) //数组里可以有多个自定义方法名
//或者使用ts约束自定义方法的参数
const emit = defineEmits<{
(e:'getAge',age:number):void //设置自定义函数名称,参数类型与返回值类型
// 可在此设置第二个自定义函数
}>()
function btn() {
emit('getAge',18)
}
</script>
// ---------父级组件中--------
// 在父级组件中,使用子级的自定义事件,在html中去写@自定义事件名称=事件名称(就是在子组件中emits的第一个参数)
<HelloWorld @getAge="handleAge"/>
<script setup>
import HelloWorld from '@/components/HelloWorld'
// 函数中data是个形参,为子级传递过来的数据
const handleAge = function (data) {
console.log(data)
}
</script>
(2)用法二:使用modelValue直接更新父组件数据
父组件:
//结构
<CHild v-model:test="test"></CHild>
//逻辑
let test =ref()
子组件
//逻辑
const props = defineProps({
test:'',
})
const emit = defineEmits(['update:test']); //这个test就是接收的props
const resetTest =() =>{
//更新test给父组件
emit('update:test','最新数据')
}
这样父组件不需要自定义事件就能接受到最新的test数据。!
3.ref(子传父)
【子组件内】
定义方法或变量,使用defineExpose暴露出去
import {defineExpose} from "vue"
//初始化表单方法
const resetForm = () => {
formRef.value.resetFields()
}
//暴露方法
defineExpose({resetForm})
【父组件内】
定义ref,绑定给子组件
父组件调用子组件的方法:
4.provide / inject(祖孙、父子组件)
这两个都只能在setup( )中调用
在多级嵌套的组件体系中,某一级的外层组件可以通过provide属性向其下任意的一级子组件提供一个依赖,不管层级有多深;而某一级的子组件则可以通过inject属性接收来自其上任意一级父组件提供的依赖。 注意:provide
和inject
需要一起使用,通过provide / inject互相传递的值在任意组件修改了,其他组件也同步
举个例子:有三个组件,分别是爷爷,爸爸,孙子。
// 嵌套条件
<yeye>
<baba>
<sunzi></sunzi>
</baba>
</yeye>
定义爷爷组件
<script setup lang="ts">
import {provide} from "vue"
let my = ref('我是爷爷')
//传入的数据其他组件可改(当前组件也会同步)
provide('info',my) //传递 键 ,值
//让传入的数据在其他组件中不可修改
provide('info',readonly(my))
</script>
定义爸爸、孙子组件(写法都一样)
<script setup lang="ts">
import {inject} from 'vue'
const info = inject<Ref<string>>('info') //通过键取得值
info!.value = '1212' //修改得到的值(使用非空断言操作符就不会报错)
</script>
兄弟组件
1.mitt
vue到3.0之后好像取消了bus全局事件总线,选择使用mitt作为兄弟组件间通信和传参的方式。mitt的使用方法有两种:可以单独创建一个文件,哪里要用就引入它;也可以 main.js 中挂载全局属性;
使用mitt,首先要安装mitt库
npm i mitt
使用方法1:单文件方法
在单独的文件中暴露出事件总线对象
import mitt from "mitt"
const Mit = mitt()
// 由于必须要拓展ComponentCustomProperties类型才能获得类型提示
declare module "vue" {
export interface ComponentCustomProperties {
bus: typeof Mit
}
}
export default Mit
在指定组件中导入并使用它
<template>
<button @click="sendHomeContent">send</button>
</template>
文件1:
<script setup>
// 导入事件总线
import mitt from "./utils/eventbus.js";
sendHomeContent(){
// 触发自定义总线why,并传入一个对象(图方便就用上面第一种写法了)
mitt.emit("why",{name:'why',age:19})
}
</script>
文件2:
<script setup>
// 导入事件总线
import mitt from "./utils/eventbus.js";
// 在创建vue实例时,注册why事件总线
// res就是传过来的数据
mitt.on("why",res=>{
console.log("HomeContent接收到得About发送得数据了:",res);
}
</script>
使用方法2:全局挂载使用
全局总线,vue 入口文件 main.js 中挂载全局属性
import { createApp } from 'vue'
import App from './App.vue'
import mitt from 'mitt'
const Mit = mitt()//创建mitt实例
//TypeScript注册
// 由于必须要拓展ComponentCustomProperties类型才能获得类型提示
declare module "vue" {
export interface ComponentCustomProperties {
$Bus: typeof Mit
}
}
const app = createApp(App)
// vue3 中使用 app.config.globalProperties,替代了vue2中的Vue.prototype,用于注册能够被应用内所有组件实例访问到的全局属性的对象
app.config.globalProperties.$Bus = Mit //使用的时候就是xx.$Bus.on或者xx.$Bus.emit
app.mount('#app')
3使用方法通过emit派发, on 方法添加事件,off 方法移除,clear 清空所有
A组件派发(emit)
<template>
<button @click="emit1">emit1</button>
</template>
<script setup lang='ts'>
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance(); //获得当前组件实例对象
const emit1 = () => {
instance?.proxy?.$Bus.emit('on-num', 100) //参数1:自定义方法名,参数二:要传的数据
}
</script>
B组件监听(on)
<script setup lang='ts'>
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
instance?.proxy?.$Bus.on('on-num', (num) => {
console.log(num)
})
</script>
监听所有事件( on("*") )
instance?.proxy?.$Bus.on('*',(type,num)=>{
console.log(type,num,'===========>B')
})
移除监听事件(off)
const Fn = (num: any) => {
console.log(num, '===========>B')
}
instance?.proxy?.$Bus.on('on-num',Fn)//listen
instance?.proxy?.$Bus.off('on-num',Fn)//unListen
清空所有监听(clear)
instance?.proxy?.$Bus.all.clear()
原文链接:https://blog.csdn.net/qq1195566313/article/details/125453908