vue3组件通信(8种)
各位看官,以下为本人根据官方及各路大神的总。结所收集的,若有错误欢迎纠正
一、父传子:
1、props
父:
<template>
<!-- 子组件 -->
<Child :data1="data1"></Child>
</template>
<script setup>
const data1 = []
</script>
子:
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
data1: {
type: Array,
default: () => [],
},
})
const data1 = props.data1
</script>
或
<script>
import {defineCompontent} from 'vue'
export default defineCompontent({
name: '',
props: ['data1'],
setup(props) {
const data1 = props.data1
return {
data1,
}
}
})
</script>
2、provide/inject(可跨级)
父:
<script setup>
import { ref, provide } from 'vue'
// 向子组件提供数据
const data1 = []
provide('data1', data1)
</script>
子孙等:
<script setup>
import {inject} from 'vue'
const data1 = inject('data1')
</script>
3、attrs(个人不常用)
父:
<Child :data1="data1" :data2="data2"></Child>
<script setup>
import { ref, reactive } from "vue"
const data1 = ref("1")
const data2 = ref("2")
</script>
子:
<script setup>
import {defineProps, useAttrs} from 'vue'
const props = defineProps({
data1,
})
const attrs = useAttrs()
const data2 = attrs.data2;
</script>
4、父亲调用子方法expose/ref
父:
<template>
<!-- 子组件 -->
<Child ref="child"></Child>
</template>
<script setup>
import { ref } from 'vue'
const child = ref()
child.value.fn()
</script>
子:
<script setup>
import {defineExpose} from 'vue'
const fn = () => {}
defineExpose({
fn,
})
</script>
或
<script>
import {defineCompontent} from 'vue'
export default defineCompontent({
name: '',
setup() {
const fn = () => {}
return {
fn,
}
}
})
</script>
二、子传父
5、$emit
父:
<template>
<!-- 子组件 -->
<child @fn1="fn1"></child>
</template>
<script setup>
const fn1 = (data) => {}
</script>
子:
<script setup>
import {defineEmits} from 'vue'
const emits = defineEmits(['fn1'])
const data = {}
emits('fn1', data)
</script>
或
<script>
import {defineComponent} from 'vue'
export default defineComponent({
name: '',
setup(props, context) {
const data = {}
context.emit('fn1', data)
}
})
</script>
或
<script>
import {defineComponent} from 'vue'
export default defineComponent({
name: '',
setup(props, ctx) {
const data = {}
ctx.emit('fn1', data)
}
})
</script>
三、父子之间
6、v-model(props和emit)
父:
<Child v-model:data="data"></Child>
子:
<script setup>
import { defineEmits, defineProps } from 'vue'
const props = defineProps({
data: {
type: Array,
default: () => [],
},
})
const emits = defineEmits(['update:data'])
emits('update:data', data)
四、跨组件
7、mitt(全局事件总线)
先安装:npm i mitt -S
main.js
import { createApp } from 'vue'
import App from './App.vue'
import mitt from 'mitt'
const emitter = mitt()
const app = createApp(App)
app.config.globalProperties.$emitter = emitter
发:
<script setup>
import {getCurrentInstance} from 'vue'
const {proxy} = getCurrentInstance()
const data = {}
proxy.$emitter.emit('data1', data)
</script>
收:
<script setup>
import {getCurrentInstance, onBeforeUnmount} from 'vue'
const {proxy} = getCurrentInstance()
const fn = (data) => {}
proxy.$emitter.on('data1', fn)
onBeforeUnmount(() => {
proxy.$emitter.off('data1', fn)
}) // 组件销毁时需清除,
</script>
8、VueX
<script setup>
import {computed} from 'vue'
import {useStore} from 'vuex'
const store = useStore()
const data = computed(() => store.state.name.data)
// 其中name为模块化的名字,如果没有可直接用store.state.data
</script>