【vue教程】三. 组件复用和通信(7 种方式)

news2024/11/15 4:32:55

目录

    • 本章涵盖知识点
    • 回顾
  • 组件开发与复用
    • 组件的创建和注册
      • 全局定义
      • 局部定义
      • 单文件组件(.vue 文件)
      • 组件的注册方式
        • 在实例中注册
        • 在 Vue 中注册
    • 组件的 props
      • 定义 props
      • 传递 props
    • 组件事件
      • 自定义事件的创建和触发
      • 父组件监听子组件事件
      • 父组件处理事件
    • Vue 实现逻辑复用的两种方式
      • 插件 (Plugins)
      • 混入 (Mixins)
    • 内容分发--插槽(Slots)
      • 默认插槽
      • 具名插槽
      • 作用域插槽
      • 使用插槽
      • 作用域插槽的使用
  • 组件通信方式
    • 1. 父子组件通信
      • Props 和 Events
      • 实例演示
    • 2.Event Bus (非官方,但常用)
    • 3.`$attrs` 和 `$listeners` (v-bind 与 v-on)
    • 4.provide/inject (2.2.0+)
      • 实例演示
    • 5. 状态管理库(Vuex)
      • 实例演示
    • 6.ref
    • 7. `$parent` / `$children`
    • 常见使用场景可以分为三类:
    • 结语

本章涵盖知识点

  • 组件的基本概念和作用
  • 组件的创建和注册
  • 组件的 props、事件和自定义事件
  • 三类插槽(slot)的使用
  • 组件间常见的7种通信方式

回顾

在前两篇文章中,我们分别介绍了 Vue.js 的基础知识,包括 Vue 实例、模板语法、数据绑定、事件处理等。本文将主要学习组件化,组件化是 Vue.js 的核心概念之一,它允许开发者将界面拆分成独立、可复用的组件,使得开发大型应用变得更加简单和高效。


在这里插入图片描述

正文开始如果觉得文章对您有帮助,请帮我三连+订阅,谢谢💖💖💖


组件开发与复用

组件的创建和注册

Vue 组件是可复用的 Vue 实例,拥有自己的模板、数据和方法。

全局定义

// 全局注册组件
Vue.component('my-component', {
  template: '<div>我是全局组件!</div>',
})

局部定义

// 在特定实例中局部注册组件
new Vue({
  components: {
    'my-component': {
      template: '<div>我是局部组件!</div>',
    },
  },
})

单文件组件(.vue 文件)

<template>
  <div>A single file component!</div>
</template>
<script>
export default {
  // component definition
}
</script>

组件的注册方式

在实例中注册
new Vue({
  components: {
    'my-component': MyComponentDefinition,
  },
})
在 Vue 中注册
// 全局注册后可以在任何实例中使用
Vue.component('my-component', MyComponentDefinition)

组件的 props

Props 是父组件向子组件传递数据的一种方式。

定义 props

// 在 JavaScript 中是 camelCase 的
props: ['id', 'name', 'isCompleted']

传递 props

<todo-item id="1" name="Learn Vue" :is-completed="false"></todo-item>

组件事件

组件可以向父组件触发自定义事件。

自定义事件的创建和触发

methods: {
  notifyParent: function () {
    this.$emit('custom-event', 'Hello from child!');
  }
}

父组件监听子组件事件

<child-component @custom-event="handleCustomEvent"></child-component>

父组件处理事件

methods: {
  handleCustomEvent: function (message) {
    console.log(message);
  }
}

Vue 实现逻辑复用的两种方式

插件 (Plugins)

可以全局或局部地添加功能。

// 插件
Vue.use({
  install(Vue) {
    Vue.prototype.$myGlobalMethod = function () {
      // ...
    }
  },
})

混入 (Mixins)

可以包含可复用的组件逻辑。

// myMixin.js
// 混入
export default {
  created: function () {
    this.hello()
  },
  methods: {
    hello: function () {
      console.log('hello from mixin!')
    },
  },
}
// 定义一个使用混入对象的组件
var Component = Vue.extend({
  mixins: [myMixin],
})

内容分发–插槽(Slots)

插槽是 Vue 组件用于内容分发的机制。

默认插槽

