Vue 组件封装,父组件传参给子组件,子组件调用父组件。

2024-08-30 00:20

本文主要是介绍Vue 组件封装,父组件传参给子组件,子组件调用父组件。,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        在 Vue 开发中,组件化是提升代码复用性可维护性的重要手段。通过组件化,可以将常用的功能封装为独立的组件,并在需要的地方复用。本文将介绍如何在 Vue 中实现父组件与子组件之间的数据传递,以及子组件如何调用父组件的方法。

一、组件封装的基本思路

在 Vue 中,通常会将一些可复用的逻辑、UI 封装成单独的组件。比如一个表单,如果需要在多个地方使用,最好的做法是将其提取为一个子组件,而不是在多个地方重复编写相同的代码。

项目场景

        前端有一个页面,需要要 《新增》 与 《详情》 展示一个内容一样的表单窗口。为了代码复用,我们将表单窗口提取为一个子组件,并且嵌入到《新增》 与 《详情》的代码中复用。我们需要在父组件中控制这个表单的显示与隐藏,并在表单提交后关闭窗口并刷新父组件的数据。

二、父组件向子组件传递数据与子组件调用父组件方法

        在 Vue 中,父组件通过 props 向子组件传递数据。props 是一种单向数据流,从父组件流向子组件。子组件在执行保存表单后调用父组件的方法实现,关闭窗口与刷新父组件数据列表。我们来看以下实现代码:

1. 父组件

