Vue3通信方式之defineProps、defineEmits、useAttrs、插件mitt和v-model

简介: Vue3通信方式之defineProps、defineEmits、useAttrs、插件mitt和v-model

1、使用defineProps

props可以实现父子组件通信,在vue3中我们可以通过defineProps获取父组件传递的数据。且在组件内部不需要引入defineProps方法可以直接使用!

父组件给子组件传递数据

<Child info="我爱祖国" :money="money"></Child>

子组件获取父组件传递数据:方式1

let props = defineProps({
      info:{
       type:String,//接受的数据类型
       default:'默认参数',//接受默认数据
      },
      money:{
       type:Number,
       default:0
    }})

子组件获取父组件传递数据:方式2

let props = defineProps(["info",'money']);

子组件获取到props数据就可以在模板中使用了,但是切记props是只读的(只能读取,不能修改)

2、使用defineEmits接受自定义事件

在vue框架中事件分为两种:一种是原生的DOM事件,另外一种自定义事件。

原生DOM事件可以让用户与网页进行交互,比如click、dbclick、change、mouseenter、mouseleave…

自定义事件可以实现子组件给父组件传递数据

2.1原生DOM事件

代码如下:

<pre @click="handler">
          我是祖国的老花骨朵
     </pre>

当前代码级给pre标签绑定原生DOM事件点击事件,默认会给事件回调注入event事件对象。当然点击事件想注入多个参数可以按照下图操作。但是切记注入的事件对象务必叫做$event.

<div @click="handler1(1,2,3,$event)">我要传递多个参数</div>

vue3框架click、dbclick、change(这类原生DOM事件),不管是在标签、自定义标签上(组件标签)都是原生DOM事件。

2.2自定义事件

自定义事件可以实现子组件给父组件传递数据.在项目中是比较常用的。

比如在父组件内部给子组件(Event2)绑定一个自定义事件

<Event2  @xxx="handler3"></Event2>

在Event2子组件内部触发这个自定义事件

<template>
      <div>
        <h1>我是子组件2</h1>
        <button @click="handler">点击我触发xxx自定义事件</button>
      </div>
    </template>
    
    <script setup lang="ts">
    let $emit = defineEmits(["xxx"]);
    const handler = () => {
      $emit("xxx", "法拉利", "茅台");
    };
    </script>
    <style scoped>
    </style>

我们会发现在script标签内部,使用了defineEmits方法,此方法是vue3提供的方法,不需要引入直接使用。defineEmits方法执行,传递一个数组,数组元素即为将来组件需要触发的自定义事件类型,此方执行会返回一个$emit方法用于触发自定义事件。

当点击按钮的时候,事件回调内部调用$emit方法去触发自定义事件,第一个参数为触发事件类型,第二个、三个、N个参数即为传递给父组件的数据。

需要注意的是:代码如下

<Event2  @xxx="handler3" @click="handler"></Event2>

正常说组件标签书写@click应该为原生DOM事件,但是如果子组件内部通过defineEmits定义就变为自定义事件了

let $emit = defineEmits(["xxx",'click']);

3、全局事件总线(插件mitt)

全局事件总线可以实现任意组件通信,在vue2中可以根据VM与VC关系推出全局事件总线。

但是在vue3中没有Vue构造函数,也就没有Vue.prototype.以及组合式API写法没有this,

那么在Vue3想实现全局事件的总线功能就有点不现实啦,如果想在Vue3中使用全局事件总线功能

可以使用插件mitt实现。

mitt:官网地址:https://www.npmjs.com/package/mitt

4、v-model

v-model指令可是收集表单数据(数据双向绑定),除此之外它也可以实现父子组件数据同步。

而v-model实指利用props[modelValue]与自定义事件[update:modelValue]实现的。

下方代码:相当于给组件Child传递一个props(modelValue)与绑定一个自定义事件update:modelValue

实现父子组件数据同步

<Child v-model="msg"></Child>

在vue3中一个组件可以通过使用多个v-model,让父子组件多个数据同步,下方代码相当于给组件Child传递两个props分别是pageNo与pageSize,以及绑定两个自定义事件update:pageNo与update:pageSize实现父子数据同步

<Child v-model:pageNo="msg" v-model:pageSize="msg1"></Child>

5、useAttrs

使用vue中的useAttrs方法可以获取组件标签上的属性和事件。

两个组件分别为父组件app.vue和子组件helloworld.vue

父组件:

