最新版vue3+TypeScript开发入门到实战教程之组件通信之一

概述

Vue 组件通信是面试和实际开发中的核心知识点,组件通信包括父组件与子组件甚至孙组件的通信,子组件与子组件之间的通信。组件通信详细掌握以下9中方法:

  • props
  • 自定义事件
  • mitt
  • v-model
  • $attrs
  • refs、refs、refs、parent
  • provide、inject
  • pinia
  • slot

props

概述

props是组件通信中最常用的一种方式,常用于父与子之间数据传递

  • 父传子,通过数据传递
  • 子传父,通过函数传递数据

事例

  • 创建父组件App,数据为name、price

  • 创建子组件Fish,数据为num

  • 父传子数据name、price,父传子函数,子调用函数传数量num

  • 子接收数据、函数
    App组件代码

    <template>

    父组件接收到鱼的数量:{{ num }}

    <Fish :fishname="name" :price="price" :getNum="getNum"/>
    </template> <script setup lang="ts"> import { ref } from 'vue'; import Fish from './view/Fish.vue'; let name = ref('鲫鱼'); let price = ref(100); let num = ref(0); function getNum(n: number) { num.value= n; }

Fish组件代码

复制代码
<template>
  <div>
    <h2>鱼类:{{ fishname }}</h2>
    <h2>价格:{{ price }}</h2>
    <button @click="getNum(num++)">修改鱼的数据</button>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
let num = ref(999);
defineProps(['fishname','price','getNum'])
</script>

运行效果

自定义事件

父组件给子组件绑定自定义事件,子组件触发事件,回调父组件函数,传递数据,类似@click。自定义事件只能由子组件传递给父组件

  • 父组件传递自定义函数

  • 子组件触发自定义函数,传递参数
    App组件代码

    <template>

    父组件接收到鱼:{{ name }}

    父组件接收到鱼的价格:{{ price }}

    <Fish @get-fish="getFish"/>
    </template> <script setup lang="ts"> import { ref } from 'vue'; import Fish from './view/Fish.vue'; let name = ref(''); let price = ref(0); function getFish(s:string,p:number) { name.value = s; price.value = p; } </script>

Fish组件代码

复制代码
<template>
  <div>
    <h2>鱼类:{{ name }}</h2>
    <h2>价格:{{ price }}</h2>
    <button @click="emit('get-fish',name,price)">修改鱼的数据</button>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
let name = ref('鲫鱼');
let price = ref(999);
const emit = defineEmits(['get-fish']);
</script>

运行效果:

mitt

概述

mitt是一个第三方库,它可以实现任意组件通信。组件通过订阅接收消息,通过发布传递数据。

  • emitter.on(event, handler) 监听事件
  • emitter.emit(event, data) 触发事件并传递数据
  • emitter.off(event, handler) 移除事件监听
  • emitter.all.clear() 清空所有事件

事例

以子组件传递数据,父组件接收数据为例。同理若父组件给数据,子组件接收数据是一样的。

  • 安装mitt,npm install mitt
  • 创建utils目录,创建emitter.ts
  • main.ts引入emitter.ts
  • 创建App接收Fish传递数据,
  • 创建Fish,发送数据

emitter.ts代码

复制代码
import mitt from 'mitt'
const emitter = mitt();
export default emitter;

main.ts代码

复制代码
import { createApp } from 'vue'
import App from './App.vue'
import emitter from './utils/emitter'
console.log(emitter)
const app = createApp(App)
app.mount('#app')

App组件代码

复制代码
<template>
  <div class="app">
    <h2>父组件接收到鱼:{{ name }}</h2>
    <h2>父组件接收到鱼的价格:{{ price }}</h2>
    <Fish/>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import Fish from './view/Fish.vue';
import emitter from '@/utils/emitter'
let name = ref('');
let price = ref(0);
emitter.on('get-fish', (value:any) => {
  console.log(value)
  name.value = value.name;
  price.value=value.price
})
</script>

Fish组件代码

复制代码
<template>
  <div>
    <h2>鱼类:{{ fish.name }}</h2>
    <h2>价格:{{ fish.price }}</h2>
    <button @click="emitter.emit('get-fish',fish)">修改鱼的数据</button>
  </div>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
import emitter from '@/utils/emitter'
emitter.emit('test',121)
let fish = reactive({
  name: '鲫鱼',
  price:99
});
</script>

v-model

概述

v-model是双向数据绑定,它的底层是通过props参数modelValue与自定义函数update:modelValue实现的。在子组件接收props参数与自定义函数,就可以实现双向数据绑定。

事例

App代码

复制代码
<template>
  <div class="app">
    <h2>父组件接收到鱼:{{ name }}</h2>
    <Fish v-model="name"/>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import Fish from './view/Fish.vue';
let name = ref('鲫鱼');
</script>

Fish代码

复制代码
<template>
  <div>
    <h2>鱼类:{{ modelValue }}</h2>
    <button @click="changefish">修改鱼的数据</button>
  </div>
</template>
<script setup lang="ts">
let props = defineProps(['modelValue']);
const emit = defineEmits(['update:modelValue']);
function changefish() {
  emit('update:modelValue','草鱼')

}
</script>

运行查看结果

注意代码,v-model默认传递props参数是modelValue、自定义函数式update:modelValue,注意有冒号也是个函数。以下修改v-model props名称、自定义函数名称。

事例2修改v-model props名称与自定义函数名称

App源码

复制代码
<template>
  <div class="app">
    <h2>父组件接收到鱼:{{ name }}</h2>
    <h2>父组件接收到鱼:{{ price }}</h2>
    <Fish v-model="name" v-model:price="price"/>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import Fish from './view/Fish.vue';
let name = ref('鲫鱼');
let price = ref(666);
</script>

Fish源码

复制代码
<template>
  <div>
    <h2>鱼类:{{ modelValue }}</h2>
    <h2>鱼类:{{ price }}</h2>
    <button @click="changefish">修改鱼的数据</button>
  </div>
</template>
<script setup lang="ts">
let props = defineProps(['modelValue','price']);
const emit = defineEmits(['update:modelValue','update:price']);
function changefish() {
  emit('update:modelValue','草鱼')
  emit('update:price','999')

}
</script>

运行效果如下:

相关推荐
kyriewen5 分钟前
你写的代码没有测试,就像出门不锁门——Jest + Testing Library 从入门到不慌
前端·单元测试·jest
yuzhiboyouye1 小时前
web前端英语面试
前端·面试·状态模式
canonical_entropy2 小时前
下一代低代码渲染框架 nop-chaos-flux 的设计原则
前端·低代码·前端框架
东方小月2 小时前
5分钟搞懂Harness Engineering(驾驭工程):从提示词到AI Agent的进化之路
前端·后端·架构
我叫黑大帅2 小时前
为什么需要 @types/react?解决“无法找到模块 react 的声明文件”报错
前端·javascript·面试
之歆3 小时前
DAY_21JavaScript 深度解析:数组(Array)与函数(Function)(一)
前端·javascript
XinZong3 小时前
【AI社交】基于OpenClaw自研轻量化AI社交平台实战
前端
Le_ee4 小时前
ctfweb:php/php短标签/.haccess+图片马/XXE
开发语言·前端·php
爱上好庆祝4 小时前
学习js的第七天(wed APIs的开始)
前端·javascript·css·学习·html·css3
KaMeidebaby5 小时前
卡梅德生物技术快报|冻干工艺开发:注射用心肌肽全流程参数优化与工程化方案
前端·其他·百度·新浪微博