Vue3.2+Ts組件之間通信的實現(xiàn)
受疫情影響,居家辦公有一陣了,最近閑下來開始談?wù)勛约簩τ赩ue3.2 + TS 知識的理解和使用。今天就總結(jié)下項目中常用到的一些組件之間的通信。
vue框架提供了前端開發(fā)組件的思想,頁面由一個個組件組合而成,在一些大型項目中,組件的數(shù)量越來越多,之間也需要通信,接下來我們進入主題,談?wù)剉ue3.x + ts中如何使用組件通信。
(vue3.x中組件之間通信和2基本上差別不大,就是基于ts寫法可能有點差別。)
父子組件通信
1、defineProps
Parent
<template> <child :count= "countNum" :labels="labels" /> </template> <script setup lang="ts"> import child from "@/componets/child.vue" import { ref } from "vue" const countNum = ref(100); const labels = ref([]) </script>
Child
<template> <div>{{count}}</div> </template> <script setup lang="ts"> //這里我們使用typescript的寫法 type TData = { count:number,labels:string[] } //聲明父組件傳過來的數(shù)據(jù)以及類型 //這種寫法無法設(shè)定默認值 const props = defineProps<TData>() //聲明默認值的寫法 const props = withDefaults( defineProps<TData>(), { count:1, labels:() => ["默認值1","默認值2"] //對于復(fù)雜數(shù)據(jù)類型以函數(shù)式聲明 }) console.log(props.count) // 模版中直接可以獲取值 </script>
2、defineEmits
Parent
<template> <child @changeHandle="changeHandle" /> </template> <script setup lang="ts"> import child from "@/componets/child.vue" const changeHandle = ((e) =>{ console.log(e) }) </script>
Child
<template> <div @click="btnHandle">按鈕點擊</div> </template> <script setup lang="ts"> import { ref } from "vue" const count = ref(100); //typescript的寫法 type TFn = { (e:'changeHandle',value:number) : void } const emit = defineEmits<TFn>() const btnHandle = (() => { emit('changeHandle',count) }) //非typescript的寫法 const emit = defineEmits(["changeHandle"]) const btnHandle = (() => { emit('changeHandle',count) }) </script>
3、defineExpose
文檔是這么介紹的:
使用 <script setup> 的組件是默認關(guān)閉的,也即通過模板 ref 或者 $parent 鏈獲取到的組件的公開實例,不會暴露任何在 <script setup> 中聲明的綁定。為了在 <script setup> 組件中明確要暴露出去的屬性,使用 defineExpose 編譯器宏,(其實可以理解為父組件想獲取子組件的內(nèi)容,子組件通過defineExpose把內(nèi)容暴露出去)
Parent
<template> <child ref="getChild" /> <div @click="btnHandle">按鈕點擊</div> </template> <script setup lang="ts"> import child from "@/componets/child.vue" const getChild = ref(null) const btnHandle = () => { //通過ref獲取子組件暴露出來的內(nèi)容 console.log(getChild.value.count) console.log(getChild.value.btnHandle()) } </script>
Child
<template> <div @click="btnHandle">按鈕點擊</div> </template> <script setup lang="ts"> import { ref } from "vue" const count = ref(100); const btnHandle = () => { count++ } defineExpose({count,btnHandle}) </script>
4、v-model
父子之間通信,有時需要子組件修改父組件傳遞過來的內(nèi)容,使用defineProps穿過來的值,進行修改會報錯,我在vue2.x中通過watch監(jiān)聽,然后把新值賦值data內(nèi)自定義屬性。
在vue3.x中我們可以通過v-model的傳遞并可以進行修改值,我們直接操作吧!
<template> ? <A v-model:count="count"></A> </template> <script setup lang="ts"> import A from "@/components/A.vue" import { ref } from "vue" const count = ref(100); </script> <template> ? <div>{{count}}</div> ? <div @click="updateHandle">修改內(nèi)容</div> </template> <script setup lang="ts"> import { ref } from "vue" const props = defineProps<{count:number}>() //修改 const emit = defineEmits(["update:count"]) const updateHandle = () => { ? emit("update:count",10) } </script>
兄弟組件通信
在vue2.x中我們一般用中央事件總線(eventBus)來處理兄弟組件,在vue3中用mitt()來處理兄弟組件之間的通信,實際用法和eventBus是一樣的,我們來看看如何實現(xiàn)吧
mitt
第一步安裝:
yarn add mitt -S
第二步創(chuàng)建
//在src/utils創(chuàng)建eventBus.ts import mitt from "mitt" const mitter = mitt() default export mitter
第三步使用
//兄弟A組件 <template> ? <div @click="btnHandle">按鈕點擊</div> </template> <script setup lang="ts"> import mitter from "@/utils/eventBus.ts" import { ref } from "vue" const count = ref(100) mitter.emit("count",count.value) </script> //兄弟B組件 <template> ? <div @click="btnHandle">按鈕點擊</div> </template> <script setup lang="ts"> import mitter from "@/utils/eventBus.ts" import { ref } from "vue" const getCount = ref() mitter.on("count",(e) => { ? getCount.value = e }) </script>
跨組件通信
Provide/Inject
往往在業(yè)務(wù)中會存在跨組件之間的通信,有的同學(xué)可能會想到一層層通過defineProps傳遞,這樣是可以實現(xiàn),但是隨著項目的代碼量龐大很難做到維護。
//provide 接收兩個參數(shù) 1、name<String類型> 2、value <template> ? <A></A>? </template> <script setup lang="ts"> import mitter from "@/utils/eventBus.ts" import A from "@/components/A.vue" import { provide } from "vue" const count = ref(190) provide('count',count.value) </script> <!--A組件內(nèi)的B組件--> //inject 接收兩個參數(shù) 1、provide傳如果來的name 2、可選參數(shù),提供默認值 <template> ? <div>我是B組件</div> </template> <script setup lang="ts"> import mitter from "@/utils/eventBus.ts" import { inject } from "vue" const getCount = inject('count',11) </script>
到此這篇關(guān)于Vue3.2+Ts組件之間通信的實現(xiàn)的文章就介紹到這了,更多相關(guān)Vue3.2 Ts組件通信內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue使用Office?Web實現(xiàn)線上文件預(yù)覽
這篇文章主要為大家介紹了vue使用微軟的開發(fā)接口Office?Web,實現(xiàn)線上文件預(yù)覽,預(yù)覽word,excel,pptx,pdf文件,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-07-07使用vue編寫h5公眾號跳轉(zhuǎn)小程序的實現(xiàn)代碼
這篇文章主要介紹了使用vue編寫h5公眾號跳轉(zhuǎn)小程序,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11python虛擬環(huán)境 virtualenv的簡單使用
virtualenv是一個創(chuàng)建隔絕的Python環(huán)境的工具。這篇文章主要介紹了python虛擬環(huán)境 virtualenv的簡單使用,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2020-01-01Vue為何棄用Ajax,選擇Axios?ajax與axios的區(qū)別?
ajax技術(shù)實現(xiàn)了局部數(shù)據(jù)的刷新,axios實現(xiàn)了對ajax的封裝;axios有的ajax都有,ajax有的axios不一定有??偨Y(jié)一句話就是axios是ajax,ajax不止axios。2023-01-01