Geeker Admin框架使用初体验--菜单模块编码

前言

事先说明我只是个正常的前端开发者,没有使用过太多的后台框架, 最近公司要开发一个后台,让前端自己主选后台模板,查看了两时半之后,我选择了这一款Geeker-Admin | 一款简单易用的中后台模版 (spicyboy.cn)

选择它的原因主要是以下几点:

技术栈

技术栈符合我的技术范围,使用的也是比较流行的技术,vite+vue3+ts那一套

功能完整

前端需要的功能大多都完善了,作者大大封装了element的表格系统,代码初看了一遍还是非常方便的,它将搜索栏和操作栏,数据栏都转换为了配置项。

其次我非常喜欢的样式皮肤设置,在这里可以选择各种界面样式,当然暗黑模式也是在这里设置,适应各种管理者的操作习惯。

文档详细

还有一个比较重要的一点是文档详细,作者大大将他的组件都写了详细的文档,清晰易懂,还有各种小细节就不一一介绍了。

使用开发

拉取代码后观看一圈后,我开始尝试着编码菜单模块。

编码前,作者源代码是这样的

没有写弹框以及添加子菜单的操作,然后我就编码了这一个功能。

作为一个大三半年的新手程序员,看完代码之后还是学习到一些写法。

在index.vue同级下创建components/MenuDialog.vue,使用defineExpose将方法暴露给父组件,接收父组件操作名称,字段数据(编辑内容初始化),点击确认调用的api,以及更新表格数据。

html 复制代码
<template>
  <div>
    <el-dialog v-model="dialogShow" :title="FData?.title + '菜单'" width="500">
      <el-form ref="ruleFormRef" label-width="100px" label-suffix=" :" :rules="rules" :model="FData?.row">
        <el-form-item label="路由地址" prop="path">
          <el-input v-model="FData.row!.path" placeholder="请填写路由地址" clearable></el-input>
        </el-form-item>
        <el-form-item label="路由名称" prop="name">
          <el-input v-model="FData.row!.name" placeholder="请填写路由名称" clearable></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogShow = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit()"> 确定 </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts" name="MenuDialog">
import { reactive, ref } from "vue";
import { ElDialog, ElMessage, FormInstance } from "element-plus";
const dialogShow = ref(false);
const FData = ref<FProps>({
  title: "",
  row: {}
});
const rules = reactive({
  path: [{ required: true, message: "请填写路由地址" }],
  name: [{ required: true, message: "请填写路由名称" }]
});

// 提交数据(新增/编辑)
const ruleFormRef = ref<FormInstance>();
const handleSubmit = () => {
  ruleFormRef.value!.validate(async valid => {
    if (!valid) return;
    try {
      await FData.value?.api!(FData.value?.row);
      ElMessage.success({ message: `${FData.value?.title}菜单成功!` });
      FData.value?.getTableList!();
      dialogShow.value = false;
    } catch (error) {
      console.log(error);
    }
  });
};
interface FProps {
  title: string;
  row: Partial<Menu.MenuOptions>;
  api?: (params: any) => Promise<any>;
  getTableList?: () => void;
}
// 接收父组件传过来的参数
const acceptParams = (params: FProps) => {
  FData.value = params;
  dialogShow.value = true;
};

defineExpose({
  acceptParams
});
</script>

<style lang="scss" scoped></style>

由于是假数据,编辑器会报错,换成Promise请求就不会了,代码如下,使用ProTable组件,配置请求api,columns如果api的返回不符合处理规范,使用data-callback可以进行处理。

最后我有样学样的把操作都写在一个方法内,将数据处理后调用子组件方法,值得注意的是我尝试编码是没有写处理api的,把传给子组件的api改成调用的就行。

