深度解析Vue.js组件间的通信方式

Vue.js 组件通信主要通过以下几种方式来实现:

Props(属性)

  • 方向:父组件到子组件
  • 用途:父组件通过属性向子组件传递数据。
  • 特性:
    • 只读:默认情况下,子组件不能改变props的值。
    • 验证:可以通过props选项定义验证规则。
    • 动态:props的值可以随父组件状态的变化而变化。
父组件(Parent.vue)
<template><div><ChildComponent :message="parentMessage" /></div>
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},data() {return {parentMessage: 'Hello from Parent'};}
};
</script>
子组件(ChildComponent.vue)
<template><div><p>{{ message }}</p></div>
</template><script>
export default {props: {message: String}
};
</script>

$emit(事件)

  • 方向:子组件到父组件
  • 用途:子组件通过触发自定义事件来通知父组件。
  • 特性:
    • 传递数据:事件可以携带数据。
    • 多个事件:子组件可以触发多个不同的事件。
子组件(ChildComponent.vue)
<template><button @click="notifyParent">Notify Parent</button>
</template><script>
export default {methods: {notifyParent() {this.$emit('child-event', 'Hello from Child');}}
};
</script>
父组件(Parent.vue)
<template><ChildComponent @child-event="handleChildEvent" />
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},methods: {handleChildEvent(data) {console.log('Received data from child:', data);}}
};
</script>

Vuex

  • 全局状态管理
  • 用途:用于管理整个应用的状态,任何组件都可以访问。
  • 特性:
    • State:存储全局状态。
    • Mutations:唯一改变state的方式,同步操作。
    • Actions:用于异步操作,可以派发mutations。
    • Getters:计算属性,基于state创建缓存的属性。
    • Modules:大型应用中可以分割状态管理模块。
首先,设置 Vuex Store:

store.js

import Vue from 'vue';
import Vuex from 'vuex';Vue.use(Vuex);export default new Vuex.Store({state: {sharedCounter: 0},mutations: {increment(state) {state.sharedCounter++;}},actions: {incrementAsync({ commit }) {setTimeout(() => {commit('increment');}, 1000);}},getters: {getCounter: state => state.sharedCounter}
});

主应用(main.js)

确保应用使用了 Vuex Store

import Vue from 'vue';
import App from './App.vue';
import store from './store';new Vue({store,render: h => h(App)
}).$mount('#app');
父/子组件使用 Vuex

可以在任何组件中通过 this.$store 访问 Vuex Store

ComponentUsingVuex.vue

<template><div><p>Counter: {{ counter }}</p><button @click="increment">Increment</button><button @click="incrementAsync">Increment Async</button></div>
</template><script>
export default {computed: {counter() {return this.$store.getters.getCounter;}},methods: {increment() {this.$store.commit('increment');},incrementAsync() {this.$store.dispatch('incrementAsync');}}
};
</script>

Provide/Inject

  • 跨级通信
  • 用途:允许祖先组件提供数据,后代组件注入数据,无需依赖父组件层级。
  • 特性:
    • 不受组件层次限制,但可能导致代码耦合度增加。
    • 不推荐在常规组件通信中广泛使用,更适合库或框架级别的数据传递。
祖先组件(AncestorComponent.vue)
<template><div><ChildComponent /></div>
</template><script>
export default {provide() {return {ancestorValue: 'Value from Ancestor'};}
};
</script>
后代组件(DescendantComponent.vue)
<template><div><p>Value from Ancestor: {{ injectedValue }}</p></div>
</template><script>
export default {inject: ['ancestorValue'],mounted() {console.log('Injected value:', this.injectedValue);}
};
</script>

Ref 和 v-model

  • 直接引用
  • 用途:父组件直接引用子组件实例,或双向数据绑定。
  • 特性:
    • Refs:用于获取子组件实例或DOM元素,进行直接操作。
    • v-model:用于双向数据绑定,常见于表单元素,也可以应用于自定义组件。
父组件(ParentComponent.vue)
<template><ChildComponent ref="childRef" v-model="parentValue" /><button @click="logChildRef">Log Child Ref</button>
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},data() {return {parentValue: 'Initial Value'};},methods: {logChildRef() {console.log(this.$refs.childRef);}}
};
</script>
子组件(ChildComponent.vue)
<template><input :value="value" @input="$emit('input', $event.target.value)" />
</template><script>
export default {props: ['value']
};
</script>

Custom Events(自定义事件)

  • 事件通信
  • 用途:自定义事件允许组件间非标准的通信。
  • 特性:
    • 可以在任何组件之间触发和监听。
    • 适用于特定的交互或组件间的复杂通信。
子组件(ChildComponent.vue)
<template><button @click="customEvent">Send Custom Event</button>
</template><script>
export default {methods: {customEvent() {this.$emit('custom-event', 'Data to send');}}
};
</script>
父组件(ParentComponent.vue)
<template><ChildComponent @custom-event="handleCustomEvent" />
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},methods: {handleCustomEvent(data) {console.log('Received custom event data:', data);}}
};
</script>

