vue3对话框组件封装

需求:1.添加功能与编辑功能调用一个组件,但想要它们传入的表单项不一样,比如点击添加功能后可以修改用户的姓名,电话,初始密码;点击编辑功能只能修改姓名和电话。
            2.调用后端接口saveOrUpdate使得新增和编辑的数据可以渲染到页面上

遇到问题:1.传入的表单项添加和编辑一样,无法根据id是否为0判断传入哪个表单项
                   2.数据渲染不到页面上

//index.vue      新增时想传入表单数据formData,编辑时传入editId
template>
  <el-card class="box-card">
    <template #header>
      <Search :searchData="searchData" :searchInfo="productionlineForm" @submitEmits="submitEmitsFn"></Search>
    </template>

    
    <DialogForm ref="dialog" :formData="formData" :formInfo="Form||Edit" :editId="editId" @confirmDia="confirmDia" />

<el-button @click="handleAdd" type="primary">添加</el-button>
    <el-table :data="queriedResult.records" border style="width: 100%">
      <el-table-column type="index" />
      <el-table-column prop="name" label="姓名" align="center" />
      <el-table-column prop="url" label="电话" align="center" />
      <el-table-column prop="description" label="城市ID" align="center" />
      <el-table-column prop="createdTime" label="年龄" align="center" />
      <el-table-column prop="url" label="专业ID" align="center" />
      <el-table-column label="操作">
        <el-button type="primary" @click="handleEdit">编辑</el-button>
        <el-button type="danger">删除</el-button>
      </el-table-column>
    </el-table>

    <el-pagination
      v-model:current-page="queriedResult.current"
      v-model:page-size="queriedResult.size"
      :page-sizes="[10, 20, 30, 40]"
      layout="total, sizes, prev, pager, next, jumper"
      :total="queriedResult.total"
      @size-change="(pageSize) => {queryMethod({size:pageSize})}"
      @current-change=" (pageNumber) => {queryMethod({current:pageNumber})}"
    />
  </el-card>
</template>
 
<script setup lang="ts">
import { ref, reactive } from 'vue';
import Search from '@/components/search/Search.vue';
import { queryMethod, queriedResult } from '@/composables/users';
import DialogForm from '@/components/dialog/DialogForm.vue';
import { ElMessage, dateEquals } from 'element-plus';
import {saveOrUpdate } from '@/api/users';

//搜索功能

const productionlineForm = ref({
  name: '',
  url: '',
  categoryId: ''
});
const searchData = ref([
  {
    label: '姓名',
    type: 'input',
    prop: 'name',
    placeholder: '请输入姓名'
  },
  {
    label: '电话',
    type: 'input',
    prop: 'url'
  },

  {
    label: '所在地',
    type: 'cascader',
    prop: 'adress',
  },
  {
    label: '性别',
    type: 'radio',
    prop: 'sex',
    radios: [
      {
        label: '男',
        value: 0
      },
      {
        label: '女',
        value: 1
      }
    ]
  },
  {
    label: '部门',
    type: 'select',
    prop: 'categoryId',
    options: [
      { label: '部门1', value: 'categoryId1' },
      { label: '部门2', value: 'categoryId2' },
      { label: '部门3', value: 'categoryId3' }
    ]
  }
]);

const submitEmitsFn = (val: any) => {
  productionlineForm.value = val;
  queryMethod(productionlineForm.value); 
};
queryMethod(); 



//添加功能
let dialog = ref<InstanceType<typeof DialogForm> | null>(null)
  const open = (id = 0): void => {
  if (id === 0) {
    dialog.value?.openDia();
  } else {
    // 编辑模式
    dialog.value?.openDia(id);
  }
}

const confirmDia = async (val: string) => {
  console.log(val);
  dialog.value?.closeDia();

  const { data } = await saveOrUpdate(formData.value).finally(() => dialog.value = null);
  if (data.code === '000000') {
    queryMethod({ current: 1 });
  } else {
    ElMessage.error('失败');
  }
}
const Form = ref({
  name: '',
  url: '',
  categoryId: '',
  password:'',
  
});

