Vue3常用的通訊方式總結(jié)與實例代碼
前言
Vue3更新了很久了,但是之前項目都是用Vue2寫的,最近去官網(wǎng)look了一波,在這里總結(jié)一下Vue3常用的通訊方式。
尤大大,不要再更新了,真的學(xué)不動了。
本文用的是Vue3.2版本的setup語法糖官網(wǎng)
props
父組件
<template>
<div>
<Child :msg="msg" :obj="obj" />
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
// Vue3.2版本setup語法糖引入組件不需要注冊便可以使用組件
import Child from './child.vue'
const msg = ref('一只豆豆')
// 傳遞復(fù)雜類型數(shù)據(jù)
const obj = reactive({name: '豆豆'})
</script>子組件
<template>
<div></div>
</template>
<script setup>
// Vue3.2版本setup語法糖 defineProps 不需要引入可以直接使用
const props = defineProps({
msg: {
type: String,
default: ''
},
obj: {
type: Object,
default: () => {}
}
})
console.log('msg', props.msg); // 一只豆豆
console.log('obj', props.obj.name); // 豆豆
</script>$emit
父組件
<template>
<div>
<Child @myClick="myClick" />
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import Child from './child.vue'
const myClick = val => {
console.log('val', val); // emit傳遞信息
}
</script>子組件
<template>
<div>
<button @click="handleClick">click me</button>
</div>
</template>
<script setup>
// Vue3.2版本setup語法糖 defineEmits 不需要引入可以直接使用
const emit = defineEmits(['myClick']) // 如果有多個emit事件可以往數(shù)組后邊添加即可
const handleClick = ()=>{
emit("myClick", "emit傳遞信息")
}
</script>EventBus
在Vue3中就沒有EventBus了,可以使用mitt.js來替代
安裝
$ npm install --save mitt
bus.js
import mitt from 'mitt'
export default mitt()兄弟組件A emit觸發(fā)
<template>
<div>
<button @click="handleClick">click me</button>
</div>
</template>
<script setup>
import bus from './bus'
const handleClick = () => {
bus.emit('foo', '豆豆')
}
</script>兄弟組件B on接收
<template>
<div></div>
</template>
<script setup>
import bus from './bus'
bus.on('foo', e => {
console.log('e', e) // '豆豆'
})
</script>v-model
Vue2版本是可以通過修飾符.sync讓子組件修改父組件的值,但是Vue3就取消這個修飾符,融合到v-model里邊去了
父組件
<template>
<div>
<div>{{ name }}</div>
<div>{{ age }}</div>
<Child v-model:name="name" v-model:age="age" />
</div>
</template>
<script setup>
import Child from './child.vue'
import { ref } from 'vue'
const name = ref('豆豆')
const age = ref(20)
</script>子組件
<template>
<div>
<div></div>
<button @click="handleChange">click me</button>
</div>
</template>
<script setup>
// 'update:name' 這樣寫在console里面就不會有告警了
const emit = defineEmits(['update:name', 'update:age'])
const handleChange = () => {
emit('update:name', '一只豆豆')
emit('update:age', 18)
}
</script>expose / ref
子組件通過 expose 暴露屬性和方法出去
父組件通過 ref 來獲取子組件的值和調(diào)用方法
父組件
<template>
<div>
<Child ref="myRef" />
<button @click="handleClick">click me</button>
</div>
</template>
<script setup>
import Child from './child.vue'
import { ref } from 'vue'
const myRef = ref(null)
const handleClick = () => {
console.log('myRef', myRef.value.name) // 豆豆
myRef.value.fn() // 一只豆豆
}
</script>子組件
<template>
<div>
<div></div>
</div>
</template>
<script setup>
// Vue3.2版本setup語法糖 defineExpose 不需要引入可以直接使用
defineExpose({
name: '豆豆',
fn () {
console.log('一只豆豆')
}
})
</script>provide / inject
provide / inject 可以給后代組件傳參,嵌套多少層都沒問題
父組件
<template>
<div>
<Child />
</div>
</template>
<script setup>
import Child from './child.vue'
import { ref, provide } from 'vue'
const name = ref('豆豆')
provide('name', name)
</script>后代組件
<template>
<div>
<div>后代組件name {{ name }}</div>
</div>
</template>
<script setup>
import { inject } from 'vue'
const name = inject('name')
console.log('name', name.value) // 豆豆
</script>Vue2使用 provide / inject 傳遞數(shù)據(jù)不是響應(yīng)式的,所以只能通過傳遞一個對象數(shù)據(jù)才能變成響應(yīng)式
Vue3使用 provide / inject傳遞數(shù)據(jù)就是響應(yīng)式了,這就很便捷
插槽 slot
普通插槽
父組件
<template>
<div>
<Child>豆豆</Child>
</div>
</template>
<script setup>
import Child from './child.vue'
</script>子組件
<template>
<div>
<slot></slot>
</div>
</template>
<script setup></script>具名插槽
<template>
<div>
<Child>
豆豆
<template #name>
<div>
<button>一只豆豆</button>
</div>
</template>
</Child>
</div>
</template>
<script setup>
import Child from './child.vue'
</script>子組件
<template>
<div>
// 普通插槽
<slot></slot>
// 具名插槽
<slot name="name"></slot>
</div>
</template>
<script setup></script>效果圖

作用域插槽
父組件
<template>
<!-- v-slot="{scope}" 子組件返回的每一項數(shù)據(jù) -->
<Child v-slot="{ scope }" :arr="arr">
<div class="box">
<div>名字:{{ scope.name }}</div>
<div>年齡:{{ scope.age }}</div>
<div>愛好:{{ scope.like }}</div>
</div>
</Child>
</template>
<script setup>
import { reactive } from 'vue'
import Child from './child.vue'
const arr = reactive([
{ name: '張三', age: 18, like: '籃球' },
{ name: '李四', age: 19, like: '排球' },
{ name: '王五', age: 20, like: '足球' }
])
</script>
<style lang="less">
.box {
display: inline-block;
width: 200px;
border: dashed blue 1px;
margin-right: 15px;
padding: 10px;
}
</style>子組件
<template>
<div>
<!-- :scope="item" 返回每一項 -->
<slot v-for="item in arr" :scope="item" />
</div>
</template>
<script setup>
const props = defineProps({
arr: {
type: Array,
default: () => []
}
})
</script>效果圖

結(jié)語
到此這篇關(guān)于Vue3常用的通訊方式的文章就介紹到這了,更多相關(guān)Vue3通訊方式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue的route-view子頁面調(diào)用父頁面的函數(shù)詳解
這篇文章主要介紹了Vue的route-view子頁面調(diào)用父頁面的函數(shù)詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07
vue+webpack實現(xiàn)異步加載三種用法示例詳解