Slots(插槽)

  • 内容分发
  • 用途:允许父组件的内容插入到子组件的特定位置。
  • 特性:
    • 默认插槽:子组件的默认内容区域。
    • 具名插槽:子组件可以定义多个插槽,父组件指定插入内容的位置。
    • 作用域插槽:父组件可以访问子组件的数据来决定插槽内容。
父组件(ParentComponent.vue)
<template><WrapperComponent><h1 slot="header">Custom Header</h1><p slot="body">Custom Body Content</p></WrapperComponent>
</template><script>
import WrapperComponent from './WrapperComponent.vue';export default {components: {WrapperComponent}
};
</script>
WrapperComponent.vue
<template><div><slot name="header"></slot><div class="content"><slot name="body"></slot></div></div>
</template>

Composition API(组合API)

  • 新功能
  • 用途:Vue 3引入的新特性,允许在组件内更好地组织逻辑和数据。
  • 特性:
    • setup() 函数:在组件生命周期开始时运行,可以访问props和触发生命周期钩子。
    • refreactive:用于响应式数据管理。
    • provideinject:在组合API中也有相应的实现,更灵活地进行跨组件数据传递。
父组件(ParentComponent.vue)
<template><ChildComponent :count="count" @updateCount="updateCount" />
</template><script>
import { ref, onMounted } from 'vue';
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},setup() {const count = ref(0);function updateCount(newCount) {count.value = newCount;}onMounted(() => {console.log('Initial count:', count.value);});return {count,updateCount};}
};
</script>
子组件(ChildComponent.vue)
<template><button @click="increment">Increment</button>
</template><script>
import { ref, emit } from 'vue';export default {props: ['count'],setup(props) {const count = ref(props.count);function increment() {count.value++;emit('updateCount', count.value);}return {count,increment};}
};
</script>

2500G计算机入门到高级架构师开发资料超级大礼包免费送!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/17873.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于学习Go语言的并发编程

开始之前&#xff0c;介绍一下​最近很火的开源技术&#xff0c;低代码。 作为一种软件开发技术逐渐进入了人们的视角里&#xff0c;它利用自身独特的优势占领市场一角——让使用者可以通过可视化的方式&#xff0c;以更少的编码&#xff0c;更快速地构建和交付应用软件&#…

【数据结构】直接选择排序详解!

文章目录 1.直接选择排序 1.直接选择排序 &#x1f427; begin 有可能就是 maxi &#xff0c;所以交换的时候&#xff0c;要及时更新 maxi &#x1f34e; 直接选择排序是不稳定的&#xff0c;例如&#xff1a; 9 [9] 5 [5]&#xff0c;排序后&#xff0c;因为直接选择排序是会…

Debug-012-el-popover 使用 doClose() 关闭窗口不生效的处理方案

前言&#xff1a; 今天上午碰见一个非常奇怪的情况&#xff1a;一样的方法实现的功能&#xff0c;效果却不一样。 两个页面都是使用的doClose()去关闭的el-popover&#xff0c;其中有一个就是不生效&#xff0c;找不同找了半天&#xff0c;始终不得其解。请看效果吧&#xff1…

Day 5:2785. 将字符串中的元音字母排序

Leetcode 2785. 将字符串中的元音字母排序 给你一个下标从 0 开始的字符串 s &#xff0c;将 s 中的元素重新 排列 得到新的字符串 t &#xff0c;它满足&#xff1a; 所有辅音字母都在原来的位置上。更正式的&#xff0c;如果满足 0 < i < s.length 的下标 i 处的 s[i] …

【第5章】SpringBoot整合Druid

文章目录 前言一、启动器二、配置1.JDBC 配置2.连接池配置3. 监控配置 三、配置多数据源1. 添加配置2. 创建数据源 四、配置 Filter1. 配置Filter2. 可配置的Filter 五、获取 Druid 的监控数据六、案例1. 问题2. 引入库3. 配置4. 配置类5. 测试类6. 测试结果 七、案例 ( 推荐 )…

理解磁盘分区与管理:U启、PE、DiskGenius、MBR与GUID

目录 U启和PE的区别: U启(U盘启动): PE(预安装环境)&#xff1a; 在DiskGenius中分区完成之后是否还需要格式化&#xff1a; 1.建立文件系统&#xff1a; 2.清除数据&#xff1a; 3.检查并修复分区&#xff1a; 分区表格式中&#xff0c;MBR和GUID的区别&#xff1a; 1…

移动端开发 笔记01

目录 01 移动端的概述 02 移动端的视口标签 03 开发中的二倍图 04 流式布局 05 弹性盒子布局 01 移动端的概述 移动端包括:手机 平板 便携式设备 目前主流的移动端开发: 安卓设备 IOS设备 只要移动端支持浏览器 那么就可以使用浏览器开发移动端项目 开发移动端 使用…

怎么看外国的短视频:四川鑫悦里文化传媒有限公司