const Edit = ref({
  name: '',
  url: '',
  categoryId: '',

});
const formData = ref([
  {

    label: '姓名',
    type: 'input',
    prop: 'name',
    placeholder: '请输入姓名'
  },
  {

    label: '电话',
    type: 'input',
    prop: 'url',
    placeholder: '请输入电话'
  },

  {
    label: '密码',
    type: 'input',
    prop: 'password',
    placeholder: '请输入密码'
  },

]);

const editId= ref([
  {
    label: '姓名',
    type: 'input',
    prop: 'name',
    placeholder: '请输入姓名'
  },
  {
    label: '地址',
    type: 'input',
    prop: 'url',
    placeholder: '请输入电话'
  },
]);

const handleAdd = () => {
  open(0); // 调用open函数,将id参数设为0,表示新增功能
}

const handleEdit = () => {
  const id = 1; // 假设你已经获取到了编辑的id
  console.log(id);
  
  open(id);  // 调用open函数,将id参数设为编辑的id,表示编辑功能
}

</script>
 
//封装的对话框组件
<script setup lang="ts">
import { ref, defineEmits, defineExpose , defineProps} from 'vue'

interface FormItem {
  span?: number;
  label: string;
  type: string;
  prop: string;
  options?: { label: string; value: any }[];
  width?: string;
  placeholder?: string;
  format?: string;
  radios?: { label: string; value: any }[];

}

const props = defineProps({
  // 表单信息
  formInfo: {
    type: Object,
    default: () => ({}),
    required: true
  },
  // 表单数组
  formData: {
    type: Array as () => FormItem[],
    default: () => [],
    required: true
  },
  editId: {
    type:Array as () => FormItem[],
    default: () => [],
    required: true
  }
});

const emit = defineEmits(['confirmDia'])
let showDia = ref<boolean>(false)
const openDia = (): void => {
  showDia.value = true
}  

const closeDia = (): void => {
  showDia.value = false
}

const confirmDia = (): void => {
  emit('confirmDia', '弹窗内容事件处理完毕,信息传给父组件。')
}  

defineExpose({
  openDia,
  closeDia
})

</script>

<template>
   <el-dialog 
        title="添加信息" 
        @close="closeDia" 
        v-model="showDia"
    >

  <el-form :model="formInfo">
      <el-col :span="item.span || 6" v-for="item, i in formData" :key="i">
        <el-form-item :label="item.label" :label-width="item.width || '80px'">

          <el-input v-if="item.type === 'input'" v-model="formInfo[item.prop]"
            :placeholder="item.placeholder || '请输入'" clearable />

          <el-select v-if="item.type === 'select'" v-model="formInfo[item.prop]"
            :placeholder="item.placeholder || '请选择'" clearable>
            <el-option v-for="item2 in item.options" :key="item2.value" :label="item2.label" :value="item2.value" />
          </el-select>


          <el-date-picker v-if="item.type === 'date'" type="date" :value-format="item.format || 'yyyy-MM-dd'"
            :placeholder="item.placeholder || '请选择日期'" v-model="formInfo[item.prop]"
            style="width: 100%;" clearable></el-date-picker>


            <el-radio-group v-if="item.type === 'radio'" v-model="formInfo[item.prop]"   :placeholder="item.placeholder || '请选择'" clearable>
              <el-radio v-for="item2 in item.radios" :key="item2.value" :label="item2.label" :value="item2.value" />
            </el-radio-group>

        </el-form-item>
      </el-col>
  </el-form>
           
    <template v-slot:footer>
        <el-button @click="confirmDia" type="primary">确定</el-button>
        <el-button @click="closeDia" type="primary" plain>取消</el-button>
    </template>
  </el-dialog>
</template>


//api/users.ts
import request from"@/utils/request"
type Common<T>={
    code: string
    data:T
    mesg: string
    time:string

}

export type Users={
    categoryId:number
    createdBy:string
    createdTime:string
    description:string
    id:number
    name:string
    operatorId:number|null
    selected: boolean
    updatedBy:string
    updatedTime:string
    url:string
}


    export type Resource={
        categoryId:number
        createdBy:string
        createdTime:string
        description:string
        id:number
        name:string
        operatorId:number|null
        selected: boolean
        updatedBy:string
        updatedTime:string
        url:string
    
    }


