对话框

72 阅读1分钟

父组件

<template>
  <div class="table-box">
    <MenuForm ref="menuForm"/>
    <el-button type="primary" @click="menuForm.open('create', '新增菜单')">新增菜单 </el-button>
  </div>
</template>
<script setup lang="ts" name="SystemMenu">
import { ref } from "vue"
const menuForm = ref()
</script>

子组件

<template>
  <el-dialog v-model="dialogVisible" :title="dialogTitle" v-bind="options.dialog">
    <component :is="'el-form'" v-bind="options.formConfig" ref="proFormRef" :model="model">
      <template v-for="item in options.columns" :key="item.prop">
        <component is="el-form-item" v-bind="item.formItem">
          <!-- 单选框组 -->
          <component v-if="item.attrs?.typeName == 'radio-group'" is="el-radio-group" v-model="model[item.formItem.prop]">
            <template v-for="radioItem in item.attrs.data" :key="radioItem.value">
              <component is="el-radio" :label="radioItem.label" :value="radioItem.value"></component>
            </template>
          </component>
          <!-- 其他 -->
          <component v-else :is="(item.attrs?.typeName)?`el-${item.attrs.typeName}`:'el-input'"  v-bind="item.attrs" v-model="model[item.formItem.prop]"></component>
        </component>
      </template>

      <el-form-item>
        <slot name="operation"> 
          <el-button type="button">提交</el-button>
          <el-button type="button">取消</el-button>
        </slot>
      </el-form-item>
    </component> 
  </el-dialog>
</template>

<script setup lang="ts" name="MenuForm">
import { ref } from "vue"
import { CloseBold } from "@element-plus/icons-vue"
import { useAuthStore } from "@/stores/modules/auth";
let model = ref<any>({})
const dialogTitle = ref("未设置标题") // 弹窗的标题
const formType = ref("") // 表单的类型 控制发送新增还是修改请求
const dialogVisible = ref(false) // 弹窗的是否展示
const authStore = useAuthStore()

const options:any = ref({
  // 表单整体配置项
  formConfig: {
    inline: false,
    labelPosition: "right",
    labelWidth: "80px",
    size: "default",
    disabled: false,
    labelSuffix: " :"
  },
  // 表单列配置项 (formItem 代表 item 配置项,attrs 代表 输入、选择框 配置项)
  columns: [
    {
      formItem: {
        label: "上级菜单",
        prop: "parentId"
      },
      attrs: {
        typeName: "tree-select",
        data: authStore.authMenuList,
        props: { children: "children", label: "name" },
        nodeKey: "id",
      }
    },
    { formItem: { label: "权限标识", prop: "permission"} },
    { formItem: { label: "菜单类型", prop: "name"}, 
      attrs:{
        typeName:"radio-group",
        data:[{label:"目录",value:1},{label:"菜单",value:2},{label:"按钮",value:3}]
      }
    },
  ],
  // 对话框整体配置项
  dialog: {
    draggable: true, // 为 Dialog 启用可拖拽功能
    alignCenter: true, // 是否水平垂直对齐对话框
    closeIcon: CloseBold
  }
})

/**
 * 打开弹窗
 * @param type 类型
 * @param title 标题
 */
const open = async (type: string, title: string) => {
  dialogVisible.value = true
  dialogTitle.value = title
  formType.value = type
}
//提供open方法用于打开弹窗
defineExpose({ open })
</script>

<style scoped></style>