<!-- 子组件 -->
<template>
  <div>
    <slot>默认插槽内容</slot>
  </div>
</template>

具名插槽

<!-- 子组件 -->
<template>
  <div>
    <slot name="header">Default header</slot>
    <slot name="footer">Default footer</slot>
  </div>
</template>

作用域插槽

<!-- 子组件 -->
<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      <slot :item="item">text</slot>
    </li>
  </ul>
</template>

使用插槽

<child-component>
  <template v-slot:header>Header content</template>
  <template v-slot:footer>Footer content</template>
  Default content
</child-component>

作用域插槽的使用

<child-component>
  <template v-slot="slotProps">
    <div>{{ slotProps.item.defaultText }}</div>
  </template>
</child-component>

组件通信方式

1. 父子组件通信

Props 和 Events

  • Props:父组件可以通过props向子组件传递数据。
  • Events:子组件可以使用$emit向父组件发送事件。

实例演示

<!-- 子组件 -->
<template>
  <button @click="increment">Increment</button>
</template>

<script>
  export default {
    props: ['initialCount'],
    methods: {
      increment() {
        this.$emit('increment', this.initialCount + 1)
      },
    },
  }
</script>

<!-- 父组件 -->
<template>
  <child-component :initial-count="count" @increment="count++"></child-component>
</template>

2.Event Bus (非官方,但常用)

通过一个事件总线(通常是一个 Vue 实例)来通信。

// 创建一个中央事件总线
const EventBus = new Vue()

// 在组件中
EventBus.$emit('custom-event', 'some data')

EventBus.$on('custom-event', data => {
  // 处理事件
})

3.$attrs$listeners (v-bind 与 v-on)

  • $attrs:包含父作用域中不作为 prop 被识别(且获取)的属性绑定(classstyle除外)。
  • $listeners(在 Vue 2.x 中):包含了父作用域中的(不含.native修饰器的)v-on 事件监听器。它可以通过v-on="$listeners"传入内部组件。

4.provide/inject (2.2.0+)

  • provide:祖父组件可以使用provide来提供数据。
  • inject:后代组件可以使用inject来注入数据。

实例演示

// 祖父组件
provide() {
  return {
    someData: this.someData
  };
}
// 后代组件
inject: ['someData'],

5. 状态管理库(Vuex)

Vue 探索之旅:第六站 — Vue 的状态管理

对于复杂应用,可以使用 Vuex 来集中管理状态。

实例演示

// Vuex store
const store = new Vuex.Store({
  state: {
    count: 0,
  },
  mutations: {
    increment(state) {
      state.count++
    },
  },
})

// 组件中
this.$store.commit('increment')

6.ref

ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例

// 父组件
<template>
  <component-a ref="comA"></component-a>
</template>
<script>
  export default {
    mounted () {
      const comA = this.$refs.comA;
      console.log(comA.title);  // Vue.js
    }
  }
</script>

// component-a 子组件
export default {
  data() {
    return {
      title: 'Vue.js',
    }
  },
}

7. $parent / $children

使用 $parent$children 可能会导致组件之间的耦合度增加,这可能会使组件更难以重用和测试。因此,通常推荐使用 props 和 events 来实现父子组件之间的通信。

<template>
  <div>
    <h1>这是父组件</h1>
    <child-component1></child-component1>
    <child-component2></child-component2>
    <button @click="callChildMethod">调用子组件方法</button>
  </div>
</template>

<script>
import ChildComponent1 from './ChildComponent1.vue'
import ChildComponent2 from './ChildComponent2.vue'

export default {
  components: {
    ChildComponent1,
    ChildComponent2,
  },
  methods: {
    callChildMethod() {
      // 遍历所有子组件并调用它们的方法
      this.$children.forEach(child => {
        if (child.someMethod) {
          child.someMethod()
        }
      })
    },
  },
}
</script>
<!-- ChildComponent1.vue -->
<template>
  <div>
    <h2>我是子组件1</h2>
    <p>父组件的标题是: "{{ parentTitle }}"</p>
  </div>
</template>

<script>
export default {
  name: 'ChildComponent1',
  mounted() {
    // 访问父组件的属性
    this.parentTitle = this.$parent.someProperty || '父组件标题'
  },
  data() {
    return {
      parentTitle: '',
    }
  },
  methods: {
    someMethod() {
      alert('子组件1的方法被调用了!')
    },
  },
}
</script>

