Vue09 五一前 组件通信

2024-05-07 01:28
文章标签 组件 通信 vue09 五一

本文主要是介绍Vue09 五一前 组件通信,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

store组合式写法

count.ts组合式写法

import { reactive } from 'vue'
export const useLoveTalkStore = defineStore('talk', () => {const talkList = reactive(JSON.parse(localStorage.getItem('talkList') as string) || [])//getATalk函数相当于actionasync function getATalk() {//发请求,下面这行写法是:连续解构+重命名let { data: { content: title } } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')// //把请求回来的字符,包装成一个对象let obj = { id: nanoid(), title } //简单写成title:content 上面let可以result改成 {data:{content}};还可以进一步 title  {data:{content:title}}// //放到数组中talkList.unshift(obj)}//必须有return,不然无效return { talkList, getATalk }
})

选项式写法

import { defineStore } from 'pinia'
import axios from 'axios'
import { nanoid } from 'nanoid'export const useLoveTalkStore = defineStore('talk', {actions: {async getATalk() {//发请求,下面这行写法是:连续解构+重命名let { data: { content: title } } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json')// //把请求回来的字符,包装成一个对象let obj = { id: nanoid(), title } //简单写成title:content 上面let可以result改成 {data:{content}};还可以进一步 title  {data:{content:title}}// //放到数组中this.talkList.unshift(obj)}},//state真正存储数据的地方state() {return {talkList: JSON.parse(localStorage.getItem('talkList') as string) || []// talkList: [//     { id: 'ftrfasdf01', title: '今天天气好' },//     { id: 'ftrfasdf02', title: '今天天气好2' },//     { id: 'ftrfasdf03', title: '今天天气好3' }// ]}}
})

组件通信_方式1_props

  • 父传子:属性值是非函数
<template><div class="father"><h3>父组件</h3><h4>汽车:{{ car }}</h4><!-- 传递,子需要接收 --><Child :car="car" :sendToy="getToy"/></div>
</template>

子组件需要接收

<script setup lang="ts" name="Child">import {ref} from 'vue'// 数据let toy = ref('奥特曼')// 声明接收propsdefineProps(['car','sendToy'])
</script>
  • 子传父:属性值是函数
<template><div class="father"><h3>父组件</h3><h4>汽车:{{ car }}</h4><!-- v-show、v-if条件渲染 不传递参数就不显示 --><h4 v-show="toy">子给的玩具:{{ toy }}</h4><Child :car="car" :sendToy="getToy"/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import {ref} from 'vue'// 数据let car = ref('奔驰')let toy = ref('')// 方法function getToy(value:string){toy.value = value}
</script>
<template><div class="child"><h3>子组件</h3><h4>玩具:{{ toy }}</h4><h4>父给的车:{{ car }}</h4><button @click="sendToy(toy)">把玩具给父亲</button></div>
</template><script setup lang="ts" name="Child">import {ref} from 'vue'// 数据let toy = ref('奥特曼')// 声明接收propsdefineProps(['car','sendToy'])
</script>

组件通信_方式2__自定义事件

<template><div class="father"><h3>父组件</h3><h4>{{ str }}</h4><button @click="test">点我</button><!-- 给子组件Child绑定事件 --><Child/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import { ref } from "vue";// 数据let str = ref('你好')function test() {str.value = '哈哈'}
</script>

可以简化写法

<template><div class="father"><h3>父组件</h3><h4>{{ str }}</h4><button @click="str = '哈哈'">点我</button><!-- 给子组件Child绑定事件 --><Child/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import { ref } from "vue";// 数据let str = ref('你好')
</script>

$seven 特殊占位符 这是一个事件对象

<template><div class="father"><h3>父组件</h3><h4>{{ str }}</h4><button @click="str = $event">点我</button><!-- 给子组件Child绑定事件 --><Child/></div>
</template>

子传父

<template><div class="father"><h3>父组件</h3><h4 v-show="toy">子给的玩具:{{ toy }}</h4><!-- 给子组件Child绑定事件 --><Child @send-toy="saveToy"/></div>
</template>

​ <Child @send-toy=“saveToy”/>

给组件绑定send-toy事件,只要这个事件被触发,saveToy就会被调用

如何触发事件

需要在子组件里面声明,用一个宏函数,defineEmits

还需要加上emit。这个可以放在任何想要触发的地方

<template><div class="child"><h3>子组件</h3><h4>玩具:{{ toy }}</h4><button @click="emit('send-toy',toy)">测试</button></div>
</template><script setup lang="ts" name="Child">import { ref } from "vue";// 数据let toy = ref('奥特曼')// 声明事件const emit =  defineEmits(['send-toy'])// onMounted(() => {// setTimeout(() => {// 	emit('send-toy')// }, 3000);// })
</script>

案例

父组件

<template><div class="father"><h3>父组件</h3><h4 v-show="toy">子给的玩具:{{ toy }}</h4><!-- 给子组件Child绑定事件 --><Child @send-toy="saveToy"/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import { ref } from "vue";// 数据let toy = ref('')// 用于保存传递过来的玩具function saveToy(value:string){console.log('saveToy',value)toy.value = value}
</script>

子组件

<template><div class="child"><h3>子组件</h3><h4>玩具:{{ toy }}</h4><button @click="emit('send-toy',toy)">测试</button></div>
</template><script setup lang="ts" name="Child">import { ref } from "vue";// 数据let toy = ref('奥特曼')// 声明事件const emit = defineEmits(['send-toy'])
</script>

组件通信_方式3__mitt

pubsub

$bus

mitt

接收数据:提前绑定好事件(提前订阅事件)

提供数据:在合适的时候触发事件(发布消息)

案例

哥哥传递玩具给弟弟

<template><div class="child1"><h3>子组件1</h3><h4>玩具:{{ toy }}</h4><button @click="emitter.emit('send-toy',toy)">玩具给弟弟</button></div>
</template><script setup lang="ts" name="Child1">import {ref} from 'vue'import emitter from '@/utils/emitter';// 数据let toy = ref('奥特曼')
</script>
<template><div class="child2"><h3>子组件2</h3><h4>电脑:{{ computer }}</h4><h4>哥哥给的玩具:{{ toy }}</h4></div>
</template><script setup lang="ts" name="Child2">import {ref,onUnmounted} from 'vue'import emitter from '@/utils/emitter';// 数据let computer = ref('联想')let toy = ref('')// 给emitter绑定send-toy事件emitter.on('send-toy',(value:any)=>{toy.value = value})// 在组件卸载时解绑send-toy事件;对内存友好onUnmounted(()=>{emitter.off('send-toy')})
</script>

组件通信_方式4__v-model

双向绑定

v-model用在html标签上

<template><div class="father"><h3>父组件</h3><!-- v-model用在html标签上 --><!-- <input type="text" v-model="username"> --><!-- :value数据来到页面,@input页面来到数据 --><input type="text" :value="username" @input="username = (<HTMLInputElement>$event.target).value"></div>
</template>

v-model用在组件标签上

father.Vue

<template><div class="father"><h3>父组件</h3><!-- v-model用在组件标签上 --><AtguiguInput v-model="username"/><!-- <AtguiguInput :modelValue="username" @update:modelValue="username = $event"/> --></div>
</template><script setup lang="ts" name="Father">import { ref } from "vue";import AtguiguInput from './AtguiguInput.vue'// 数据let username = ref('zhansgan')
</script>
<template><input type="text" :value="modelValue"@input="emit('update:modelValue',(<HTMLInputElement>$event.target).value)">
</template><script setup lang="ts" name="AtguiguInput">defineProps(['modelValue'])const emit = defineEmits(['update:modelValue')
</script>

$event到底是什么,什么时候可以用.target

对于原生事件,$event就是事件对象——能.target

对于自定义事件,$event就是触发事件时,所传递的数据——不能.target

组件通信_v-model的细节

update:modelValue名称太长 可以更改名字

如果value可以更换,可以再组件标签上多次使用v-model

<template><div class="father"><h3>父组件</h3><h4>{{ username }}</h4><h4>{{ password }}</h4> <!-- 修改modelValue --><AtguiguInput v-model:ming="username" v-model:mima="password"/></div>
</template><script setup lang="ts" name="Father">import { ref } from "vue";import AtguiguInput from './AtguiguInput.vue'// 数据let username = ref('zhansgan')let password = ref('123456')
</script>

组件

<template><input type="text" :value="ming"@input="emit('update:ming',(<HTMLInputElement>$event.target).value)"><br><input type="text" :value="mima"@input="emit('update:mima',(<HTMLInputElement>$event.target).value)">
</template><script setup lang="ts" name="AtguiguInput">defineProps(['ming','mima'])const emit = defineEmits(['update:ming','update:mima'])
</script>

组件通信_方式5__$attrs

概念:$attrs用于实现当前组件的父组件,向当前组件的子组件的通信(祖—孙)

祖-孙

father.vue

<template><div class="father"><h3>父组件</h3><h4>a:{{a}}</h4><h4>b:{{b}}</h4><h4>c:{{c}}</h4><h4>d:{{d}}</h4><Child :a="a" :b="b" :c="c" :d="d" v-bind="{x:100,y:200}" /></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import {ref} from 'vue'let a = ref(1)let b = ref(2)let c = ref(3)let d = ref(4)</script>

child.vue 把祖所有值都传递给孙

<template><div class="child"><h3>子组件</h3><!-- <h4>a:{{ a }}</h4><h4>其他:{{ $attrs }}</h4> --><GrandChild v-bind="$attrs"/></div>
</template><script setup lang="ts" name="Child">import GrandChild from './GrandChild.vue'// defineProps(['a'])
</script>

grandchild.vue

<template><div class="grand-child"><h3>孙组件</h3><h4>a:{{ a }}</h4><h4>b:{{ b }}</h4><h4>c:{{ c }}</h4><h4>d:{{ d }}</h4><h4>x:{{ x }}</h4><h4>y:{{ y }}</h4></div>
</template><script setup lang="ts" name="GrandChild">defineProps(['a','b','c','d','x','y'])
</script>

孙-组

father.vue

<template><div class="father"><h3>父组件</h3><h4>a:{{a}}</h4><Child :a="a" :updateA="updateA"/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import {ref} from 'vue'let a = ref(1)function updateA(value:number){a.value += value}
</script>

grandchild.vue

<template><div class="grand-child"><h3>孙组件</h3><h4>a:{{ a }}</h4><button @click="updateA(6)">点我将爷爷那的a更新</button></div>
</template><script setup lang="ts" name="GrandChild">defineProps(['a','updateA'])
</script>

组件通信_方式6__ r e f s 与 refs与 refsparent

father.vue

<template><div class="father"><h3>父组件</h3><h4>房产:{{ house }}</h4><button @click="changeToy">修改Child1的玩具</button><button @click="changeComputer">修改Child2的电脑</button><button @click="getAllChild($refs)">让所有孩子的书变多</button><Child1 ref="c1"/><Child2 ref="c2"/></div>
</template><script setup lang="ts" name="Father">import Child1 from './Child1.vue'import Child2 from './Child2.vue'import { ref,reactive } from "vue";let c1 = ref()let c2 = ref()// 数据let house = ref(4)// 方法function changeToy(){c1.value.toy = '小猪佩奇'}function changeComputer(){c2.value.computer = '华为'}function getAllChild(refs:{[key:string]:any}){console.log(refs)for (let key in refs){refs[key].book += 3}}// 向外部提供数据defineExpose({house})
</script>

child1.vue

<template><div class="child1"><h3>子组件1</h3><h4>玩具:{{ toy }}</h4><h4>书籍:{{ book }} 本</h4><button @click="minusHouse($parent)">干掉父亲的一套房产</button></div>
</template><script setup lang="ts" name="Child1">import { ref } from "vue";// 数据let toy = ref('奥特曼')let book = ref(3)// 方法function minusHouse(parent:any){parent.house -= 1}// 把数据交给外部defineExpose({toy,book})</script>

child2.vue

<template><div class="child2"><h3>子组件2</h3><h4>电脑:{{ computer }}</h4><h4>书籍:{{ book }} 本</h4></div>
</template><script setup lang="ts" name="Child2">import { ref } from "vue";// 数据let computer = ref('联想')let book = ref(6)// 把数据交给外部defineExpose({computer,book})
</script>

$refs 父传子

父得到子数据

<template><div class="father"><h3>父组件</h3><h4>房产:{{ house }}</h4><button @click="changeToy">修改Child1的玩具</button><button @click="getAllChild($refs)">让所有孩子的书变多</button><Child1 ref="c1"/></div>
</template><script setup lang="ts" name="Father">import Child1 from './Child1.vue'import Child2 from './Child2.vue'import { ref,reactive } from "vue";let c1 = ref()// 数据let house = ref(4)// 方法function changeToy(){c1.value.toy = '小猪佩奇'}function getAllChild(refs:{[key:string]:any}){for (let key in refs){refs[key].book += 3}}
</script>

子必须把数据传递出去

<script setup lang="ts" name="Child1">import { ref } from "vue";// 数据let toy = ref('奥特曼')let book = ref(3)// 把数据交给外部defineExpose({toy,book})</script>

$parent 子传父

<template><div class="child1"><h3>子组件1</h3><h4>玩具:{{ toy }}</h4><h4>书籍:{{ book }} 本</h4><button @click="minusHouse($parent)">干掉父亲的一套房产</button></div>
</template><script setup lang="ts" name="Child1">import { ref } from "vue";// 数据let toy = ref('奥特曼')let book = ref(3)// 方法function minusHouse(parent:any){parent.house -= 1}</script>
说明属性
$refs值为对象,包含所有被ref属性标识的DOM元素或组件实例
$parent值为对象,当前组件的父组件实例对象

一个注意点

<script setup lang="ts" name="Father">
// 注意点:当访问obj.c的时候,底层会自动读取value属性,因为c是在obj这个响应式对象中的let obj = reactive({a:1,b:2,c:ref(3)})let x = ref(4)console.log(obj.a)console.log(obj.b)console.log(obj.c) //自动拆包解包console.log(x) //这不是4
</script>

组件通信_方式7__provide_inject

如何不打扰儿子,直接传递给孙 区别attrs

father.vue

<template><div class="father"><h3>父组件</h3><h4>银子:{{ money }}万元</h4><h4>车子:一辆{{car.brand}}车,价值{{car.price}}万元</h4><Child/></div>
</template><script setup lang="ts" name="Father">import Child from './Child.vue'import {ref,reactive,provide} from 'vue'let money = ref(100)let car = reactive({brand:'奔驰',price:100})function updateMoney(value:number){money.value -= value}// 向后代提供数据 不能是money.value 否则传递的就是个数字 无法改变provide('moneyContext',{money,updateMoney})provide('car',car)</script>

GrandChild.vue

<template><div class="grand-child"><h3>我是孙组件</h3><h4>银子:{{ money }}</h4><h4>车子:一辆{{car.brand}}车,价值{{car.price}}万元</h4><button @click="updateMoney(6)">花爷爷的钱</button></div>
</template><script setup lang="ts" name="GrandChild">import { inject } from "vue";let {money,updateMoney} = inject('moneyContext',{money:0,updateMoney:(param:number)=>{}})let car = inject('car',{brand:'未知',price:0})
</script>

这篇关于Vue09 五一前 组件通信的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/965937

相关文章

Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析

《Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析》InstantiationAwareBeanPostProcessor是Spring... 目录一、什么是InstantiationAwareBeanPostProcessor?二、核心方法解

RabbitMQ工作模式中的RPC通信模式详解

《RabbitMQ工作模式中的RPC通信模式详解》在RabbitMQ中,RPC模式通过消息队列实现远程调用功能,这篇文章给大家介绍RabbitMQ工作模式之RPC通信模式,感兴趣的朋友一起看看吧... 目录RPC通信模式概述工作流程代码案例引入依赖常量类编写客户端代码编写服务端代码RPC通信模式概述在R

在Spring Boot中实现HTTPS加密通信及常见问题排查

《在SpringBoot中实现HTTPS加密通信及常见问题排查》HTTPS是HTTP的安全版本,通过SSL/TLS协议为通讯提供加密、身份验证和数据完整性保护,下面通过本文给大家介绍在SpringB... 目录一、HTTPS核心原理1.加密流程概述2.加密技术组合二、证书体系详解1、证书类型对比2. 证书获

C++ RabbitMq消息队列组件详解

《C++RabbitMq消息队列组件详解》:本文主要介绍C++RabbitMq消息队列组件的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. RabbitMq介绍2. 安装RabbitMQ3. 安装 RabbitMQ 的 C++客户端库4. A

Python模拟串口通信的示例详解

《Python模拟串口通信的示例详解》pySerial是Python中用于操作串口的第三方模块,它支持Windows、Linux、OSX、BSD等多个平台,下面我们就来看看Python如何使用pySe... 目录1.win 下载虚www.chinasem.cn拟串口2、确定串口号3、配置串口4、串口通信示例5

基于C#实现MQTT通信实战

《基于C#实现MQTT通信实战》MQTT消息队列遥测传输,在物联网领域应用的很广泛,它是基于Publish/Subscribe模式,具有简单易用,支持QoS,传输效率高的特点,下面我们就来看看C#实现... 目录1、连接主机2、订阅消息3、发布消息MQTT(Message Queueing Telemetr

PyQt6中QMainWindow组件的使用详解

《PyQt6中QMainWindow组件的使用详解》QMainWindow是PyQt6中用于构建桌面应用程序的基础组件,本文主要介绍了PyQt6中QMainWindow组件的使用,具有一定的参考价值,... 目录1. QMainWindow 组php件概述2. 使用 QMainWindow3. QMainW

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n

SpringQuartz定时任务核心组件JobDetail与Trigger配置

《SpringQuartz定时任务核心组件JobDetail与Trigger配置》Spring框架与Quartz调度器的集成提供了强大而灵活的定时任务解决方案,本文主要介绍了SpringQuartz定... 目录引言一、Spring Quartz基础架构1.1 核心组件概述1.2 Spring集成优势二、J

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方