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组件,这样不但可以复用页面,也可以降低代码耦合性,更加清晰,上面举的例子不太合适,主要是提供一个思路,后续有机会再继续深入研究一下。

        如果有谁能有更合理的例子欢迎私信或评论告诉我,谢谢!!

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