文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Vue3组件间的通信方式详解

2023-05-17 11:13

关注

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

1、父子组件通信

1.1 defineProps

父子组件通信我们第一个想到的就是props,我们在子组件显示声明所接受的props,然后我们在从父组件传入对应的 key与value, 这样我们就可以在子组件上接收到父组件传过来的属性与值。

具体实现如下:

// 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>

如上图所示,我们既实现了在子组件上显示了父组件传过来的 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>

如上图所示,我们使用 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>

如上图所示,我们在子组件上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>

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

到此这篇关于Vue3组件间的通信方式详解的文章就介绍到这了,更多相关Vue3组件通信内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