vue创建子组件步骤及注意事项

在 Vue 中创建子组件需要遵循组件化开发的核心原则,并注意数据流、通信机制、复用性等关键点。以下是详细步骤和注意事项,结合代码示例说明:


一、创建子组件的步骤

1. 定义子组件

创建一个 .vue 文件(单文件组件),包含模板、逻辑和样式:

<!-- ChildComponent.vue -->
<template><div class="child"><h3>{{ title }}</h3><button @click="handleClick">点击我</button></div>
</template><script>
export default {props: {title: {type: String,required: true}},emits: ['button-clicked'], // 声明触发的事件methods: {handleClick() {this.$emit('button-clicked', '来自子组件的消息');}}
};
</script><style scoped>
.child {border: 1px solid #ccc;padding: 20px;
}
</style>
2. 在父组件中引入并使用子组件
<!-- ParentComponent.vue -->
<template><div class="parent"><ChildComponent title="子组件标题"@button-clicked="handleChildEvent"/></div>
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},methods: {handleChildEvent(message) {console.log(message); // 输出:"来自子组件的消息"}}
};
</script>

二、关键注意事项

1. 组件通信
  • 父 → 子:通过 props 传递数据。

    • 单向数据流:子组件不能直接修改 props,需通过事件通知父组件修改。
    <!-- 父组件传递数据 -->
    <ChildComponent :title="parentTitle" /><!-- 子组件接收 -->
    <script>
    export default {props: ['title']
    };
    </script>
    
  • 子 → 父:通过 $emit 触发事件。

    <!-- 子组件触发事件 -->
    <button @click="$emit('update', newValue)">提交</button><!-- 父组件监听 -->
    <ChildComponent @update="handleUpdate" />
    
2. 插槽(Slots)

用于在子组件中插入动态内容,增强复用性:

<!-- 子组件 ChildComponent.vue -->
<template><div class="card"><slot name="header"></slot><slot>默认内容(当父组件不传递内容时显示)</slot></div>
</template><!-- 父组件使用 -->
<ChildComponent><template #header><h2>自定义标题</h2></template><p>这是父组件插入的内容</p>
</ChildComponent>
3. 作用域样式

使用 <style scoped> 隔离子组件样式,避免全局污染:

<style scoped>
/* 仅对当前组件生效 */
.child {background: #f0f0f0;
}
</style>
4. 性能优化
  • 避免不必要的渲染

    • 使用 v-once 静态缓存:
      <div v-once>{{ staticContent }}</div>
      
    • 复杂数据使用 computed 属性缓存:
      computed: {filteredList() {return this.list.filter(item => item.active);}
      }
      
  • 异步组件:按需加载子组件(Vue 3):

    const ChildComponent = defineAsyncComponent(() => import('./ChildComponent.vue'));
    
5. Props 设计规范
  • 类型检查:明确数据类型和默认值。

    props: {count: {type: Number,default: 0,validator: (value) => value >= 0}
    }
    
  • 复杂对象传递:使用 v-bind 绑定对象:

    <!-- 父组件 -->
    <ChildComponent v-bind="userData" /><!-- 等价于 -->
    <ChildComponent :name="userData.name" :age="userData.age" />
    
6. 事件命名规范
  • 自定义事件名:建议使用 kebab-case(短横线命名),避免与原生事件冲突。
    <!-- 子组件触发 -->
    this.$emit('custom-event', data);<!-- 父组件监听 -->
    <ChildComponent @custom-event="handler" />
    

三、Vue 3 的新特性

1. 组合式 API(Composition API)

更灵活的逻辑复用方式(推荐在复杂组件中使用):

<script setup>
import { ref, defineProps, defineEmits } from 'vue';const props = defineProps({title: String
});
const emit = defineEmits(['button-clicked']);const handleClick = () => {emit('button-clicked', '来自子组件的消息');
};
</script>
2. 多个 v-model 绑定

支持在单个组件上绑定多个 v-model

<!-- 父组件 -->
<ChildComponent v-model:name="userName" v-model:age="userAge" /><!-- 子组件 -->
<script setup>
defineProps(['name', 'age']);
defineEmits(['update:name', 'update:age']);
</script>

四、常见问题与解决方案

1. Props 未触发更新
  • 问题:直接修改对象/数组类型的 props(如 props.list.push(newItem))。
  • 解决:深拷贝数据或通过事件通知父组件修改。
2. 样式污染
  • 问题:未使用 scoped 导致样式影响全局。
  • 解决:始终添加 <style scoped> 或使用 CSS Modules。
3. 事件未触发
  • 问题:未在子组件中声明 emits(Vue 3 中会警告)。
  • 解决:显式声明 emits 选项。

五、总结

核心要点实现方式
创建子组件单文件组件(.vue),包含 <template>, <script>, <style>
父子通信props(父 → 子),$emit(子 → 父)
插槽<slot> 插入动态内容,<slot name="header"> 具名插槽
样式隔离<style scoped> 或 CSS Modules
性能优化v-oncecomputed、异步组件
Vue 3 特性组合式 API、<script setup>、多个 v-model

通过合理设计组件职责、规范通信机制、优化渲染性能,可以构建 高复用、易维护 的 Vue 子组件。

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

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

相关文章

Cocos Creator版本发布时间线

官网找不到&#xff0c;DeepSeek给的答案&#xff0c;这里做个记录。 Cocos Creator 1.x 系列 发布时间&#xff1a;2016 年 - 2018 年 1.0&#xff08;2016 年 3 月&#xff09;&#xff1a; 首个正式版本&#xff0c;基于 Cocos2d-x 的 2D 游戏开发工具链&#xff0c;集成可…

【Spring AI】基于专属知识库的RAG智能问答小程序开发——功能优化:用户鉴权主体功能开发

系列文章目录 【Spring AI】基于专属知识库的RAG智能问答小程序开发——完整项目&#xff08;含完整前端后端代码&#xff09;【Spring AI】基于专属知识库的RAG智能问答小程序开发——代码逐行精讲&#xff1a;核心ChatClient对象相关构造函数【Spring AI】基于专属知识库的R…

【AI神经网络】深度神经网络(DNN)技术解析:从原理到实践

引言 深度神经网络&#xff08;Deep Neural Network, DNN&#xff09;作为人工智能领域的核心技术&#xff0c;近年来在计算机视觉、自然语言处理、医疗诊断等领域取得了突破性进展。与传统机器学习模型相比&#xff0c;DNN通过多层非线性变换自动提取数据特征&#xff0c;解决…

目标跟踪——deepsort算法详细阐述

deepsort 算法详解 Unmatched Tracks(未匹配的轨迹) 本质角色: 是已存在的轨迹在当前帧中“失联”的状态,即预测位置与检测结果不匹配。 生命周期阶段: 已初始化: 轨迹已存在多帧,可能携带历史信息(如外观特征、运动模型)。 未被观测到: 当前帧中未找到对应的检测框…

Vue-admin-template安装教程

#今天配置后台管理模板发现官方文档的镜像网站好像早失效了&#xff0c;自己稍稍总结了一下方法# 该项目环境需要node17及以下&#xff0c;如果npm install这一步报错可能是这个原因 git clone https://github.com/PanJiaChen/vue-admin-template.git cd vue-admin-template n…

Rust从入门到精通之进阶篇:14.并发编程

并发编程 并发编程允许程序同时执行多个独立的任务&#xff0c;充分利用现代多核处理器的性能。Rust 提供了强大的并发原语&#xff0c;同时通过类型系统和所有权规则在编译时防止数据竞争和其他常见的并发错误。在本章中&#xff0c;我们将探索 Rust 的并发编程模型。 线程基…

算法训练营第二十三天 | 贪心算法(一)

文章目录 一、贪心算法理论基础二、Leetcode 455.分发饼干二、Leetcode 376. 摆动序列三、Leetcode 53. 最大子序和 一、贪心算法理论基础 贪心算法是一种在每一步选择中都采取当前状态下的最优决策&#xff0c;从而希望最终达到全局最优解的算法设计技术。 基本思想 贪心算…

css基础-display 常用布局

CSS display 属性详解 属性设置元素是否被视为块级或行级盒子以及用于子元素的布局&#xff0c;例如流式布局、网格布局或弹性布局。 一、基础显示模式 1. block 作用&#xff1a; 元素独占一行可设置宽高和内外边距默认宽度撑满父容器 应用场景&#xff1a; 布局容器&a…

速卖通API数据清洗实战:从原始JSON到结构化商品数据库

下面将详细介绍如何把速卖通 API 返回的原始 JSON 数据清洗并转换为结构化商品数据库。 1. 数据获取 首先要借助速卖通 API 获取商品数据&#xff0c;以 Python 为例&#xff0c;可使用requests库发送请求并得到 JSON 数据。 import requests# 替换为你的 API Key 和 Secret …

【零基础入门unity游戏开发——2D篇】2D物理系统 —— 2D刚体组件(Rigidbody2D)

考虑到每个人基础可能不一样,且并不是所有人都有同时做2D、3D开发的需求,所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】:主要讲解C#的基础语法,包括变量、数据类型、运算符、流程控制、面向对象等,适合没有编程基础的…

Collectors.toMap / list 转 map

前言 略 Collectors.toMap List<User> userList ...; Map<Long, User> userMap userList.stream().collect(Collectors.toMap(User::getUserId, Function.identity()));假如id存在重复值&#xff0c;则会报错Duplicate key xxx, 解决方案 两个重复id中&#…

热门面试题第13天|Leetcode 110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和 222.完全二叉树的节点个数

222.完全二叉树的节点个数&#xff08;优先掌握递归&#xff09; 需要了解&#xff0c;普通二叉树 怎么求&#xff0c;完全二叉树又怎么求 题目链接/文章讲解/视频讲解&#xff1a;https://programmercarl.com/0222.%E5%AE%8C%E5%85%A8%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E8…

关于Object.assign

Object.assign 基本用法 Object.assign() 方法用于将所有可枚举属性的值从一个或者多个源对象source复制到目标对象。它将返回目标对象target const target { a: 1, b: 2 } const source { b: 4, c: 5 }const returnedTarget Object.assign(target, source)target // { a…

GitHub高级筛选小白使用手册

GitHub高级筛选小白使用手册 GitHub 提供了强大的搜索功能&#xff0c;允许用户通过高级筛选器来精确查找仓库、Issues、Pull Requests、代码等。下面是一些常用的高级筛选用法&#xff0c;帮助你更高效地使用 GitHub 搜索功能。 目录 搜索仓库搜索Issues搜索Pull Requests搜…

手动集成sqlite的方法

注意到sqlite有backup方法&#xff08;https://www.sqlite.org/backup.html&#xff09;。 也注意到android中sysroot下&#xff0c;没有sqlite3的库&#xff0c;也没有相关头文件。 如果要使用 sqlite 的backup&#xff0c;那么就需要手动集成sqlite代码到项目中。可以如下操…

蓝桥杯真题 2109.统计子矩阵

原题地址:1.统计子矩阵 - 蓝桥云课 问题描述 给定一个 NMNM 的矩阵 AA, 请你统计有多少个子矩阵 (最小 1111, 最大 NM)NM) 满足子矩阵中所有数的和不超过给定的整数 KK ? 输入格式 第一行包含三个整数 N,MN,M 和 KK. 之后 NN 行每行包含 MM 个整数, 代表矩阵 AA. 输出格…