export type QueriedResult={
    current: number
    hitCount?: false
    optimizeCountSql?:boolean
    orders?:any[]
    pages?:number
    records:Users[]|[]
    searchCount?: boolean
    size:number
    total: number


    

}
export type Condition=Partial<{
    id:number
    size:number
    name:string
    startCreateTime:string
    url:string
    categoryId:string
    endCreateTime: string
    current: number

}>
//分页查询
export const userPage=  (condition:Condition) => {
    return request<Common< QueriedResult>>({
        method:'POST',
        url:'http://39.97.218.60/boss/resource/getResourcePages',
        data: condition,
    })
}

//保存或更新数据

export const saveOrUpdate=(resource:Partial<Resource>)   => {
    return request<Common<boolean>>({
        method:"GET",
        url:"http://39.97.218.60/boss/resource/saveOrUpdate",
        data:resource
    })
    
}

  

引用 皆我百晓生 小程序回复内容作答:
根据你的需求,你可以对对话框组件进行如下封装:

  1. 在对话框组件中,添加一个props属性editId,用于接收父组件传递的编辑id。
  2. 在对话框组件中,根据editId的值判断是添加功能还是编辑功能,从而决定传入的表单项。
  3. 在对话框组件中,添加一个确认按钮,点击确认按钮时触发confirmDia事件,并将表单数据传递给父组件。
  4. 在父组件中,根据点击添加按钮或编辑按钮时调用open函数,并传入对应的id。
  5. 在父组件中,定义confirmDia方法,用于处理对话框确认事件,将表单数据传递给后端接口进行保存或更新。
  6. 在父组件中,根据后端接口的返回结果进行相应的处理,如重新查询数据或显示错误信息。

下面是对话框组件的封装示例代码:

<script setup lang='ts'>
import { ref, defineEmits, defineExpose, defineProps } from 'vue'

interface FormItem {
  span?: number;
  label: string;
  type: string;
  prop: string;
  options?: { label: string; value: any }[];
  width?: string;
  placeholder?: string;
  format?: string;
  radios?: { label: string; value: any }[];
}

const props = defineProps({
  // 表单信息
  formInfo: {
    type: Object,
    default: () => ({}),
    required: true
  },
  // 表单数组
  formData: {
    type: Array as () => FormItem[],
    default: () => [],
    required: true
  },
  editId: {
    type: Number,
    default: 0,
    required: true
  }
});

const emit = defineEmits(['confirmDia'])
let showDia = ref<boolean>(false)

const openDia = (id: number = 0): void => {
  showDia.value = true
  // 根据id判断是添加功能还是编辑功能
  if (id === 0) {
    // 添加功能
    // 设置表单数据为添加时的表单项
    // ...
  } else {
    // 编辑功能
    // 设置表单数据为编辑时的表单项
    // ...
  }
}

const closeDia = (): void => {
  showDia.value = false
}

const confirmDia = (): void => {
  emit('confirmDia', formInfo.value)
}

defineExpose({
  openDia,
  closeDia
})
</script>

<template>
  <el-dialog 
    title='添加信息' 
    @close='closeDia' 
    v-model='showDia'
  >
    <el-form :model='formInfo'>
      <el-col :span='item.span || 6' v-for='item, i in formData' :key='i'>
        <el-form-item :label='item.label' :label-width='item.width || '80px''>
          <el-input v-if='item.type === 'input'' v-model='formInfo[item.prop]'
            :placeholder='item.placeholder || '请输入'' clearable />

          <el-select v-if='item.type === 'select'' v-model='formInfo[item.prop]'
            :placeholder='item.placeholder || '请选择'' clearable>
            <el-option v-for='item2 in item.options' :key='item2.value' :label='item2.label' :value='item2.value' />
          </el-select>

          <el-date-picker v-if='item.type === 'date'' type='date' :value-format='item.format || 'yyyy-MM-dd''
            :placeholder='item.placeholder || '请选择日期'' v-model='formInfo[item.prop]'
            style='width: 100%;' clearable></el-date-picker>

          <el-radio-group v-if='item.type === 'radio'' v-model='formInfo[item.prop]' :placeholder='item.placeholder || '请选择'' clearable>
            <el-radio v-for='item2 in item.radios' :key='item2.value' :label='item2.label' :value='item2.value' />
          </el-radio-group>
        </el-form-item>
      </el-col>
    </el-form>
           
    <template v-slot:footer>
      <el-button @click='confirmDia' type='primary'>确定</el-button>
      <el-button @click='closeDia' type='primary' plain>取消</el-button>
    </template>
  </el-dialog>
