一个使用vite+vue3+antd+ts搭建的管理系统

504 阅读3分钟

ice-cli

git地址:github.com/lbiceman/ic…

介绍

脚手架使用vite + vue3 + antd + ts + pinia等。

使用ts封装了form,table,drawer,editor,header,menu,layout,404等组件。

对proxy进行了封装,开发时候可以通过json对代理地址进行配置。

对路由模块,状态模块做了基本的封装,开发时候可以参考示例。

配置了基本的dev,test,prod环境变量,可以修改对应的文件之后进行使用。

脚手架引入了eslint,prettier,husky用于解决代码格式问题。

为了解决项目打包之后体积过大问题,在使用antd组件的时候需要手动进行引入(参考项目componentRegister文件夹)。

基本样式:

image.png

工具

你可以这样使用pinia:

import { defineStore } from "pinia";
import { getStorage, setStorage } from "@/utils/index";

export interface User {
	id?: string;
	name?: string;
	level?: number;
	sex?: number;
	userId?: string;
	address?: string;
	phone?: string;
	token?: string;
	isLogin?: boolean;
	avator?: string;
}

export interface UserStoreState {
	user: User | null;
}

export interface UserSotreActions {
	setUser: (user: User | null) => void;
}

export interface UserStoreGetters<T = UserStoreState> {
	getUser: (state: T) => User;
	isLogin: (state: T) => boolean | undefined;
	[key: string]: any;
}

export const useUserStore = defineStore<string, UserStoreState, UserStoreGetters, UserSotreActions>("user", {
	state: () => ({
		user: {}
	}),
	getters: {
		getUser: (state: UserStoreState) => {
			return state.user ? getStorage("userData") : state.user;
		},
		isLogin: (state: UserStoreState) => state.user?.isLogin
	},
	actions: {
		setUser(this: UserStoreState, data: User | null) {
			if (data) data.isLogin = true;
			setStorage("userData", data);
			this.user = data;
		}
	}
});

你可以这样使用axios:

// data是ref类型
const { data, run } = useAxios({
    method: "get",
    url: "/myWeb/ice-cli/getUser",
    data: {},
    module: "login"
});
run();
watchEffect(() => {
    console.log(data);
});

组件

之前在不同公司做开发的时候总是会重复的封装组件,所以在写这个项目的时候我想了一下能不能通过json直接生成form,table之类的组件。于是就有了现在这种使用方式~~~

例如我们现在想要创建一个form表单收集用户数据,可以这样做:

1.引入form组件 import IceForm from "@/components/iceForm/index.vue";

2.通过json配置组件,支持antd所有的表单组件,兼容antd的所有配置。

   const formConfig = computed((): IceFormProps => ({
   	model: ref({
                   name: "lbiceman",
                   fav: 4
               }),
   	list: [
                   {
                       item: {
                               component: "a-input",
                               allowClear: true,
                               placeholder: "请填写姓名"
                       },
                       formItem: {
                               label: "姓名",
                               required: true,
                               name: "name"
                       }
                   },
                   {
                       item: {
                               component: "a-select",
                               allowClear: true,
                               placeholder: "请选择爱好",
                               options: [
                                       { value: 0, label: "唱" },
                                       { value: 1, label: "跳" },
                                       { value: 2, label: "RAP" },
                                       { value: 3, label: "篮球" },
                                       { value: 4, label: "偶像练习生" }
                               ]
                       },
                       formItem: {
                               label: "爱好",
                               required: true,
                               name: "fav"
                       }
                   }
           ],
           onFinish: () => {
               iceFormRef.value
                   .validate()
                   .then((state: any) => {
                       console.log("validate success", state);
                   })
                   .catch((error: any) => {
                       console.log("validate err", error);
                   });
           },
           onReset: () => {
                   console.log("reset");
           }
   }));

3.在template中加入form组件<IceForm ref="iceFormRef" :config="formConfig" />

渲染之后的样式:

image.png

例如我们现在想要一个表格,我们可以使用table组件:

1.引入table组件import IceTable from "@/components/iceTable/index.vue";

2.通过json配置组件

    const tableConfig = computed(
	(): TableProps => ({
            bordered: true,
            columns: [
                {
                    title: "个人信息",
                    children: [
                        {
                            title: "姓名",
                            dataIndex: "name",
                            render: ({ text }) => text
                        },
                        {
                            title: "角色",
                            dataIndex: "roleName",
                            render: ({ text }) => text
                        },
                        {
                            title: "年龄",
                            sorter: true,
                            dataIndex: "age",
                            render: {
                                component: "a-tag",
                                props: ({ text }) => {
                                    return {
                                        color: parseInt(text) >= 20 ? "#87d068" : parseInt(text) >= 15 ? "#2db7f5" : "#E8D82C"
                                    };
                                },
                                text: ({ text }) => text
                            }
                        },
                        {
                            title: "爱好",
                            dataIndex: "fav",
                            render: ({ text }) => text
                        },
                        {
                            title: "分数",
                            dataIndex: "score",
                            render: {
                                component: "a-progress",
                                props: ({ text }) => {
                                    return {
                                        format: () => text,
                                        strokeColor: {
                                            "0%": "#87d068",
                                            "100%": "#66bbff"
                                        },
                                        percent: parseFloat(text)
                                    }
                                }
                            }
                        }
                    ]
                },
                {
                    title: "创建时间",
                    dataIndex: "createTime",
                    render: ({ text }) => text
                },
                {
                    title: "备注",
                    dataIndex: "remark",
                    render: ({ text }) => text
                },
                {
                    title: "操作",
                    render: [
                        {
                            component: "a-button",
                            props: ({ record }) => ({
                                type: "link",
                                onClick: () => {
                                    message.info("update");
                                    console.log("update", record);
                                }
                            }),
                            icon: "iconfont ice-icon-edit",
                            text: () => " 修改"
                        },
                        {
                            component: "a-button",
                            props: () => ({
                                type: "link",
                                danger: true,
                                onClick: () => {
                                    Modal.confirm({
                                        title: "提示",
                                        content: "确认要删除吗?",
                                        onOk() {
                                                message.success("删除成功");
                                        },
                                        onCancel() {}
                                    });
                                }
                            }),
                            icon: "iconfont ice-icon-delete",
                            text: () => "删除"
                        }
                    ]
                }
            ],
            onChange: (
                pagination: TablePaginationConfig,
                filters: Record<string, FilterValue | null>,
                sorter: SorterResult | SorterResult[],
                extra: TableCurrentDataSource
            ) => {
                console.log(pagination, filters, sorter, extra);
            },
            // 加载中的loading
            loading: loading.value,
            // 数据
            dataSource: tableList.value,
            pagination: {
                total: 10
            }
	})
    );

3.在template中加入table组件<IceTable :config="tableConfig" />

渲染之后的样式:

image.png

注:

所有封装的组件都可以通过这种方式进行配置。

这里只介绍基本的功能,组件。如果想要了解更多可以克隆这个项目github.com/lbiceman/ic… 里边有详细的注释。

有不清楚的地方可以通过邮箱联系我。

结语

目前这个脚手架还在开发阶段,部分组件可能不够完善,部分工具使用起来可能不够顺手。如果大家有更好的建议可以直接提交到git或者我的邮箱(lbiceman@126.com)。

如果大家有需要,我会更加详细的讲一下这个项目。

各位吴彦祖,胡歌,彭于晏,李一桐,李沁们,能不能给我点一个star(求求了~~~)。

只要你帮我点了小星星,我们就是永远的PY(朋友)。