Vue3常用的通訊方式總結與實例代碼
前言
Vue3更新瞭很久瞭,但是之前項目都是用Vue2寫的,最近去官網look瞭一波,在這裡總結一下Vue3常用的通訊方式。
尤大大,不要再更新瞭,真的學不動瞭。
本文用的是Vue3.2版本的setup語法糖官網
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('一隻豆豆') // 傳遞復雜類型數據 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事件可以往數組後邊添加即可 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觸發
<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 來獲取子組件的值和調用方法
父組件
<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 傳遞數據不是響應式的,所以隻能通過傳遞一個對象數據才能變成響應式
Vue3使用 provide / inject傳遞數據就是響應式瞭,這就很便捷
插槽 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}" 子組件返回的每一項數據 --> <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>
效果圖
結語
到此這篇關於Vue3常用的通訊方式的文章就介紹到這瞭,更多相關Vue3通訊方式內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- vue3組件通信的方式總結及實例用法
- Vue3的7種種組件通信詳情
- Vue3編程流暢技巧使用setup語法糖拒絕寫return
- Vue3中10多種組件通訊方法小結
- vue3中 provide 和 inject 用法及原理