</template>

在父组件中,你可以根据需要传递不同的表单数据和编辑id,示例代码如下:

<template>
  <DialogForm ref='dialog' :formData='formData' :formInfo='Form || Edit' :editId='editId' @confirmDia='confirmDia' />
  <el-button @click='handleAdd' type='primary'>添加</el-button>
  <el-button @click='handleEdit' type='primary'>编辑</el-button>
</template>

<script setup lang='ts'>
import { ref } from 'vue';
import DialogForm from '@/components/dialog/DialogForm.vue';

const dialog = ref<InstanceType<typeof DialogForm> | null>(null)

const handleAdd = () => {
  dialog.value?.openDia();
}

const handleEdit = () => {
  const id = 1; // 假设你已经获取到了编辑的id
  dialog.value?.openDia(id);
}

const confirmDia = (formData: any) => {
  console.log(formData);
  dialog.value?.closeDia();
  // 调用后端接口保存或更新数据
  // ...
}

const Form = ref({
  // 添加时的表单项
  // ...
});

const Edit = ref({
  // 编辑时的表单项
  // ...
});

const formData = ref([
  // 公共的表单项
  // ...
]);

const editId = ref(0);
</script>

这样,你就可以根据不同的功能调用同一个对话框组件,并传递不同的表单数据和编辑id了。同时,点击确认按钮时,会触发confirmDia事件,将表单数据传递给父组件进行处理。

直接贴问题吧,这代码太多不好看的

【以下回答由 GPT 生成】

问题1:传入的表单项在添加和编辑时是一样的,无法根据id是否为0来判断传入哪个表单项。

解决方案: 1. 首先,在DialogForm组件中,添加一个editMode属性用于表示当前是添加还是编辑状态。 2. 在父组件中,在处理添加和编辑功能触发的方法中,通过传入不同的参数来设置editMode的值。 3. 修改DialogForm组件的模板,根据editMode的值来动态显示不同的表单项。 4. 在点击对话框确认按钮时,根据editMode的值来判断是调用添加功能的接口还是编辑功能的接口。

修改后的代码如下:

(index.vue)

<template>
  <el-card class="box-card">
    <template #header>
      <Search :searchData="searchData" :searchInfo="productionlineForm" @submitEmits="submitEmitsFn"></Search>
    </template>

    <DialogForm ref="dialog" :editMode="editMode" :formData="formData" :formInfo="Form||Edit" :editId="editId" @confirmDia="confirmDia"></DialogForm>

    <el-button @click="handleAdd" type="primary">添加</el-button>

    <el-table :data="queriedResult.records" border style="width: 100%">
      <el-table-column type="index" />
      <el-table-column prop="name" label="姓名" align="center" />
      <el-table-column prop="url" label="电话" align="center" />
      <el-table-column prop="description" label="城市ID" align="center" />
    </el-table>
  </el-card>
</template>
<script>
import DialogForm from './DialogForm.vue';

export default {
  components: {
    DialogForm
  },
  data() {
    return {
      editMode: '', // 添加还是编辑状态,可以设为 'add' 或 'edit'
      editId: '', // 编辑时传入的id
      formData: { // 表单数据
        name: '',
        url: '',
        description: '',
        password: ''
      },
      // 其他数据...
    };
  },
  methods: {
    handleAdd() {
      this.editMode = 'add';
      this.$refs.dialog.openDialog();
    },
    handleEdit(id) {
      this.editMode = 'edit';
      this.editId = id;
      this.$refs.dialog.openDialog();
    },
    confirmDia(data) {
      if (this.editMode === 'add') {
        // 添加功能,调用保存接口
        // 调用后端接口saveOrUpdate
      } else if (this.editMode === 'edit') {
        // 编辑功能,调用编辑接口
        // 调用后端接口saveOrUpdate
      }
    },
    // 其他方法...
  }
};
</script>

