当前位置:首页 > 技术 > 正文内容

Vue 2 组件数据流动全景图:15 种通信方案详解与示例

访客 技术 2026年9月29日 10

在 Vue 2 中,组件是 UI 的最小单元,而数据流动则是组件之间协作的"血液"。本文用 15 种方式演示如何安全、优雅地把数据从一个组件送到另一个组件,并给出可直接粘贴运行的代码片段。

一、父子组件通信

1. props / $emit

最常见的"父→子"与"子→父"组合。

// Parent.vue
<template>
  <counter :initial="num" @add="inc"/>
</template>

<script>
export default {
  data: () => ({ num: 0 }),
  methods: { inc(v) { this.num += v } }
}
</script>

// Counter.vue
<template>
  <button @click="$emit('add', 1)">+</button>
</template>

<script>
export default { props: { initial: Number } }
</script>

2. .sync 语法糖

把上例的 v-bind:page.sync="page" 与 this.$emit('update:page', newVal) 组合即可实现"双向绑定"。

3. v-model

自定义组件也可使用 v-model,只需声明 model: { prop: 'value', event: 'input' }。

4. ref

// Parent.vue
<child ref="c"/>
mounted() {
  this.$refs.c.reset();   // 直接调用子组件方法
}

5. $children / $parent

通过索引访问子实例,或子组件通过 this.$parent.xxx 访问父实例。不推荐在复杂场景使用,因为顺序不可预期。

二、跨级通信

6. $attrs / $listeners

在多层嵌套时,把父级属性/事件一次性透传到孙组件,避免"逐层声明"。

<grand-child v-bind="$attrs" v-on="$listeners"/>

7. provide / inject

适合主题、国际化等"全局"常量或方法的注入。

// Ancestor.vue
provide() {
  return { theme: this.themeColor }
}

// DeepDescendant.vue
inject: ['theme']

三、兄弟或任意组件通信

8. EventBus(中央事件总线)

// bus.js
import Vue from 'vue'
export default new Vue()

// 发送方
import Bus from './bus'
Bus.$emit('login', user)

// 接收方
import Bus from './bus'
Bus.$on('login', user => { ... })

9. Vuex

当项目规模变大,使用集中式 Store 统一管理状态。

// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
  state: { count: 0 },
  mutations: { plus(state) { state.count++ } }
})

// 组件内
methods: {
  ...mapMutations(['plus'])
}

10. $root

直接访问根实例上的数据或方法,适合极小型应用或插件。

四、内容分发与路由

11. slot(插槽)

// Card.vue
<div class="card">
  <slot name="header"/>
  <slot/>
</div>

// 使用
<card>
  <template #header>标题</template>
  正文
</card>

12. 作用域插槽

子组件把内部数据暴露给父级模板。

<slot :user="user"></slot>

13. 路由传参

  • 路径参数:/user/:id → this.$route.params.id
  • 查询参数:/user?id=1 → this.$route.query.id
  • 命名路由 + params:不会出现在 URL,刷新丢失。

五、轻量级响应式仓库

14. Vue.observable

在不需要 Vuex 的小项目里,用 Vue.observable 创建一个最小全局 Store。

// store.js
import Vue from 'vue'
export const state = Vue.observable({ count: 0 })
export const setCount = n => state.count = n

// 组件
import { state, setCount } from './store'
computed: { count: () => state.count }
methods: { setCount }

六、小结速查表

场景推荐方案
父→子props / v-model / .sync
子→父$emit / v-on
隔代provide/inject 或 $attrs/$listeners
兄弟EventBus / Vuex
全局Vuex / $root / Vue.observable

根据团队规模、状态复杂度选择最合适的通信方式,才能保持代码长期可维护。

标签: vue2Props

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。