自研国产零依赖前端UI框架实战011 用户管理系统完成

51 阅读4分钟

前言

通过前面的学习, 我们已经有了一个比较完善的用户管理系统了.

不过我们还可以继续优化.

封装表单相关的操作

我们可以把表单相关的操作封装到一个组合式API里面去.

// 用户增删改查操作的表单操作
const useCrudForm = (data, formData, title = "用户") => {
    // 是否显示对话框
    const isShowModal = ref(false);
    // 对话框标题
    const modalTitle = ref(`编辑${title}`);
    // 是否为编辑
    const isEdit = ref(false);
    // 编辑的ID
    const editId = ref(0);
    // 编辑的索引
    const editIndex = ref(0);

    // 点击编辑, 显示编辑对话框
    const onShowEditModal = (index, item) => {
        isEdit.value = true;
        isShowModal.value = true;
        editId.value = item.id
        editIndex.value = index
        formData.name = item.name
        formData.age = item.age
        modalTitle.value = `编辑${title}`
    }
    // 清空表单
    const clearFormData = () => Object.assign(formData, {})
    // 隐藏对话框
    const onHideModal = () => isShowModal.value = false
    // 显示对话框
    const onShowAddModal = () => {
        clearFormData()
        modalTitle.value = `新增${title}`
        isShowModal.value = true;
    };
    // 点击对话框中的保存按钮
    const onSave = () => {
        isShowModal.value = false;

        if (isEdit.value) {
            data.value[editIndex.value] = {
                id: editId.value,
                ...formData,
            };
        } else {
            let newUser = {
                id: random.id1(),
                ...formData,
            }
            array.insertFirst(data.value, newUser)
        }

        isEdit.value = false;
        clearFormData()
    };


    return {
        isShowModal,
        modalTitle,
        isEdit,
        editIndex,
        editId,
        clearFormData,
        onShowEditModal,
        onShowAddModal,
        onHideModal,
        onSave,
    }
}

此时去测试表单, 可以发现, 一切依旧还是正常的.

在这里插入图片描述

在这里插入图片描述

此时完整的App.vue代码如下.

<script setup>
import zdp_table1 from "./zdpui/components/zdp_table1.vue";
import zdp_page1 from "./zdpui/components/zdp_page1.vue";
import random from "./zdpui/js/random.js";
import {onMounted, reactive, ref} from "vue";
import zdp_confirm1 from "./zdpui/components/zdp_confirm1.vue";
import zdp_modal1 from "./zdpui/components/zdp_modal1.vue";
import Zdp_input1 from "./zdpui/components/zdp_input1.vue";
import Zdp_button1 from "./zdpui/components/zdp_button1.vue";
import array from "./zdpui/js/array.js";
import crud from "./zdpui/js/crud.js";

const {
  page,
  size,
  total,
  data,
  loading,
  onChange,
  loadData,
} = crud.useCrudPage(random.apiGetPageUser)
const {
  columns,
  isShowDeleteDialog,
  onDelete,
  onShowDeleteDialog,
  onHideDeleteDialog,
} = crud.useCrudTable(data)

const formData = reactive({
  name: "张三",
  age: 23,
});

const {
  isShowModal,
  modalTitle,
  onShowEditModal,
  onShowAddModal,
  onHideModal,
  onSave,
} = crud.useCrudForm(data, formData)

onMounted(async ()=>{
  await loadData()
  console.log("data...", data.value)
})
</script>
<template>
  <div>
    <zdp_button1
        @click="onShowAddModal"
        text="新增"
    />
    <zdp_table1
        :columns="columns"
        :data="data"
        :loading="loading"
        @edit="onShowEditModal"
        @delete="onShowDeleteDialog"
    />
    <zdp_page1
        :page="page"
        :size="size"
        :total="total"
        @change="onChange"
    />
    <zdp_confirm1
        :show="isShowDeleteDialog"
        @confirm="onDelete"
        @close="onHideDeleteDialog"
    />
    <zdp_modal1
        :show="isShowModal"
        :title="modalTitle"
        @confirm="onSave"
        @close="onHideModal"
    >
      <zdp_input1
          label="姓名"
          v-model="formData.name"
          placeholder="请输入姓名"
      />
      <zdp_input1
          label="年龄"
          type="number"
          v-model="formData.age"
          placeholder="请输入年龄"
      />
    </zdp_modal1>
  </div>
</template>

封装crud组件

紧接着, 我们来封装crud的组件.

<script setup>
import zdp_table1 from "./zdp_table1.vue";
import zdp_page1 from "./zdp_page1.vue";
import random from "../js/random.js";
import {onMounted, reactive, ref} from "vue";
import zdp_confirm1 from "./zdp_confirm1.vue";
import zdp_modal1 from "./zdp_modal1.vue";
import Zdp_input1 from "./zdp_input1.vue";
import Zdp_button1 from "./zdp_button1.vue";
import crud from "../js/crud.js";
const props = defineProps({
  // 标题
  title: {
    typeString,
    requiredtrue,
  },
  // 表单数据
  formData: {
    typeObject,
    requiredtrue,
  },
  // 分页查询数据的接口
  apiGetPage: {
    typeFunction,
    requiredtrue,
  },
  // 新增数据的接口
  apiAdd: {
    typeFunction,
    requiredfalse,
  },
  // 删除数据的接口
  apiUpdate: {
    typeFunction,
    requiredfalse,
  },
})
const {
  page,
  size,
  total,
  data,
  loading,
  onChange,
  loadData,
} = crud.useCrudPage(props.apiGetPage)
const {
  columns,
  isShowDeleteDialog,
  onDelete,
  onShowDeleteDialog,
  onHideDeleteDialog,
} = crud.useCrudTable(data)