(DialogForm.vue)

<template>
  <el-dialog :visible.sync="dialogVisible" :before-close="handleClose">
    <el-form :model="formData" label-width="80px">
      <el-form-item label="姓名">
        <el-input v-model="formData.name"></el-input>
      </el-form-item>
      <el-form-item label="电话">
        <el-input v-model="formData.url"></el-input>
      </el-form-item>
      <template v-if="editMode === 'add'">
        <el-form-item label="初始密码">
          <el-input type="password" v-model="formData.password"></el-input>
        </el-form-item>
      </template>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogVisible = false">取 消</el-button>
      <el-button type="primary" @click="handleConfirm">确 定</el-button>
    </div>
  </el-dialog>
</template>
<script>
export default {
  props: {
    editMode: String, // 添加还是编辑状态,可以设为 'add' 或 'edit'
    editId: String, // 编辑时传入的id
    formData: { // 表单数据
      type: Object,
      default() {
        return {
          name: '',
          url: '',
          description: '',
          password: ''
        };
      }
    }
  },
  data() {
    return {
      dialogVisible: false
    };
  },
  methods: {
    openDialog() {
      this.dialogVisible = true;
    },
    handleClose(done) {
      this.$confirm('确认关闭?')
        .then(_ => {
          done();
        })
        .catch(_ => {});
    },
    handleConfirm() {
      this.$emit('confirmDia', this.formData);
      this.dialogVisible = false;
    }
  }
};
</script>

问题2:数据无法渲染到页面上。

解决方案: 1. 在父组件中,定义一个queriedResult属性用于存储从后端接口获取的数据。 2. 在父组件中,使用异步请求从后端获取数据并将数据赋值给queriedResult。 3. 将queriedResult作为属性传递给el-table组件,以渲染数据。

修改后的代码如下:

(index.vue)

<template>
  <el-card class="box-card">
    <template #header>
      <Search :searchData="searchData" :searchInfo="productionlineForm" @submitEmits="submitEmitsFn"></Search>
    </template>

    <DialogForm ref="dialog" :editMode="editMode" :formData="formData" :formInfo="Form||Edit" :editId="editId" @confirmDia="confirmDia"></DialogForm>

    <el-button @click="handleAdd" type="primary">添加</el-button>

    <el-table :data="queriedResult" border style="width: 100%">
      <el-table-column type="index" />
      <el-table-column prop="name" label="姓名" align="center" />
      <el-table-column prop="url" label="电话" align="center" />
      <el-table-column prop="description" label="城市ID" align="center" />
    </el-table>
  </el-card>
</template>
<script>
import DialogForm from './DialogForm.vue';
import axios from 'axios';

export default {
  components: {
    DialogForm
  },
  data() {
    return {
      editMode: '', // 添加还是编辑状态,可以设为 'add' 或 'edit'
      editId: '', // 编辑时传入的id
      formData: { // 表单数据
        name: '',
        url: '',
        description: '',
        password: ''
      },
      queriedResult: [] // 从后端接口获取的数据
      // 其他数据...
    };
  },
  mounted() {
    this.getDataFromBackend();
  },
  methods: {
    handleAdd() {
      this.editMode = 'add';
      this.$refs.dialog.openDialog();
    },
    handleEdit(id) {
      this.editMode = 'edit';
      this.editId = id;
      this.$refs.dialog.openDialog();
    },
    getDataFromBackend() {
      axios.get('/api/data') // 假设这是从后端接口获取数据的路径
        .then(response => {
          this.queriedResult = response.data;
        })
        .catch(error => {
          console.error(error);
        });
    },
    confirmDia(data) {
      if (this.editMode === 'add') {
        // 添加功能,调用保存接口
        // 调用后端接口saveOrUpdate
      } else if (this.editMode === 'edit') {
        // 编辑功能,调用编辑接口
        // 调用后端接口saveOrUpdate
      }
    },
    // 其他方法...
  }
};
</script>

通过以上修改,你应该可以在Vue3中封装一个对话框组件,使得添加和编辑功能可以通过同一个组件调用,同时可以根据功能不同传入不同的表单项数据,并且数据可以渲染到页面上了。如还有问题,请及时追问。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

