Vue3子组件
1.简介
Vue 3组件的主要优势之一就是它们可以帮助你将你的应用程序分解成可维护和可重用的部分。当你在应用程序中多次使用相同的代码时,你可以将它们抽象成一个组件,然后在应用程序中的多个地方使用该组件,而不必每次都编写相同的代码。
最近写前端代码,有些功能代码可以复用,于是尝试使用子组件方式优化代码。
总结主要有两个使用方向
-
一:像方法一样调用传递参数,调用组件(打开一个可复用的复杂详情页)
-
二:引入组件解决复杂的业务问题(比如一个可编辑表格,列字段是一个动态可以增删的tag标签,每次修改都需要通过遍历整个表格List对象,按照id匹配行数据,进而修改对应列字段,过程十分繁杂)
2.组件举例
2.1父组件
父组件点击按钮
父组件代码 - FatherComponent.vue
<template>
<div class="content_box">
<el-button @click="">处理</el-button>
</div>
<ChildComponent ref="childComponentRef" @success="handleSuccess"></ChildComponent>
</template>
<script lang="ts">
import {
defineComponent, nextTick,
onMounted, reactive, ref
} from 'vue';
import ChildComponent from "/@/views/my/childComponentRef.vue";
export default defineComponent({
name: 'FatherComponent',
components: {
ChildComponent,
},
setup() {
const childComponentRef = ref()
function openDetailInfo(record) {
let toData = {
costProjectAct: record.dictId,
name: record.dictName
}
childComponentRef.value?.openDetailDialog(toData)
}
function handleSuccess(){
//todo 刷新表格
reloadTable()
}
return {
openDetailInfo,childComponentRef,handleSuccess
};
},
});
</script>
2.2子组件
本子组件弹出一个Element-UI弹窗Dialog
子组件代码 - ChildComponent.vue
<template>
<div>
<el-dialog
v-model=" dataInfo.show"
:title="dataInfo.title"
width="30%"
:before-close="handleClose"
draggable
>
<span>This is a message</span>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">关闭</el-button>
<el-button type="primary" @click="submitForm">
提交
</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script lang="ts">
import {
defineComponent, defineExpose, onMounted, reactive, ref, watch
} from "vue";
export default defineComponent({
name: 'ChildComponent',
components: {
},
props: ['data'],
setup(props, { emit }) {
onMounted(() => {
});
const dataInfo =ref({
show: false,//编辑提示框是否显示
title: '',
})
function openDetailDialog(record){
dataInfo.value.title = "详情页-" + record.name
dataInfo.value.show = true
}
function handleClose(){
dataInfo.value.show = false
}
function submitForm(){
// todo 提交逻辑
// 1.子组件业务操作 - 当前模拟关闭弹窗
dataInfo.value.show = false
// 2.告知父组件需要刷新列表等操作 使用emit注意参数success需要和父组件对应
emit('success');
}
defineExpose({
openDetailDialog
})
return {
handleClose,dataInfo,openDetailDialog,submitForm
};
},
});
</script>
3.首先外部方法调用包含参数
3.1子组件
关键代码定义一个方法
function openDetailDialog(record){
dataInfo.value.title = "详情页-" + record.name
dataInfo.value.show = true
}
然后使用defineExpose暴露方法
defineExpose({
openDetailDialog
})
3.2父组件
1.使用方法调用需要给引入的子组件绑定ref对象
2.使用方法调用需要给引入的子组件绑定ref对象financeComponentRef.value?.openDialog(toData)方法调用组件中方法
<ChildComponent ref="childComponentRef" @success="handleSuccess"></ChildComponent>
//对象映射
const childComponentRef = ref()
childComponentRef.value?.openDetailDialog(toData)
4.组件通信-子组件通知父组件
4.1子组件
在子组件页面点击确认,关闭弹窗,同时通知父组件页面-表格组件刷新需要使用emit方法
在vue声明时候,可以看到emit参数
setup(props, { emit }) {
}
点击确认,使用 emit(‘success’); 发送消息告知父组件
function submitForm(){
// todo 提交逻辑
// 1.子组件业务操作 - 当前模拟关闭弹窗
dataInfo.value.show = false
// 2.告知父组件需要刷新列表等操作 使用emit注意参数success需要和父组件对应
emit('success');
}
4.2父组件
可以看到@success=“handleSuccess” 这个属性 其中@success需要和子组件中emit(‘success’) 的success对应,这样能触发我们再父组件绑定的方法
<ChildComponent ref="childComponentRef" @success="handleSuccess"></ChildComponent>
即调用父组件方法,刷新表格
function handleSuccess(){
//todo 刷新表格
reloadTable()
}
5.组件通信-父组件通知子组件
5.1父组件
父组件改造一下添加自定义属性 :data
父组件定义一个变量userInfo与:data绑定
<ChildComponent ref="childComponentRef" @success="handleSuccess" :data="userInfo"></ChildComponent>
const userInfo = ref({
id: '99789798789789',
name: '小明'
})
5.2子组件
在子组件中,可以看到props参数,使用 props[‘data’]形式接收父组件数据绑定参数
setup(props, { emit }) {
const userInfo = ref()
onMounted(() => {
userInfo.value = props['data']
console.log(userInfo.value )
});
}
像我们使用Element-UI的实际上可以理解为 v-model 绑定的参数,传递给el-dialog子组件props参数中
<el-dialog
v-model=" dataInfo.show"
:title="dataInfo.title"
width="30%"
:before-close="handleClose"
draggable
>