赞
踩
vue3组件通信方式有以下几种:porps,$emit, bus,v-model,useAttrs,$ref/$parent,provide/inject,pinia,slot。下面将逐一讲解。
目录
5. $attrs/useAttrs:获取组件标签身上属性与事件
8.pinia :vuex:集中管理状态容器,可以实现任意组件之间的通信
9.slot 插槽分为默认插槽、具名插槽、作用域插槽(可以传递数据的插槽,子组件可以将数据回传给父组件的插槽)
父组件中,引入子组件并给子组件绑定一个money参数
- <template>
- <div id="app">
- <h1>父组件</h1>
- <h3>富一代资产{{ money }}元</h3>
- <index1 :money="money"></index1>
- </div>
- </template>
-
- <script lang="ts" setup>
-
- import index1 from './view/index.vue'
- import { ref } from 'vue'
-
- let money = ref(1000000000000)
-
- </script>
-
- <style scoped>
- #app {
- width: 100vw;
- height: 100vh;
- color: #000;
- padding: 50px;
- box-sizing: border-box;
- }
- </style>
子组件中,使用defineProps接收,在template中,可以直接使用money,
- <template>
- <div class="index1">
- <h1>子组件1</h1>
- <h3>儿子不知道父亲有{{ porps.money }}元</h3>
- <h3>
- 儿子知道了会争这{{ money }}元(template中可以直接省略porps---script中无法省略!)
- </h3>
- </div>
- </template>
-
- <script setup lang="ts">
- import { ref } from 'vue'
- // porps:实现父子组件通信,props数据还是只读
- // 组合式api 使用 defineProps 接收父子组件传递过来的数据,可以是数组也可以是对象,
- //不需要引入 template中可直接使用
- const porps = defineProps(['money'])
- console.log(porps)
-
- </script>
-
- <style lang="scss" scoped>
- .index1 {
- background-color: azure;
- padding: 12px;
- }
- </style>
示例
说到$emit就要说一下自定义事件,在vue框架中事件分为两种:一种是原生的DOM事件,另外一种自定义事件。原生DOM事件可以让用户与网页进行交互,比如click、dbdlick、change、mouseenter、mouseleave...自定义事件可以实现子组件给父组件传递数据。vue2中的@click绑定的是自定义事件 ,可以通过.native修饰符变为原生DOM事件 。vue3中绑定的是原生事件,利用defineEmits方法返回函数触发自定义事件,不需要引入,直接使用。
父组件
- <template>
- <div id="app">
- <h1>父组件</h1>
- <h3>富一代资产{{ money }}元</h3>
- <index1 :money="money" @xxx="handlerXXX"></index1>
- <h3>{{ son }}</h3>
- </div>
- </template>
-
- <script lang="ts" setup>
-
- import index1 from './view/index.vue'
- import { ref } from 'vue'
-
- let money = ref(1000000000000)
- let son = ref('')
- const handlerXXX = (value: string) => {
- son.value = value
- }
-
- </script>
-
- <style scoped>
- #app {
- width: 100vw;
- height: 100vh;
- color: #000;
- padding: 50px;
- box-sizing: border-box;
- }
- </style>
子组件
- <template>
- <div class="index1">
- <h1>子组件1</h1>
- <h3>儿子不知道父亲有{{ porps.money }}元</h3>
- <h3>
- 儿子知道了会争这{{ money }}元(template中可以直接省略porps---script中无法省略!)
- </h3>
- <p>
- vue2中 @click是自定义事件,可以通过.native修饰符变为原生DOM事件。
- 在vue3中@click是原生DOM事件
- </p>
- <el-button @click="handlerClick">自定义事件</el-button>
- </div>
- </template>
-
- <script setup lang="ts">
- import { ref } from 'vue'
- //------porps-------
- // porps:实现父子组件通信,props数据还是只读
- // 组合式api 使用 defineProps 接收父子组件传递过来的数据,可以是数组也可以是对象,
- //不需要引入 template中可直接使用
- const porps = defineProps(['money'])
- console.log(porps)
-
- //------$emit-------
- //defineEmits方法返回函数出发自定义事件,不需要引入 直接使用
- const $emit = defineEmits(['xxx'])
- const handlerClick = () => {
- console.log('触发自定义事件')
- $emit('xxx', '富二代上交9999元给富一代')
- }
-
- </script>
-
- <style lang="scss" scoped>
- .index1 {
- background-color: azure;
- padding: 12px;
- }
- </style>
示例:
mitt
Mitt
是一个小巧的JavaScript发布-订阅库,用于在应用程序中实现事件监听和触发。
安装:npm install mitt -S
在src目录下新建bus文件夹,bus文件夹下新建index.ts
- // 引入mitt插件 index.ts
- import mitt from "mitt"
-
- const $bus = mitt();
- export default $bus
接收组件:引入上面新建的bus,$bus.on 接收将来兄弟组件传递的数据
- <template>
- <div class="index1">
- <h1>子组件1</h1>
- <p>收到{{ car }}</p>
- </div>
- </template>
-
- <script setup lang="ts">
- import { ref ,onMounted} from 'vue'
-
- // 事件总线 引入$bus
- import $bus from '@/bus'
-
- let car = ref('')
- // 组件挂载完毕后,当前组件绑定一个事件,接收将来兄弟组件传递的数据
- onMounted(() => {
- $bus.on('car', (value: string) => {
- car.value = value
- })
- })
-
- </script>
-
- <style lang="scss" scoped>
- .index1 {
- background-color: azure;
- padding: 12px;
- }
- </style>
发送组件:$bus.emit 使用发送
- <template>
- <div class="index2">
- <h1>子组件2</h1>
- <h3>富二代的亲弟钱包有999999元</h3>
- <el-button @click="handler">点击送富二代哥哥法拉利跑车一台</el-button>
- </div>
- </template>
- <script setup lang="ts">
- import $bus from '@/bus'
-
- const handler = () => {
- $bus.emit('car', '弟弟送哥哥的法拉利跑车一台')
- }
- </script>
- <style lang="scss" scoped>
- .index2 {
- background-color: antiquewhite;
- padding: 12px;
- margin: 12px 0;
- }
- </style>
示例:
在vue2中v-model绑定了一个value值,和input事件,并且只能绑定一个v-model。
而在vue3中给子组件传递一个porps,并且绑定了一个自定义事件。
此处有两种用法,方法一
porps + @update:money 代表自定义事件。代码如下:
父组件代码:
- <template>
- <div id="app">
- <h1>父组件</h1>
- <!-- porps @update:money代表自定义事件,也可以换成其他名字 -->
- <!-- v-model
- 1.相当于子子组件传递props[modelValue]
- 2.相当于给子组件绑定了自定义事件update:modelValue
- -->
- <index3 :modelValue="money" @update:modelValue="handleMoney"></index3>
- <h3>父亲60大寿三妹送出价值{{ money3 }}元礼品</h3>
- </div>
- </template>
- <script lang="ts" setup>
- import index3 from './view/index3.vue'
- import { ref } from 'vue'
- // 接收子组件传递的数据
- let money3 = ref(666666)
- const handleMoney = (value: number) => {
- console.log('接收改变的值:' + value)
- money3.value = value
- }
- </script>
-
- <style scoped>
- #app {
- width: 100vw;
- height: 100vh;
- color: #000;
- padding: 50px;
- box-sizing: border-box;
- }
- </style>
子组件
- <template>
- <div class="index3">
- <h1>子组件3</h1>
- <h3>父亲送给三妹 {{ modelValue }}元</h3>
- <el-button @click="send">点击送出</el-button>
- </div>
- </template>
- <script setup lang="ts">
- // v-module :收集表单数据,数据双向绑定,组件之间的通信去实现父子数据同步业务
-
- defineProps(['modelValue'])
- let $emit = defineEmits(['update:modelValue'])
-
- const send = () => {
- $emit('update:modelValue', 9999)
- }
-
- </script>
- <style lang="scss" scoped>
- .index3 {
- background-color: beige;
- padding: 12px;
- }
- </style>
方法二
1.相当于给子组件传递一个porps[modelValue]=666666 (一定叫modelValue)
2.相当于给子组件绑定了一个自定义事件,事件名一定是 update:modelValue,父组件不用自己写自定义事件
父组件代码
- <template>
- <div id="app">
- <h1>父组件</h1>
- <!-- v-model使用情况:1.相当于给子组件传递一个porps[modelValue]=100000 (一定叫modelValue)
- 2.相当于给子组件绑定了一个自定义事件,事件名一定是 update:modelValue
- 与vue2的v-model的区别在于,vue2的v-model绑定了一个value值,和input事件,声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/490205推荐阅读
相关标签
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。