蓝桥杯—最少操作数

一.题目 分析:每次可以进行三次操作&#xff0c;求在n步操作后可以达到目标数的最小n&#xff0c;和最短路径问题相似&#xff0c;分层遍历加记忆化搜索防止时间复杂度过高&#xff0c;还需要减枝操作 import java.util.HashSet; import java.util.LinkedList; import java.ut…

Linux内核NIC网卡驱动实战案例分析

以下Linux 内核模块实现了一个虚拟网络设备驱动程序&#xff0c;其作用和意义如下&#xff1a; 1. 作用 &#xff08;1&#xff09;创建虚拟网络设备对 驱动程序动态创建了两个虚拟网络设备&#xff08;nic_dev[0]和nic_dev[1]&#xff09;&#xff0c;模拟物理网卡的功能。这两…

Trae初使用心得(Java后端)

1.前提 2025年3月3日&#xff0c;字节跳动正式官宣“中国首个 AI 原生集成开发环境&#xff08;AI IDE&#xff09;”Trae 国内版正式上线&#xff0c;由于之前项目的原因小编没有及时的去体验&#xff0c;这几日专门抽空去体验了一下感觉还算可以。 2.特点 Trade重在可以白嫖…

[项目]基于FreeRTOS的STM32四轴飞行器: 十二.角速度加速度滤波

基于FreeRTOS的STM32四轴飞行器: 十二.滤波 一.滤波介绍二.对角速度进行一阶低通滤波三.对加速度进行卡尔曼滤波 一.滤波介绍 模拟信号滤波&#xff1a; 最常用的滤波方法可以在信号和地之间并联一个电容&#xff0c;因为电容通交隔直&#xff0c;信号突变会给电容充电&#x…