<script setup lang='ts'>
import { ref, defineEmits, defineExpose, defineProps } from 'vue'
interface FormItem {
  span?: number;
  label: string;
  type: string;
  prop: string;
  options?: { label: string; value: any }[];
  width?: string;
  placeholder?: string;
  format?: string;
  radios?: { label: string; value: any }[];
}
const props = defineProps({
  // 表单信息
  formInfo: {
    type: Object,
    default: () => ({}),
    required: true
  },
  // 表单数组
  formData: {
    type: Array as () => FormItem[],
    default: () => [],
    required: true
  },
  editId: {
    type: Number,
    default: 0,
    required: true
  }
});
const emit = defineEmits(['confirmDia'])
let showDia = ref<boolean>(false)
const openDia = (id: number = 0): void => {
  showDia.value = true
  // 根据id判断是添加功能还是编辑功能
  if (id === 0) {
    // 添加功能
    // 设置表单数据为添加时的表单项
    // ...
  } else {
    // 编辑功能
    // 设置表单数据为编辑时的表单项
    // ...
  }
}
const closeDia = (): void => {
  showDia.value = false
}
const confirmDia = (): void => {
  emit('confirmDia', formInfo.value)
}
defineExpose({
  openDia,
  closeDia
})
</script>
<template>
  <el-dialog 
    title='添加信息' 
    @close='closeDia' 
    v-model='showDia'
  >
    <el-form :model='formInfo'>
      <el-col :span='item.span || 6' v-for='item, i in formData' :key='i'>
        <el-form-item :label='item.label' :label-width='item.width || '80px''>
          <el-input v-if='item.type === 'input'' v-model='formInfo[item.prop]'
            :placeholder='item.placeholder || '请输入'' clearable />
          <el-select v-if='item.type === 'select'' v-model='formInfo[item.prop]'
            :placeholder='item.placeholder || '请选择'' clearable>
            <el-option v-for='item2 in item.options' :key='item2.value' :label='item2.label' :value='item2.value' />
          </el-select>
          <el-date-picker v-if='item.type === 'date'' type='date' :value-format='item.format || 'yyyy-MM-dd''
            :placeholder='item.placeholder || '请选择日期'' v-model='formInfo[item.prop]'
            style='width: 100%;' clearable></el-date-picker>
          <el-radio-group v-if='item.type === 'radio'' v-model='formInfo[item.prop]' :placeholder='item.placeholder || '请选择'' clearable>
            <el-radio v-for='item2 in item.radios' :key='item2.value' :label='item2.label' :value='item2.value' />
          </el-radio-group>
        </el-form-item>
      </el-col>
    </el-form>
    <template v-slot:footer>
      <el-button @click='confirmDia' type='primary'>确定</el-button>
      <el-button @click='closeDia' type='primary' plain>取消</el-button>
    </template>
  </el-dialog>
</template>


援引通义千问:
这是一个比较复杂的问题,需要进行多方面的改进。以下是一些可能的解决方案:

  1. 根据id是否为0判断传入哪个表单项:可以在调用对话框组件时,将id作为参数传入,然后在对话框组件中根据id来判断传入哪个表单项。例如,可以在对话框组件中定义一个函数,用于根据id来获取对应的表单项,然后在调用对话框组件时将id作为参数传入,对话框组件根据id来调用相应的函数获取表单项。
  2. 数据渲染不到页面上:可能是由于后端接口返回的数据格式不正确,或者是前端没有正确处理返回的数据。可以检查一下后端接口的返回数据格式是否正确,是否包含了所有需要的字段。同时,也可以检查一下前端是否正确处理了返回的数据,例如是否正确渲染到了页面上。

希望以上建议可以帮助您解决问题。如果您还有其他问题,请随时联系我。

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:

  1. DialogForm组件中,将editId的类型从Array as () => FormItem[]更改为ref<Array as () => FormItem[]>,以便在open函数中使用editId.value而不是editId

  2. addedit函数中,根据id是否为0来判断是新增还是编辑操作,然后调用DialogForm组件的open函数并传入相应的参数。

  3. DialogForm组件的open函数中,根据传入的参数设置formData的值,然后调用后端接口saveOrUpdate保存数据。

  4. handleAddhandleEdit函数中,分别设置editId的值为[{ label: '姓名', type: 'input', prop: 'name', placeholder: '请输入姓名' }, { label: '地址', type: 'input', prop: 'url', placeholder: '请输入电话' }][{ label: '姓名', type: 'input', prop: 'name', placeholder: '请输入姓名' }, { label: '电话', type: 'input', prop: 'url', placeholder: '请输入电话' }]