html 复制代码
<template>
  <div class="table-box">
    <ProTable
      ref="proTable"
      title="菜单列表"
      row-key="path"
      :indent="20"
      :columns="columns"
      :request-api="getAuthMenuListApi"
      :data-callback="dataCallback"
    >
      <!-- 表格 header 按钮 -->
      <template #tableHeader>
        <el-button type="primary" :icon="CirclePlus" @click="menuOperate('新增')">新增菜单 </el-button>
      </template>
      <!-- 菜单图标 -->
      <template #icon="scope">
        <el-icon :size="18">
          <component :is="scope.row.meta.icon"></component>
        </el-icon>
      </template>
      <!-- 菜单操作 -->
      <template #operation="scope">
        <el-button type="primary" link :icon="CirclePlus" @click="menuOperate('新增子', scope.row)"> 新增子菜单 </el-button>
        <el-button type="warning" link :icon="EditPen" @click="menuOperate('编辑', scope.row)"> 编辑 </el-button>
        <el-button type="danger" link :icon="Delete" @click="menuOperate('删除', scope.row)"> 删除 </el-button>
      </template>
    </ProTable>
    <MenuDialog ref="menuDialogRef"></MenuDialog>
  </div>
</template>

<script setup lang="ts" name="menuMange">
import { ref } from "vue";
import { ColumnProps } from "@/components/ProTable/interface";
import { Delete, EditPen, CirclePlus } from "@element-plus/icons-vue";
import ProTable from "@/components/ProTable/index.vue";
import MenuDialog from "./components/MenuDialog.vue";
import { getAuthMenuListApi } from "@/api/modules/login";
import { ElMessage, ElMessageBox } from "element-plus";

const proTable = ref();
const menuDialogRef = ref<InstanceType<typeof MenuDialog> | null>(null);
const dataCallback = (data: any) => {
  return {
    list: data,
    total: data.total,
    pageNum: data.pageNum,
    pageSize: data.pageSize
  };
};
// 表格配置项
const columns: ColumnProps[] = [
  { prop: "meta.title", label: "菜单名称", align: "left", search: { el: "input" } },
  { prop: "meta.icon", label: "菜单图标" },
  { prop: "name", label: "菜单 name", search: { el: "input" } },
  { prop: "path", label: "菜单路径", width: 300, search: { el: "input" } },
  { prop: "component", label: "组件路径", width: 300 },
  { prop: "operation", label: "操作", width: 300, fixed: "right" }
];
const menuOperate = (title: string, row: Partial<Menu.MenuOptions> = {}) => {
  if (title == "删除") {
    ElMessageBox.confirm(`确认删除菜单 ${row.meta?.title} 及其子菜单`, `删除菜单 ${row.meta?.title} 及其子菜单`, {
      type: "error"
    }).then(() => {
      ElMessage.success("删除成功");
    });
    return;
  }
  const params = {
    title: title == "编辑" ? "编辑" + row.meta?.title : title == "新增子" ? "新增" + row.meta?.title + "子" : title,
    row: title == "新增子" ? {} : { ...row },
    api: () => {
      console.log("操作成功");
    },
    getTableList: proTable.value?.getTableList
  };
  menuDialogRef.value?.acceptParams(params);
};
</script>

最终效果如下

总结

写起来还是非常方便的,刚刚开始可能看不太懂,写了一遍之后就好多了 , 项目中使用ts的范围非常广 , 我之前接触的项目,有一半都懒得给直接any,但是初看下来框架中都给了类型,请求的返回值也给了,有些类型我看不懂,还在学习中。

相关推荐
也无晴也无风雨37 分钟前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang1 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄4 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
阮少年、4 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
郝晨妤5 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙
AvatarGiser6 小时前
《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明
前端·vue.js·elementui
喝旺仔la6 小时前
vue的样式知识点
前端·javascript·vue.js
别忘了微笑_cuicui6 小时前
elementUI中2个日期组件实现开始时间、结束时间(禁用日期面板、控制开始时间不能超过结束时间的时分秒)实现方案
前端·javascript·elementui