常见使用场景可以分为三类:

  • 父子通信:

    • 父向子传递数据是通过 props,子向父是通过 events($emit)
    • 通过父链 / 子链也可以通信($parent / $children)
    • ref 也可以访问组件实例
    • provide / inject API
    • a t t r s / attrs/ attrs/listeners
  • 兄弟通信:

    • Bus
    • Vuex
  • 跨级通信:

    • Bus
    • Vuex
    • provide / inject API
    • a t t r s / attrs/ attrs/listeners

结语

通过本文,我们详细了解了 Vue 组件化开发的各个方面,包括组件的多种创建和注册方式、props 的定义和传递、自定义事件的创建和触发、以及插槽的多种类型和用法。这些知识将帮助我们构建更加模块化和可复用的 Vue 应用。

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

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

相关文章

网格布局 HTML CSS grid layout demo

文章目录 页面效果代码 (HTML CSS)参考 页面效果 代码 (HTML CSS) <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…

Golang | Leetcode Golang题解之第275题H指数II

题目&#xff1a; 题解&#xff1a; func hIndex(citations []int) int {n : len(citations)return n - sort.Search(n, func(x int) bool { return citations[x] > n-x }) }

你了解GD32 MCU上下电要求吗

你了解GD32 MCU的上下电要求吗&#xff1f;MCU的上下电对于系统的稳定运行非常重要。 以GD32F30X为例&#xff0c;上电/掉电复位波形如如下图所示。 上电过程中&#xff0c;VDD/VDDA电压上电爬坡&#xff0c;当电压高于VPOR&#xff08;上电复位电压&#xff09;MCU开始启动&a…

设计测试用例的具体方法

一.等价类 等价类分为: 1.有效等价类 [6~15] 2.无效等价类 :小于6位,大于15位(不在数据范围内) 组合规则: 有效等价类组合的时候,尽可能一条测试用例尽可能多的覆盖有效等价类 无效等价类组合的时候,一条测试点,之恶能覆盖一个无效等价类 二.边界值 1.上点,离点,内点 上…

科技引领水资源管理新篇章:深入剖析智慧水利解决方案,展现其在提升水资源利用效率、优化水环境管理方面的创新实践

本文关键词&#xff1a;智慧水利、智慧水利工程、智慧水利发展前景、智慧水利技术、智慧水利信息化系统、智慧水利解决方案、数字水利和智慧水利、数字水利工程、数字水利建设、数字水利概念、人水和协、智慧水库、智慧水库管理平台、智慧水库建设方案、智慧水库解决方案、智慧…

git clone超时的解决方法

问题描述&#xff1a;在克隆一个仓库的时候&#xff0c;报错如下 git clone https://github.com/TeamWiseFlow/wiseflow.git Cloning into wiseflow... fatal: unable to access https://github.com/TeamWiseFlow/wiseflow.git/: Failed to connect to github.com port 443 aft…

【PyTorch】图像二分类项目

【PyTorch】图像二分类项目 【PyTorch】图像二分类项目-部署 【PyTorch】图像多分类项目 【PyTorch】图像多分类项目部署 图像分类是计算机视觉中的一项重要任务。在此任务中&#xff0c;我们假设每张图像只包含一个主对象。在这里&#xff0c;我们的目标是对主要对象进行分类。…

C#开源、简单易用的Dapper扩展类库 - Dommel

项目特性 Dommel 使用 IDbConnection 接口上的扩展方法为 CRUD 操作提供了便捷的 API。 Dommel 能够根据你的 POCO 实体自动生成相应的 SQL 查询语句。这大大减少了手动编写 SQL 代码的工作量&#xff0c;并提高了代码的可读性和可维护性。 Dommel 支持 LINQ 表达式&#xff…

论文阅读——Integrated Diffusive Antenna Array of Low Backscattering

文章目录 摘要一、背景介绍二、天线结构A. 缝隙天线B. 低频扩散单元C. 高频扩散单元D. 集成设计 三、验证总结 论文来源&#xff1a;https://ieeexplore.ieee.org/document/10309141 摘要 文章提出了一种低雷达散射截面&#xff08;RCS&#xff09;的扩散天线阵列。 作为示例…