<template>
  <el-button type="primary" size="small" :icon="Edit"></el-button>
  <HelloWorld msg="我是helloword子组件" type="primary" size="small" :icon="Edit" title="你好编辑" />
</template>
<script setup lang="ts">
  import HelloWorld from './components/HelloWorld.vue'
  import {
    Edit,
    Delete
  } from '@element-plus/icons-vue'
</script>
<style scoped>
</style>

子组件:

<template>
  <div class="card" :title="$attrs.title">
    <h3>{{ msg }}</h3>
    <el-button :="$attrs"></el-button>
  </div>
</template>
<script setup lang="ts">
  import {
    ref
  } from 'vue'
  import {
    useAttrs
  } from 'vue'
  let $attrs = useAttrs()
  console.log($attrs)
  defineProps < {
    msg: string
  } > ()
  const count = ref(0)
</script>
<style scoped>
  .card {
    background-color: antiquewhite;
  }
  .read-the-docs {
    color: #888;
  }
</style>

上述代码中,首先在父组件中引入子组件:

import HelloWorld from './components/HelloWorld.vue'

在父组件中,子组件标签上加上所需属性:

<HelloWorld msg="我是helloword子组件" type="primary" size="small" :icon="Edit" title="你好编辑" />

然后在子组件中引入vue中的useAttrs方法:

import {
    useAttrs
  } from 'vue'

useAttrs方法返回的是一个对象

let $attrs = useAttrs()
  console.log($attrs)

打印输出这个对象:

可以看到输出结果中,能接受到父组件标签中的属性值。

最后在子组件中属性绑定$attrs的值:

<el-button :="$attrs"></el-button>

注意事项(重点)

需要注意的是:props和useAttrs方法都可以获取到父组件传过来来的属性和属性值;

但是如果一旦用prop接受了其中的某个属性和属性值,那么useAttrs就接受不到这个属性和属性值。

目录
相关文章
|
7月前
|
JavaScript 前端开发 安全
Vue 3
Vue 3以组合式API、Proxy响应式系统和全面TypeScript支持,重构前端开发范式。性能优化与生态协同并进,兼顾易用性与工程化,引领Web开发迈向高效、可维护的新纪元。(238字)
1036 139
|
7月前
|
缓存 JavaScript 算法
Vue 3性能优化
Vue 3 通过 Proxy 和编译优化提升性能,但仍需遵循最佳实践。合理使用 v-if、key、computed,避免深度监听,利用懒加载与虚拟列表,结合打包优化,方可充分发挥其性能优势。(239字)
546 1
|
8月前
|
开发工具 iOS开发 MacOS
基于Vite7.1+Vue3+Pinia3+ArcoDesign网页版webos后台模板
最新版研发vite7+vue3.5+pinia3+arco-design仿macos/windows风格网页版OS系统Vite-Vue3-WebOS。
965 11
|
7月前
|
JavaScript 安全
vue3使用ts传参教程
Vue 3结合TypeScript实现组件传参,提升类型安全与开发效率。涵盖Props、Emits、v-model双向绑定及useAttrs透传属性,建议明确声明类型,保障代码质量。
621 0
|
8月前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
728 2
|
7月前
|
缓存 JavaScript
vue中的keep-alive问题(2)
vue中的keep-alive问题(2)
613 137
|
11月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
1159 0
|
11月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
12月前
|
JavaScript 数据可视化 前端开发
基于 Vue 与 D3 的可拖拽拓扑图技术方案及应用案例解析
本文介绍了基于Vue和D3实现可拖拽拓扑图的技术方案与应用实例。通过Vue构建用户界面和交互逻辑,结合D3强大的数据可视化能力,实现了力导向布局、节点拖拽、交互事件等功能。文章详细讲解了数据模型设计、拖拽功能实现、组件封装及高级扩展(如节点类型定制、连接样式优化等),并提供了性能优化方案以应对大数据量场景。最终,展示了基础网络拓扑、实时更新拓扑等应用实例,为开发者提供了一套完整的实现思路和实践经验。
1671 78
|
10月前
|
人工智能 JSON JavaScript
VTJ.PRO 首发 MasterGo 设计智能识别引擎,秒级生成 Vue 代码
VTJ.PRO发布「AI MasterGo设计稿识别引擎」,成为全球首个支持解析MasterGo原生JSON文件并自动生成Vue组件的AI工具。通过双引擎架构,实现设计到代码全流程自动化,效率提升300%,助力企业降本增效,引领“设计即生产”新时代。
730 1