怎么看外国的短视频&#xff1a;跨文化视角下的观察与思考 随着全球化进程的加速和网络技术的飞速发展&#xff0c;外国短视频逐渐走进了我们的视野。这些来自不同文化背景、语言体系和审美观念的短视频作品&#xff0c;为我们打开了一扇了解世界的窗口。然而&#xff0c;如何…

golang中的md5、sha256数据加密文件md5/sha256值计算步骤和运行内存图解

在go语言中对数据计算一个md5&#xff0c;或sha256和其他语言 如java, php中的使用方式稍有不同&#xff0c; 那就是要加密的数据必须通过流的形式写入到你创建的Hash对象中。 Hash数据加密步骤 1. 先使用对应的加密算法包中的New函数创建一个Hash对象&#xff0c;(这个也就是…

leetCode. 85. 最大矩形

leetCode. 85. 最大矩形 部分参考上一题链接 leetCode.84. 柱状图中最大的矩形 此题思路 代码 class Solution { public:int largestRectangleArea( vector<int>& h ) {int n h.size();vector<int> left( n ), right( n );stack<int> st;// 求每个矩形…

vue/uniapp 企业微信H5使用JS-SDK

企业微信H5需要我们使用一些SDK方法如获取外部联系人userid 获取当前外部联系人userid 使用SDK前提是如何通过config接口注入权限验证配置 使用说明 - 接口文档 - 企业微信开发者中心 当前项目是vue项目&#xff0c;不好直接使用 引入JS文件&#xff0c;但我们可以安装依赖…

使用nexus搭建的docker私库,定期清理无用的镜像,彻底释放磁盘空间

一、背景 我们使用nexus搭建了docker镜像&#xff0c;随着推送的镜像数量越来越多&#xff0c;导致nexus服务器的磁盘空间不够用了。于是&#xff0c;我们急需先手动删除一些过期的镜像&#xff0c;可发现磁盘空间并没有释放。 那么&#xff0c;如何才能彻底释放掉呢&#xff…

FreeRTOS学习 -- 任务 API 函数

函数 uxTaskPriorityGet() 此函数用来查询指定任务的优先级&#xff0c;要使用此函数的话宏 INCLUDE_uxTaskPriorityGet 应该定义为 1。 函数 vTaskPrioritySet() 此函数用于改变某一个任务的任务优先级&#xff0c;要 使 用 此 函 数 的 话 宏 INCLUDE_vTaskPrioritySet 应…

一维数组操作(GOC常考类型)答案

第1题 宇航局招聘 时限&#xff1a;1s 空间&#xff1a;256m 宇航局准备招收一批科研人员从事月球探索的航空科研工作。这个职位来了很多应聘者&#xff0c;宇航局对众多应聘者进行综合素质考试&#xff0c;最终会选出x名综合得分排名靠前应聘者。目前考试已经结束了&a…

Golang | Leetcode Golang题解之第102题二叉树的层序遍历

题目&#xff1a; 题解&#xff1a; func levelOrder(root *TreeNode) [][]int {ret : [][]int{}if root nil {return ret}q : []*TreeNode{root}for i : 0; len(q) > 0; i {ret append(ret, []int{})p : []*TreeNode{}for j : 0; j < len(q); j {node : q[j]ret[i] …

Java面试精粹:高级问题与解答集锦(一)

Java 面试问题及答案 1. 什么是Java的垃圾回收机制&#xff0c;它如何工作&#xff1f; 答案&#xff1a; Java的垃圾回收机制是一种自动内存管理功能&#xff0c;用于回收不再被应用程序使用的对象所占用的内存。它通过垃圾收集器&#xff08;Garbage Collector&#xff0c;…

js数据类型显隐式转换

在JavaScript中&#xff0c;数据类型的转换可以分为两种主要类型&#xff1a;显式类型转换&#xff08;Explicit Type Conversion&#xff09;和隐式类型转换&#xff08;Implicit Type Conversion 或 Type Coercion&#xff09;。 显式类型转换&#xff08;Explicit Type Con…

React18+TypeScript搭建通用中后台项目实战02 整合 antd 和 axios

配置路径别名 tsconfig.json {"compilerOptions": {"target": "ES2020","useDefineForClassFields": true,"lib": ["ES2020","DOM","DOM.Iterable"],"module": "ESNext&quo…

磁盘分区和挂载

磁盘分区和挂载 一、磁盘 业务层面&#xff1a;满足一定的需求所是做的特定操作 硬盘是什么以及硬盘的作用 硬盘&#xff1a;计算器的存储设备&#xff0c;一个或者多个磁性的盘片做成&#xff0c;可以在盘片上进行数据的读写 连接方式&#xff1a;内部设备&#xff0c;外…

深度揭秘:蓝海创意云渲染农场的五大特色功能

在当今数字化时代&#xff0c;影视制作、效果图设计等领域对于高质量的渲染需求日益增长。在这个背景下&#xff0c;云渲染平台成为了行业中不可或缺的一部分&#xff0c;它为用户提供了高效、灵活的渲染解决方案。蓝海创意云渲染农场https://www.vsochina.com/cn/render蓝海创…