const {
  isShowModal,
  modalTitle,
  onShowEditModal,
  onShowAddModal,
  onHideModal,
  onSave,
} = crud.useCrudForm(data, props.formData, props.title)

onMounted(async ()=>{
  await loadData()
})
</script>
<template>
  <div>
    <zdp_button1
        @click="onShowAddModal"
        text="新增"
    />
    <zdp_table1
        :columns="columns"
        :data="data"
        :loading="loading"
        @edit="onShowEditModal"
        @delete="onShowDeleteDialog"
    />
    <zdp_page1
        :page="page"
        :size="size"
        :total="total"
        @change="onChange"
    />
    <zdp_confirm1
        :show="isShowDeleteDialog"
        @confirm="onDelete"
        @close="onHideDeleteDialog"
    />
    <zdp_modal1
        :show="isShowModal"
        :title="modalTitle"
        @confirm="onSave"
        @close="onHideModal"
    >
      <slot></slot>
    </zdp_modal1>
  </div>
</template>

此时App.vue就可以简化为:

<script setup>
import {onMounted, reactive, ref} from "vue";

import random from "./zdpui/js/random.js";
import Zdp_input1 from "./zdpui/components/zdp_input1.vue";
import zdp_crud1 from "./zdpui/components/zdp_crud1.vue";

const formData = reactive({
  name: "张三",
  age: 23,
});
const apiGetPage = random.apiGetPageUser
</script>
<template>
  <div>
    <zdp_crud1
        title="用户"
        :form-data="formData"
        :api-get-page="apiGetPage"
        :api-add="null"
        :api-update="null"
    >
      <zdp_input1
          label="姓名"
          v-model="formData.name"
          placeholder="请输入姓名"
      />
      <zdp_input1
          label="年龄"
          type="number"
          v-model="formData.age"
          placeholder="请输入年龄"
      />
    </zdp_crud1>
  </div>
</template>

再次测试, 可以发现页面效果依然是一样的.

下一步做什么

目前用户管理系统增删改查的功能我们就基本做完了, 有了crud组件以后, 我们做普通的数据管理也变得足够的简单.

那么下一步要做什么呢?

做图表相关的功能吗?

整合fastapi3进行开发吗?

在继续开发之前, 我们先来配置vite的路径别名, 这样我们后面开发ui组件会更方便.

配置vite路径别名

修改vite.config.js

import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import {resolve} from 'path';

export default defineConfig({
    plugins: [
        vue(),
    ],
    resolve: {
        alias: {
            "@"resolve(__dirname, 'src'),
        }
    }
})

这样就可以使用@作为根路径的别名了.

此时修改App.vue

<script setup>
import {onMounted, reactive, ref} from "vue";

import random from "@/zdpui/js/random.js";
import Zdp_input1 from "@/zdpui/components/zdp_input1.vue";
import zdp_crud1 from "@/zdpui/components/zdp_crud1.vue";

const formData = reactive({
  name: "张三",
  age: 23,
});
const apiGetPage = random.apiGetPageUser
const apiAdd = null
const apiUpdate = null
</script>
<template>
  <div>
    <zdp_crud1
        title="用户"
        :form-data="formData"
        :api-get-page="apiGetPage"
        :api-add="apiAdd"
        :api-update="apiUpdate"
    >
      <zdp_input1
          label="姓名"
          v-model="formData.name"
          placeholder="请输入姓名"
      />
      <zdp_input1
          label="年龄"
          type="number"
          v-model="formData.age"
          placeholder="请输入年龄"
      />
    </zdp_crud1>
  </div>
</template>

将案例封装为demo

为了便于后面的学习和演示, 可以方便的复制粘贴, 我们把这个案例封装为一个demo组件.

<script setup>
import {onMounted, reactive, ref} from "vue";

import random from "@/zdpui/js/random.js";
import ZdpInput1 from "@/zdpui/components/ZdpInput1.vue";
import ZdpCrud1 from "@/zdpui/components/ZdpCrud1.vue";

const formData = reactive({
  name: "张三",
  age: 23,
});
const apiGetPage = random.apiGetPageUser
const apiAdd = null
const apiUpdate = null
</script>
<template>
  <div>
    <ZdpCrud1
        title="用户"
        :form-data="formData"
        :api-get-page="apiGetPage"
        :api-add="apiAdd"
        :api-update="apiUpdate"
    >
      <ZdpInput1
          label="姓名"
          v-model="formData.name"
          placeholder="请输入姓名"
      />
      <ZdpInput1
          label="年龄"
          type="number"
          v-model="formData.age"
          placeholder="请输入年龄"
      />
    </ZdpCrud1>
  </div>
</template>

此时, 在App.vue中只需要一行代码就可以调用了.

<script setup>
import CrudUserPage from "@/zdpui/demo/crud/CrudUserPage.vue";
</script>
<template>
  <CrudUserPage/>
</template>

总结

到目前为止, 我们的用户管理系统案例就算真正的完成了.

我们最终封装的一个crud组件非常的好用, 能够极大的降低这种增删改查类型的管理系统相关的代码.

到目前为止, 一切都还比较符合我的预期, 我希望这个项目能够继续开发, 能够给大家提供更多简单的案例, 降低前后端的开成本.