修改后的代码如下:

// 封装的对话框组件
import { ref, defineEmits, defineExpose , defineProps} from 'vue'
interface FormItem {
  span?: number;
  label: string;
  type: string;
  prop: string;
  options?: { label: string; value: any }[];
  width?: string;
  placeholder?: string;
  format?: string;
  radios?: { label: string; value: any }[];
}
const props = defineProps({
  // 表单信息
  formInfo: {
    type: Object,
    default: () => ({}),
    required: true
  },
  // 表单数组
  formData: {
    type: Array as () => FormItem[],
    default: () => [],
    required: true
  },
  editId: {
    type: ref<Array as () => FormItem[]>,
    default: () => [],
    required: true
  }
});
const emit = defineEmits(['confirmDia'])
let showDia = ref<boolean>(false)
const openDia = (): void => {
  showDia.value = true
}
const closeDia = (): void => {
  showDia.value = false
}
const confirmDia = (): void => {
  emit('confirmDia', '弹窗内容事件处理完毕,信息传给父组件。')
}
defineExpose({
  openDia,
  closeDia
})

addedit函数中设置editId的值:

// api/users.ts
import request from"@/utils/request"
type Common<T>={
    code: string
    data:T
}
// ...
export const handleAdd = () => {
  open(0); // 调用open函数,将id参数设为0,表示新增功能
}
export const handleEdit = (id: number) => {
  const ids = [{ label: '姓名', type: 'input', prop: 'name', placeholder: '请输入姓名' }, { label: '地址', type: 'input', prop: 'url', placeholder: '请输入电话' }];
  open(id);  // 调用open函数,将id参数设为编辑的id,表示编辑功能
}

如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

  1. 传入的表单项不一样
    在 DialogForm 组件中接受 formData 和 editId 作为 props,同时在 DialogForm 组件内部根据 editId 的值来决定显示哪些表单项。

<template>
  <el-form :model="formInfo">
    <!-- 公共表单项 -->
    <el-input v-model="formInfo.name" :placeholder="item.placeholder || '请输入'" clearable />
    <el-input v-model="formInfo.url" :placeholder="item.placeholder || '请输入'" clearable />

    <!-- 添加特定的表单项 -->
    <el-input v-if="editId === 0" v-model="formInfo.password" :placeholder="item.placeholder || '请输入密码'" clearable />

    <!-- 编辑特定的表单项 -->
    <el-input v-else-if="editId !== 0" v-model="formInfo.anotherField" :placeholder="item.placeholder || '请输入其他字段'" clearable />

    <!-- 其他表单项 -->
  </el-form>
</template>

<script setup>
import { ref } from 'vue'

const props = defineProps({
  formData: Array,
  editId: Number
})

const formInfo = ref({
  name: '',
  url: '',
  password: '', // 添加时的特定字段
  anotherField: '' // 编辑时的特定字段
})
</script>

  1. 数据渲染问题
    在 DialogForm 组件中绑定表单的 v-model 到 formInfo 对象上。
    ```vue
在父组件中,您需要监听 confirmDia 事件,然后在事件处理程序中调用 saveOrUpdate 向后端发送请求,并在成功后刷新数据:

```vue

<script setup>
import { ref } from 'vue'
import { saveOrUpdate } from '@/api/users'

const confirmDia = async (data) => {
  // 向后端发送请求保存或更新数据
  const { data: response } = await saveOrUpdate(data)
  
  if (response.code === '000000') {
    // 数据保存成功后刷新数据列表
    queryMethod({ current: 1 })
  } else {
    ElMessage.error('保存失败')
  }
}
</script>


添加和编辑按钮应该绑定两个不同的回调函数,这两个函数像后端发请求的时候,如果是编辑按钮的回调函数调用后端请求接口,将初始密码设置为空,待请求成功之后再将之前的输入的数据渲染出来