<!-- ParentComponent.vue -->
<template><div><h1>Parent Component</h1><button @click="openForm">Open Form</button><!-- 新增窗口 --><Drawer title="新增车辆"   :mask-closable=false:closable=true v-model="show_edit_win" width="900"style="position: relative"><!-- 使用 props 向子组件传递数据 --><edit-form  @close-form="handleCloseForm" @refresh-data="refreshData" :brand-data="brandList" ></edit-form></Drawer><Drawer title="车辆详情"    :mask-closable=false:closable=true v-model="show_detail_win" width="1200"style="position: relative"><Tabs value="sub_win_tab" style="height: 100%;"><TabPane label="车辆信息" name="1"><edit-form :form-data="entity"  @refresh-data="refreshData" :brand-data="brandList" ></edit-form></TabPane><TabPane label="车辆使用记录" name="2"></TabPane><TabPane label="车辆维修记录" name="3"></TabPane></Tabs></Drawer></div>
</template><script>
import editForm from "./edit_form";export default {components: {editForm },data() {return {show_detail_win: false,  // 控制表单是否显示brandList:[] //车辆品牌};},methods: {openForm() {this.show_detail_win = true;},handleCloseForm() {this.show_edit_win=false;},refreshData() {//业务处理,一般是重新调用拉列表数据},}
};
</script>

2. 子组件

<!-- edit_form.vue -->
<template><div><Form :label-width="90" :model="entity" ref="entity_edit" :rules="ruleValidate"><div><h4>车辆信息</h4></div><Row :gutter="24"><Col span="8"><FormItem label="车辆号码:" prop="code"><Input v-model="entity.code" > </Input></FormItem></Col><Col span="8"><FormItem label="车辆VIN:" prop="vinCode"><Input v-model="entity.vinCode" > </Input></FormItem></Col><Col span="8"><FormItem label="车辆品牌:"><Select placeholder="车辆品牌" v-model="entity.brand"  clearable><Option v-for="item in brandList" :value="item.brand" :key="item.brand">{{item.brand}}</Option></Select></FormItem></Col></Row><Row :gutter="24"><Col span="8"><FormItem label="车辆系列:" prop="cardType"><Input v-model="entity.series" > </Input></FormItem></Col><Col span="8"><FormItem label="车辆型号:" prop="cardNo"><Input v-model="entity.model" > </Input></FormItem></Col><Col span="8"><FormItem label="车辆类型:" prop="cardType"><Select v-model="entity.type" placeholder="请选择车辆类型"   clearable><Option v-for="item in typeList" :key="item.value" :value="item.value">{{item.label}}</Option></Select></FormItem></Col></Row><Row :gutter="24"><Col span="24"><FormItem label="备注" prop="remark"><Input v-model="entity.remark" type="textarea" :autosize="{minRows: 5,maxRows: 8}"style="width: 800px;"placeholder="请输入备注信息..."> </Input></FormItem></Col></Row></Form><div style="text-align: center;padding-bottom: 10px;"><Button type="primary"  @click="doSave">保存</Button></div></div>
</template><script>export default {name: "edit_form",props: {formData: { //父组件在修改时传入的原对象数据,传入的不是引用而是副本。type: Object,required: false},brandData: {  //父组件传入的品牌数据type: Array,required: true}},data() {return {brandList:[...this.brandData],//品牌列表typeList:[{value:1,label:'公交车'},{value:2,label:'私家车'},],updateUrl: '/backend/resources/vehicle/edit',saveUrl: '/backend/resources/vehicle/save',entity:{...this.formData},ruleValidate: {code: [ {required: true, message: '不能为空', trigger: 'blur'}],vinCode: [ {required: true, message: '不能为空', trigger: 'blur'}],contacts: [ {required: true, message: '不能为空', trigger: 'blur'}],remark: [{required: false, message: '', trigger: 'blur'},{type: 'string', max: 30, message: '最多可录入30个字符', trigger: 'blur'}]}}},methods:{//增加或修改车辆doSave () {let self = this;self.$refs.entity_edit.validate((valid) => {if (valid) {let req = self.saveUrl;if (self.$util.isNotEmpty(self.entity.id)) {req = self.updateUrl;}self.$axios.post(req, self.entity).then(res => {if(res.code==200){self.$Message.success('操作成功!');self.$emit('refresh-data');  // 触发刷新数据的事件self.$emit('close-form');  // 触发关闭表单的事件}else{self.$Message.error(res.msg);}}).catch(e =>{self.show_edit_win = true;});}});},}}
</script><style scoped></style>

3. 代码关键点解释

   1 父组件向子组件传递数据:
  • 父组件通过 props 向子组件传递数据。在这个例子中,父组件将 parentFormData 传递给了子组件 FormComponent,子组件通过 props 接收这个数据。

  • 子组件不能直接修改传入的 props,因为 props 是不可变的。如果子组件需要修改这些数据,通常会将 props 的数据复制到本地状态(如 localFormData),然后操作本地数据。

   2 子组件调用父组件方法

        子组件不能直接调用父组件的方法。但我们可以通过事件通信的方式,让子组件触发事件,父组件监听事件并调用相应的方法。这种通信方式是 Vue 框架推荐的做法,符合单向数据流的设计思想

     具体步骤:
  1. 父组件定义方法:父组件中定义关闭表单和刷新数据的方法。
  2. 子组件触发事件:子组件通过 $emit 触发自定义事件。
  3. 父组件监听事件:父组件通过事件监听器捕获子组件触发的事件,并执行对应的方法。
  • 子组件通过 $emit 触发自定义事件。在表单提交后,子组件使用 this.$emit('close-form') 触发事件,通知父组件关闭窗口;同样使用 this.$emit('refresh-data') 触发事件,通知父组件刷新数据。

  • 父组件通过事件监听器监听事件。父组件通过 @close-form="handleCloseForm"@refresh-data="refreshData" 监听子组件触发的事件,并在事件发生时执行相应的方法。

4. 实现后的效果

  以上代码实现的效果图如下:

父组件新增】使用子组件后如下:

 父组件详情】使用子组件后如下:

三、总结

        在 Vue 的组件化开发中,父组件与子组件的通信是常见需求。通过 props,父组件可以向子组件传递数据;通过 $emit 事件,子组件可以通知父组件执行相应的操作。这样的单向数据流和事件通信机制,保证了组件之间的解耦和代码的可维护性。

这篇关于Vue 组件封装,父组件传参给子组件,子组件调用父组件。的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1119273

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

HTML提交表单给python

python 代码 from flask import Flask, request, render_template, redirect, url_forapp = Flask(__name__)@app.route('/')def form():# 渲染表单页面return render_template('./index.html')@app.route('/submit_form',