Vue中组件通信的⼏种⽅法(Vue3的7种和Vue2的12种组件通
信)
Vue3组件通信⽅式:
props
$emit
expose / ref
$attrs
v-model
provide / inject
Vuex
使⽤⽅法:
props
⽤ props 传数据给⼦组件有两种⽅法,如下
⽅法⼀,混合写法
// Parent.vue 传送
<child :msg1="msg1" :msg2="msg2"></child>
<script>
import child from "./child.vue"
import { ref, reactive } from "vue"
export default {
data(){
return {
msg1:"这是传级⼦组件的信息1"
}
},
setup(){
// 创建⼀个响应式数据
// 写法⼀适⽤于基础类型 ref 还有其他⽤处,下⾯章节有介绍
const msg2 = ref("这是传级⼦组件的信息2")
// 写法⼆适⽤于复杂类型,如数组、对象
const msg2 = reactive(["这是传级⼦组件的信息2"])
return {
msg2
}
}
}
</script>
// Child.vue 接收
<script>
export default {
props: ["msg1", "msg2"],// 如果这⾏不写,下⾯就接收不到
setup(props) {
console.log(props) // { msg1:"这是传给⼦组件的信息1", msg2:"这是传给⼦组件的信息2" }
},
}
</script>
⽅法⼆,纯 Vue3 写法
// Parent.vue 传送
<child :msg2="msg2"></child>
<script setup>
import child from "./child.vue"
import { ref, reactive } from "vue"
const msg2 = ref("这是传给⼦组件的信息2")
// 或者复杂类型
const msg2 = reactive(["这是传级⼦组件的信息2"])
</script>
// Child.vue 接收
<script setup>
// 不需要引⼊直接使⽤
// import { defineProps } from "vue"
const props = defineProps({
// 写法⼀
msg2: String
// 写法⼆
msg2:{
type:String,
default:""
}
})
console.log(props) // { msg2:"这是传级⼦组件的信息2" }
</script>
注意:
如果⽗组件是混合写法,⼦组件纯 Vue3 写法的话,是接收不到⽗组件⾥ data 的属性,只能接收到⽗组件⾥ setup 函数⾥传的属性
如果⽗组件是纯 Vue3 写法,⼦组件混合写法,可以通过 props 接收到 data 和 setup 函数⾥的属性,但是⼦组件要是在 setup ⾥接收,同样只能接收到⽗组件中 setup 函数⾥的属性,接收不到 data ⾥的属性
官⽅也说了,既然⽤了 3,就不要写 2 了,所以不推荐混合写法。下⾯的例⼦,⼀律只⽤纯 Vue3 的写法,就不写混合写法了
$emit
// Child.vue 派发
<template>
// 写法⼀
<button @click="emit('myClick')">按钮</buttom>
// 写法⼆
<button @click="handleClick">按钮</buttom>
</template>
<script setup>
// ⽅法⼀适⽤于Vue3.2版本不需要引⼊
// import { defineEmits } from "vue"
/
/ 对应写法⼀
const emit = defineEmits(["myClick","myClick2"])
// 对应写法⼆
const handleClick = ()=>{
emit("myClick", "这是发送给⽗组件的信息")
}
// ⽅法⼆不适⽤于 Vue3.2版本,该版本 useContext()已废弃
import { useContext } from "vue"
const { emit } = useContext()
const handleClick = ()=>{
emit("myClick", "这是发送给⽗组件的信息")
}
</script>
// Parent.vue 响应
<template>
<child @myClick="onMyClick"></child>
</template>
<script setup>
import child from "./child.vue"
const onMyClick = (msg) => {
console.log(msg) // 这是⽗组件收到的信息
}
</script>
expose / ref
⽗组件获取⼦组件的属性或者调⽤⼦组件⽅法
// Child.vue
<script setup>
// ⽅法⼀不适⽤于Vue3.2版本,该版本 useContext()已废弃
import { useContext } from "vue"
const ctx = useContext()
// 对外暴露属性⽅法等都可以
childName: "这是⼦组件的属性",
someMethod(){
console.log("这是⼦组件的⽅法")
}
})
// ⽅法⼆适⽤于Vue3.2版本, 不需要引⼊
// import { defineExpose } from "vue"
defineExpose({
childName: "这是⼦组件的属性",
someMethod(){
console.log("这是⼦组件的⽅法")
}
})
</script>
// Parent.vue 注意 ref="comp"
<template>
<child ref="comp"></child>
<button @click="handlerClick">按钮</button>
</template>
<script setup>
import child from "./child.vue"
import { ref } from "vue"
const comp = ref(null)
const handlerClick = () => {
console.log(comp.value.childName) // 获取⼦组件对外暴露的属性
comp.value.someMethod() // 调⽤⼦组件对外暴露的⽅法
}
</script>
attrs
attrs:包含⽗作⽤域⾥除 class 和 style 除外的⾮ props 属性集合
// Parent.vue 传送
<child :msg1="msg1" :msg2="msg2" title="3333"></child>
<script setup>
import child from "./child.vue"
import { ref, reactive } from "vue"
const msg1 = ref("1111")
const msg2 = ref("2222")
</script>
// Child.vue 接收
<script setup>
import { defineProps, useContext, useAttrs } from "vue"
// 3.2版本不需要引⼊ defineProps,直接⽤
const props = defineProps({
msg1: String
})
/
/ ⽅法⼀不适⽤于 Vue3.2版本,该版本 useContext()已废弃
const ctx = useContext()
// 如果没有⽤ props 接收 msg1 的话就是 { msg1: "1111", msg2:"2222", title: "3333" }  console.log(ctx.attrs) // { msg2:"2222", title: "3333" }
// ⽅法⼆适⽤于 Vue3.2版本
const attrs = useAttrs()
console.log(attrs) // { msg2:"2222", title: "3333" }
</script>
v-model
可以⽀持多个数据双向绑定
// Parent.vue
<child v-model:key="key" v-model:value="value"></child>
<script setup>
import child from "./child.vue"
import { ref, reactive } from "vue"
const key = ref("1111")
const value = ref("2222")
</script>
// Child.vue
<template>
<button @click="handlerClick">按钮</button>
</template>
<script setup>
/
/ ⽅法⼀不适⽤于 Vue3.2版本,该版本 useContext()已废弃
import { useContext } from "vue"
const { emit } = useContext()
// ⽅法⼆适⽤于 Vue3.2版本,不需要引⼊
// import { defineEmits } from "vue"
const emit = defineEmits(["key","value"])
// ⽤法
const handlerClick = () => {
emit("update:key", "新的key")
emit("update:value", "新的value")
}
</script>
reactive 数组provide / inject
provide / inject 为依赖注⼊
provide:可以让我们指定想要提供给后代组件的数据或
inject:在任何后代组件中接收想要添加在这个组件上的数据,不管组件嵌套多深都可以直接拿来⽤// Parent.vue
<script setup>
import { provide } from "vue"
provide("name", "沐华")
</script>
// Child.vue
<script setup>
import { inject } from "vue"
const name = inject("name")
console.log(name) // 沐华
</script>
Vuex
// store/index.js
import { createStore } from "vuex"
export default createStore({
state:{ count: 1 },
getters:{
getCount: state => unt
},
mutations:{
add(state){
}
}
})
// main.js
import { createApp } from "vue"
import App from "./App.vue"
import store from "./store"
createApp(App).use(store).mount("#app")
// Page.vue
// ⽅法⼀直接使⽤
<template>
<div>{{ $unt }}</div>
<button @click="$storemit('add')">按钮</button>
</template>
// ⽅法⼆获取
<script setup>
import { useStore, computed } from "vuex"
const store = useStore()
console.log(unt) // 1
const count = computed(()=>unt) // 响应式,会随着vuex数据改变⽽改变
console.log(count) // 1
</script>
Vue2.x 组件通信⽅式
Vue2.x 组件通信共有12种:
props
$emit / v-on
.sync
v-model
ref
$children / $parent
$attrs / $listeners
provide / inject
EventBus
Vuex
$root
slot
⽗⼦组件通信可以⽤:
props
$emit / v-on
$attrs / $listeners
ref
sync
v-model
$children / $parent
兄弟组件通信可以⽤:
EventBus
Vuex
$parent
跨层级组件通信可以⽤:
provide/inject
EventBus
Vuex
$attrs / $listeners
$root
使⽤⽅法:
props
⽗组件向⼦组件传送数据,这应该是最常⽤的⽅式了
⼦组件接收到数据之后,不能直接修改⽗组件的数据。会报错,所以当⽗组件重新渲染时,数据会被覆盖。如果⼦组件内要修改的话推荐使⽤ computed
// Parent.vue 传送
<template>
<child :msg="msg"></child>
</template>
// Child.vue 接收
export default {
// 写法⼀⽤数组接收
props:['msg'],
// 写法⼆⽤对象接收,可以限定接收的数据类型、设置默认值、验证等
props:{
msg:{
type:String,
default:'这是默认数据'
}
},
mounted(){
console.log(this.msg)
},
}
.sync
可以帮我们实现⽗组件向⼦组件传递的数据的双向绑定,所以⼦组件接收到数据后可以直接修改,并且会同时修改⽗组件的数据
// Parent.vue
<template>
<child :page.sync="page"></child>
</template>
<script>
export default {
data(){
return {
page:1
}
}
}
// Child.vue
export default {
props:["page"],
computed(){
/
/ 当我们在⼦组件⾥修改 currentPage 时,⽗组件的 page 也会随之改变
currentPage {
get(){
return this.page
},
set(newVal){
this.$emit("update:page", newVal)
}
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。