1、对于后台管理系统我们常会看到增加与编辑弹框
通常都是大体一样的,只是很小的差异
对于这种情况,很多人都会将编辑与增加共用一个组件,然后在组件内通过v-if判断做处理,但是这种做法是会是两个模块产生耦合的,我们其实有更好的方法,就是将页面逻辑分开成不同的组件
2、这里就简单尝试一下
Add(增加的主要逻辑)、Edit(编辑的主要逻辑)、Page(静态页面)三个组件 ,下面是三个组件各自对应的代码
Add.vue
<template>
<el-Dialog
v-model="state.visible"
title="增加"
@close="handleReset"
>
<Page
ref="form"
:model="state.data"
/>
<template #footer>
<el-button type="primary" @click="hanldeSubmit">提交</el-button>
<el-button @click="handleReset">取消</el-button>
</template>
</el-Dialog>
</template>
<script lang="ts" setup>
import {ref, reactive, computed} from 'vue';
import Page from './Page.vue';
const props = defineProps<{
visible: boolean
}>()
const emits = defineEmits<{
(e:'update:visible', data: boolean):void
}>()
const form = ref<{
formRef: any ,
data: any
}>()
const state = reactive({
data: {
userName: undefined,
age: undefined
},
visible: computed({
get(){
return props.visible
},
set(val: boolean) {
emits('update:visible', val)
}
})
})
// 提交
const hanldeSubmit = ()=>{
console.log(form.value?.data);
state.visible = false
// 提交后清空数据
form.value?.formRef.resetFields();
}
// 重置
const handleReset = () =>{
form.value?.formRef.resetFields();
state.visible = false
}
</script>
<style scoped>
</style>
Edit.vue组件
<template>
<el-Dialog
v-model="state.visible"
title="编辑"
@close="handleReset"
@open="getData"
>
<Page
ref="form"
:model="state.data"
/>
<template #footer>
<el-button type="primary" @click="hanldeSubmit">提交</el-button>
<el-button @click="handleReset">取消</el-button>
</template>
</el-Dialog>
</template>
<script lang="ts" setup>
import {ref, reactive, computed} from 'vue';
import type { UserType } from '../types';
import Page from './Page.vue';
const props = defineProps<{
visible: boolean
}>()
const emits = defineEmits<{
(e:'update:visible', data: boolean):void
}>()
const state = reactive({
data: {
userName: undefined,
age: undefined
} as UserType,
visible: computed({
get(){
return props.visible
},
set(val: boolean) {
emits('update:visible', val)
}
})
})
const form = ref<{
formRef: any ,
data: any
}>()
// 模拟是请求数据了
const getData = ()=>{
setTimeout(()=>{
state.data = { userName: '麦先生', age: 25};
}, 100)
}
// 提交
const hanldeSubmit = ()=>{
console.log(form.value?.data);
state.visible = false
// 提交后清空数据
form.value?.formRef.resetFields();
}
// 重置
const handleReset = () =>{
console.log(form.value);
form.value?.formRef.resetFields();
state.visible = false
}
</script>
<style scoped>
</style>
Page.vue组件
<template>
<el-form
ref="formRef"
label-width="80px"
:model="data"
>
<el-form-item label="用户名" prop="userName">
<el-input type="text" v-model="data.userName" clearable/>
</el-form-item>
<el-form-item label="年龄" prop="age">
<el-input type="number" v-model="data.age" clearable/>
</el-form-item>
</el-form>
</template>
<script lang="ts" setup>
import {ref, reactive, watch} from 'vue';
import type { UserType } from '../types';
const props = defineProps<{
model: UserType
}>()
const data = ref<UserType>(props.model)
const formRef = ref(null)
watch(()=>props.model, (val)=>{
data.value = val
})
// 这样到出外面使用ref获取值才会有值,通过data: data.value则会有问题,编辑的时候获取不到值
defineExpose({ formRef, data })
</script>
<style scoped>
</style>
这样各个页面各司其职,页面改变就去修改Page.vue,增加逻辑改变就去修改Add.vue,比那几家逻辑改变就去修改Edit.vue组件,这样不但可以复用页面,也可以降低代码耦合性,更加清晰,上面举的例子不太合适,主要是提供一个思路,后续有机会再继续深入研究一下。
如果有谁能有更合理的例子欢迎私信或评论告诉我,谢谢!!