axios请求大全

本文讲解axios封装方式以及针对各种后台接口的请求方式 axios的介绍和基础配置可以看这个文档: 起步 | Axios中文文档 | Axios中文网 axios的封装 axios封装的重点有三个&#xff0c;一是设置全局config,比如请求的基础路径&#xff0c;超时时间等&#xff0c;第二点是在每次…

【数据结构】二叉树——顺序结构——堆及其实现

一、树 1.1、树的概念和结构 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限节点组成的一个具有层次关系的集合。 树有一个特殊的节点&#xff0c;称为根节点&#xff0c;根节点没有前驱结点。 除根节点外&#xff0c;其余部分被分为M&…

Mysql - 索引

目录 一、存储引擎 二、索引 索引结构 索引分类 索引语法 联合索引 前缀索引 索引使用规则 最左前缀法则 范围查询使索引失效 字段做运算操作索引失效 字符串字段不加单引号索引失效 字段做前模糊查询索引失效 or连接条件索引失效 数据发布情况索引失效 指定使用…

Matlab编程资源库(1)选择结构

一、if语句 在 MATLAB 中&#xff0c; if 语句有 3 种格式。 (1) 单分支 if 语句&#xff1a; if 条件 语句组 end 当条件成立时&#xff0c;则执行语句组&#xff0c;执行完之后&#xff0c; 继续执行 if 语句的后继语句&#xff0c;若条件不成 立&#xff0c;则直接执…

什么是PCB流锡槽焊盘/C型焊盘,如何设计?-捷配笔记

在PCB进行机器组装器件时&#xff08;如波峰焊&#xff09;&#xff0c;为了防止部分需要二次焊接的元器件的焊盘堵孔&#xff0c;就需要在PCB焊盘上面开个过锡槽&#xff0c;以便过波峰焊时&#xff0c;这些焊锡会流掉。开流锡槽就是在焊盘裸铜&#xff08;敷锡&#xff09;部…

setsockopt选项对tcp速度

GPT-4 (OpenAI) 每个setsockopt调用都涉及到一个套接字描述符&#xff0c;一个指定网络层的常数&#xff08;如IPPROTO_IP, IPPROTO_TCP, IPPROTO_IPV6, SOL_SOCKET等&#xff09;&#xff0c;一个指定需配置的选项的常数&#xff0c;一个指向配置值的指针&#xff0c;以及那个…

04-数据库MySQL

一、项目要求 二、项目过程介绍 1、新建数据库 2、新建表 3、处理表 1.修改student 表中年龄(sage)字段属性&#xff0c;数据类型由int 改变为smallint 2.为Course表中Cno 课程号字段设置索引,并查看索引 3.为SC表建立按学号(sno)和课程号(cno)组合的升序的主键索引&#xf…

20分钟上手新版Skywalking 9.x APM监控系统

Skywalking https://skywalking.apache.org/ Skywalking是专为微服务、云原生和基于容器的&#xff08;Kubernetes&#xff09;架构设计的分布式系统性能监控工具。 Skywalking关键特性 ● 分布式跟踪 ○ 端到端分布式跟踪。服务拓扑分析、以服务为中心的可观察性和API仪表板。…

英迈中国与 Splashtop 正式达成战略合作协议

2024年7月23日&#xff0c;英迈中国与 Splashtop 正式达成战略合作协议&#xff0c;英迈中国正式成为其在中国区的战略合作伙伴。此次合作将结合 Splashtop 先进的远程桌面控制技术和英迈在技术服务与供应链管理领域的专业优势&#xff0c;为中国地区的用户带来更加安全的远程访…

Android TabLayout的简单用法

TabLayout 注意这里添加tab&#xff0c;使用binding.tabLayout.newTab()进行创建 private fun initTabs() {val tab binding.tabLayout.newTab()tab.text "模板库"binding.tabLayout.addTab(tab)binding.tabLayout.addOnTabSelectedListener(object : TabLayout.On…

【开源库编译 | zlib】 zlib库最新版本(zlib-1.3.1)在Ubuntu(Linux)系统下的 编译 、交叉编译(移植)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…