您的位置:首页 > 技术中心 > 前端框架 >

vue3组件间怎么通信?通信方式浅析

时间:2023-04-21 23:18

在我们写 vue3 的项目中,我们都会进行组件通信,我们除了使用 pinia 公共数据源的方式除外,我们还可采用那些更简单的API方法呢?那下面我就来给大家介绍介绍几种父子组件和子父组件通信的方式。

vue3组件间怎么通信?通信方式浅析

1、父子组件通信

1.1 defineProps

父子组件通信我们第一个想到的就是props,我们在子组件显示声明所接受的props,然后我们在从父组件传入对应的 key与value, 这样我们就可以在子组件上接收到父组件传过来的属性与值。【相关推荐:vuejs视频教程、web前端开发】

具体实现如下:

// children.vue<template>  <ul class="list-group">      <li class="list-group-item" v-for="item in list" :key="index">        {{item}}      </li>  </ul></template><script setup>import { defineProps } from 'vue';const props = defineProps({    list :{        type: Array,        default: () => {}    }})</script>
// parent.vue<template>  <div class="parent-wrap">      <input type="text" v-model="value" class="form-control" placeholder="请输入">      <div class="input-group-append">          <button class="btn btn-primary" @click="handleAdd">添加</button>      </div>  </div>  <!-- child -->  <childrenVue :list="list"></childrenVue></template><script setup>import { ref } from 'vue';import childrenVue from './children.vue';const value = ref('')const list = ref(['javaScript', 'Html', 'CSS'])const handleAdd = () =>{    list.value.push(value.value)    value = ''}</script>

图片.png

如上图所示,我们既实现了在子组件上显示了父组件传过来的 list 数组,还使可以向list添加数据使子组件数据更新。

1.2 provide/inject

当我们聊完了props,我们第二个要介绍的就是 vue3 的一个组合式选项 provide 和inject。

projct用于提供可以被后代组件注入的值,而inject用于声明要通过从上层提供方匹配并注入进当前组件的属性。 其代码实现如下:

// children.vue<template>    <ul class="list-group">        <li class="list-group-item" v-for="item in list" :key="item">{{item}}</li>    </ul></template><script setup>import { inject } from 'vue';const list = inject('list')</script>
// parent.vue<template>    <div class="parent-wrap">        <input type="text" v-model="value" class="form-control" placeholder="请输入">        <div class="input-group-append">            <button class="btn btn-primary" @click="handleAdd">添加</button>        </div>    </div>    <!-- child -->    <childVue /></template><script setup>import childVue from "./child.vue";const { ref, provide, readonly } = require("vue");const value = ref('')const list = ref(['javaScript', 'HTML', 'CSS'])provide('list', readonly(list.value))const handleAdd = () => {list.value.push(value.value)}</script>

图片.png

如上图所示,我们使用 provide API向外提供了一个 key 为 list,值为list.value,同时将 list,value 设置成了只读属性,防止子组件修改父组件的数据源。然后我们 injectAPI接收了 list,实现了父子组件的通信。

2.子父组件通信

2.1 defineEmits

上面我介绍了两种父向子传值的方法,但在我们开发中,我们还会遇到子向父组件传值的情况,那我们该怎么解决呢? 第一个方法就是vue3中的 defineEmits API,代码实现如下:

// children.vue<template>    <div class="parent-wrap">        <input type="text" v-model="value" class="form-control" placeholder="请输入" />        <div class="input-group-append">            <button class="btn btn-primary" @click="handleAdd">添加</button>        </div>    </div></template><script setup>const { ref, defineEmits } = require("vue");const value = ref('')const emits = defineEmits(['add']) //父传子  // 给父组件传一个函数const handleAdd = () => {    emits('add', value.value)    value.value= ''}</script>
// parent.vue<template>      <childVue @add='handleAdd'/>    <ul class="list-group">        <li class="list-group-item" v-for="item in list" :key="item">{{item}}</li>    </ul></template><script setup>import { ref } from '@vue/reactivity';import childVue from './child.vue';const list = ref(['javaScript', 'HTML', 'CSS'])const handleAdd = (val) => {    list.value.push(val)}</script>

图片.png

如上图所示,我们在子组件上emit一个出了一个 add事件给父组件接收,同时在父组件上调用来执行添加的逻辑,再将 inputvalue变为空,实现了父组件向子组件传参。

2.2 v-model:xxx + emit

在介绍完 defineEmits后, 我们再来介绍一种与其有异曲同工之处的v-model:xxx + emit的方法,实现如下:

// children.vue<template>    <div class="parent-wrap">        <input type="text" v-model="value" class="form-control" placeholder="请输入" />        <div class="input-group-append">            <button class="btn btn-primary" @click="handleAdd">添加</button>        </div>    </div></template><script setup>const { ref, defineProps, defineEmits } = require("vue");const value = ref('')const props = defineProps({    list: {        type: Array,        default: () => []    }})const emits = defineEmits(['list'])  // 给父组件一点东西const handleAdd = () => {    // props.list.push(value.value)  //不建议直接修改props的值 把握不住数据源的流转    const arr = props.list    arr.push(value.value)    emits('list', arr)    value.value= ''}</script>
<template>      <childVue v-model:list="list" @list ='add'/>    <ul class="list-group">        <li class="list-group-item" v-for="item in list" :key="item">{{item}}</li>    </ul></template><script setup>import { ref } from '@vue/reactivity';import childVue from './child.vue';const list = ref(['javaScript', 'HTML', 'CSS'])const add =(val) => {    console.log(val);    console.log(list);}</script>

图片.png

再和上面的defineEmits方法比较完以后,相信大家也看出了这两者的异曲同工在哪了。我们这里是先将父组件的list传给了子组件,再在子组件修改了父组件的数据源,同时再emit还给父组件,实现了子组件向父组件传值。

(学习视频分享:vuejs入门教程、编程基础视频)

以上就是vue3组件间怎么通信?通信方式浅析的详细内容,更多请关注Gxl网其它相关文章!

热门排行

今日推荐

热门手游