Code前端首页关于Code前端联系我们

Vue3结合Ant Design Vue做后台管理系统踩坑?这些实用技巧帮你快速通关

terry 2小时前 阅读数 30 #Vue

为什么现在越来越多的人用Vue3搭AntDv后台?

首先得给刚入门的人或者纠结技术栈的团队吃个定心丸,说清楚这个组合为什么火,Vue3的组合式API是最大的加分项,以前Vue2写后台的大组件,data、methods、computed、watch堆得像小山,找个逻辑要翻半天,现在用setup和组合函数封装,比如把分页、表格筛选、抽屉弹窗的状态分别抽成hooks,复用率瞬间上去,维护起来也轻松,Ant Design Vue作为国内开发最顺手的企业级UI库之一,不用多说,组件覆盖全——表格、表单、图表、权限组件这些后台刚需都有,而且适配Vue3做得很早,4.x版本已经是Vue3专属,优化了不少性能,比如表格的虚拟滚动体验比以前好太多,还新增了一些贴合后台的小细节,比如表单组件的自动填充禁用、日期选择器的快捷选项预设更完善。

更重要的是,生态成熟,Vue3现在是主流,官方工具链Vite/Vue Router/Pinia都配套,Pinia作为Vue3的状态管理库,比Vuex简单直观,用来存后台的用户信息、全局菜单、权限标识、临时缓存的表单数据,完全没问题,AntDv还有Pro Components这样的高级组件库,虽然不是官方亲儿子但维护得还行,能直接生成带高级筛选、批量操作的表格,省很多重复代码的时间,再加上现在网上的教程、开源项目很多,遇到问题查资料也方便。

用AntDv4.x和Vue3搭后台第一步应该做什么?

很多人上来就直接npm install vite vue ant-design-vue,然后开始写页面,最后发现主题不对、路由配置乱、权限没做、样式冲突,要推倒重来,其实第一步应该先搭好项目的“骨架”,把基础配置搞定,后面写页面才能顺风顺水。

初始化项目,推荐用Vite,速度比Webpack快太多,启动只要几秒钟,初始化的时候记得选Vue 3 + TypeScript?当然也可以选JavaScript,但用TypeScript的话,AntDv的类型提示特别全,写代码效率高,出bug的概率也低,不过如果团队里没人会TypeScript,也没关系,JavaScript也能跑,就是体验差点。

然后是配置Vite,比如配置路径别名,把@指向src目录,这样import的时候就不用写一堆../../了;配置环境变量,开发环境、测试环境、生产环境的API接口地址可以分别写在.env.development、.env.test、.env.production里,不用每次发布都改代码;如果需要配置代理的话,比如跨域问题,也可以在vite.config.ts里的server.proxy里加,把开发环境的API请求代理到后端的测试服务器。

接下来是集成AntDv4.x,现在AntDv4.x默认按需加载了,不用再配置babel-plugin-import了,这点很方便,直接引入就行,不过主题可能需要改,比如把AntDv的默认蓝色改成自己公司的品牌色,AntDv4.x提供了CSS变量的方式改主题,非常灵活,比如在main.ts或者单独的css文件里写:root { --ant-primary-color: #1890ff; / 改成自己的颜色 / } ,也可以通过ConfigProvider组件包裹整个应用来动态切换主题。

然后是路由配置,用Vue Router 4,路由模式推荐用history模式,比hash模式的URL好看,不过上线的时候需要后端配置一下,不然刷新页面会404,后台的路由一般分静态路由和动态路由,静态路由比如登录页、404页、首页,直接写在router/index.ts里;动态路由比如用户管理、角色管理、权限管理,需要根据后端返回的用户权限来动态生成,这里可以用Pinia来存用户权限和动态路由,然后在路由守卫里判断,如果用户没登录就跳登录页,如果登录了就检查有没有动态生成过路由,如果没有就调用接口获取权限,然后生成动态路由并添加到路由表中。

状态管理,用Pinia,推荐先建几个基础的store,比如userStore(存用户信息、token、权限)、menuStore(存全局菜单)、cacheStore(存临时缓存的表单数据、表格筛选条件),Pinia的语法很简单,比如userStore可以这样写:defineStore('user', () => { const token = ref(localStorage.getItem('token') || ''); const userInfo = ref({}); const permissions = ref([]); const setToken = (newToken) => { token.value = newToken; localStorage.setItem('token', newToken); }; const clearUser = () => { token.value = ''; userInfo.value = {}; permissions.value = []; localStorage.removeItem('token'); }; return { token, userInfo, permissions, setToken, clearUser }; }); ,然后在组件里直接用useUserStore()就能调用了。

用AntDv4.x的表格有哪些必用的优化技巧?

后台管理系统里用得最多的组件就是表格,AntDv4.x的表格功能很强大,但如果不优化的话,数据量大的时候会很卡,体验不好,下面说几个必用的优化技巧。

第一个是虚拟滚动,当表格数据超过1000条的时候,一定要开启虚拟滚动,不然页面会渲染所有的行,卡得动不了,AntDv4.x的表格开启虚拟滚动很简单,只要在a-table组件上加上:scroll="{ y: 500, x: 'max-content' }" ,然后数据量够大的话就会自动开启虚拟滚动了,不过要注意,开启虚拟滚动后,列的宽度必须是固定的,不能用百分比,不然虚拟滚动会失效。

第二个是自定义渲染,AntDv4.x的表格自定义渲染用的是插槽,比以前的render函数更直观、更方便,比如给表格的某一列加个状态标签,或者加个编辑、删除按钮,都可以用插槽,比如状态标签可以这样写:<template #bodyCell="{ column, record }"> ,编辑删除按钮可以这样写:<template #bodyCell="{ column, record }"> 。

第三个是高级筛选,AntDv4.x的表格默认有简单筛选,但后台一般需要高级筛选,比如日期范围筛选、下拉多选筛选,AntDv4.x的表格提供了filterDropdown插槽,可以自定义筛选面板,比如日期范围筛选可以这样写:<template #filterDropdown="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }">

<a-range-picker v-model:value="dateRange" @change="handleDateRangeChange(setSelectedKeys, confirm, clearFilters)" style="width: 100%; margin-bottom: 8px" /> <a-button type="primary" size="small" @click="confirm">确定 <a-button size="small" @click="handleClearFilters(clearFilters)">重置
,然后在a-table组件的columns里加上filterDropdown: true,filterIcon: 。

第四个是批量操作,后台一般需要批量删除、批量修改状态,AntDv4.x的表格提供了rowSelection属性,可以开启行选择,比如开启行选择可以这样写: ,然后在setup里定义rowSelection:const rowSelection = ref({ onChange: (selectedRowKeys, selectedRows) => { console.log('selectedRowKeys:', selectedRowKeys); console.log('selectedRows:', selectedRows); }, }); ,批量操作按钮可以放在表格的上方,

<a-button type="primary" :disabled="selectedRowKeys.length === 0" @click="handleBatchDelete">批量删除 <a-button :disabled="selectedRowKeys.length === 0" @click="handleBatchEnable">批量启用 <a-button danger :disabled="selectedRowKeys.length === 0" @click="handleBatchDisable">批量禁用
。

第五个是分页,后台一般都是分页查询数据的,AntDv4.x的表格提供了pagination属性,可以配置分页,比如配置分页可以这样写:const pagination = ref({ current: 1, pageSize: 10, total: 0, showSizeChanger: true, showQuickJumper: true, showTotal: (total) => 共 ${total} 条, pageSizeOptions: ['10', '20', '50', '100'], }); ,然后在a-table组件上加上:pagination="pagination" @change="handleTableChange" ,handleTableChange函数用来处理分页、排序、筛选的变化:const handleTableChange = (pag, filters, sorter) => { pagination.value.current = pag.current; pagination.value.pageSize = pag.pageSize; // 处理排序 if (sorter.field && sorter.order) { sortField.value = sorter.field; sortOrder.value = sorter.order === 'ascend' ? 'asc' : 'desc'; } else { sortField.value = ''; sortOrder.value = ''; } // 处理筛选 if (filters.status) { statusFilter.value = filters.status[0]; } else { statusFilter.value = ''; } // 调用接口获取数据 fetchData(); }; 。

用AntDv4.x的表单有哪些避坑指南?

后台管理系统里第二常用的组件就是表单,AntDv4.x的表单功能也很强大,但有几个坑如果不注意的话,会浪费很多时间。

第一个坑是表单的响应式数据,AntDv4.x的表单用的是useForm钩子来创建表单实例,然后表单的响应式数据是用formModel来绑定的,注意formModel必须是一个响应式对象,不能是普通的ref或者reactive包裹的非对象,比如不能这样写:const formModel = ref(''); ,必须这样写:const formModel = reactive({ username: '', password: '', email: '', phone: '', status: 1, }); 。

第二个坑是表单的验证,AntDv4.x的表单验证用的是rules属性,可以在a-form组件上统一配置,也可以在a-form-item组件上单独配置,验证规则可以用AntDv自带的,比如required、min、max、email、phone等,也可以自定义验证规则,自定义验证规则用的是validator函数,比如验证密码强度可以这样写:const validatePassword = (rule, value) => { if (!value) { return Promise.reject('请输入密码'); } if (value.length < 6) { return Promise.reject('密码长度不能少于6位'); } if (!/^(?=.[a-z])(?=.[A-Z])(?=.*\d)[a-zA-Z\d]{6,}$/.test(value)) { return Promise.reject('密码必须包含大小写字母和数字'); } return Promise.resolve(); }; ,然后在rules里加上:const rules = { password: [{ required: true, validator: validatePassword, trigger: 'blur' }], }; 。

第三个坑是表单的重置,AntDv4.x的表单重置用的是form.resetFields()函数,注意这个函数只会重置表单的初始值,不会重置formModel的其他属性,所以如果需要重置formModel的所有属性的话,可以手动把formModel的属性都改成初始值,或者用reactive包裹一个初始值对象,然后重置的时候用Object.assign(formModel, initialFormModel),const initialFormModel = { username: '', password: '', email: '', phone: '', status: 1, }; const formModel = reactive({ ...initialFormModel }); const handleReset = () => { form.resetFields(); Object.assign(formModel, initialFormModel); }; 。

第四个坑是表单的自动填充禁用,很多时候我们不希望浏览器自动填充表单的用户名和密码,比如修改用户信息的时候,这时候可以在a-form组件上加上autocomplete="off" ,然后在a-input-password组件上加上autocomplete="new-password" ,在a-input组件上加上autocomplete="one-time-code" 或者其他不常用的autocomplete值,不过有些浏览器可能会忽略autocomplete="off" ,这时候可以在a-form组件里加一个隐藏的input和password, ,这样浏览器就会自动填充这两个隐藏的input,而不会填充我们需要的表单了。

第五个坑是表单的日期选择器,AntDv4.x的日期选择器返回的是moment对象或者dayjs对象,现在AntDv4.x默认用的是dayjs,比moment小很多,性能也更好,注意,把日期传给后端的时候,需要把dayjs对象转换成字符串,比如用dayjs.format('YYYY-MM-DD HH:mm:ss') ;从后端获取日期的时候,需要把字符串转换成dayjs对象,比如用dayjs(dateStr) ,日期范围选择器返回的是一个数组,dayjs('2024-01-01'), dayjs('2024-01-31')] ,传给后端的时候也需要转换成字符串数组或者开始时间和结束时间的单独字符串。

用AntDv4.x和Vue3做权限控制怎么做比较好?

后台管理系统的权限控制是必不可少的,一般包括路由权限、按钮权限、数据权限,下面说一下用AntDv4.x和Vue3做权限控制的比较好的方案。

路由权限,前面搭项目骨架的时候已经提到过,静态路由比如登录页、404页、首页直接写在router/index.ts里,动态路由比如用户管理、角色管理、权限管理需要根据后端返回的用户权限来动态生成,具体的流程是:用户登录成功后,后端返回token和用户信息(包括权限标识或者路由树);然后在路由守卫里判断,如果用户没登录就跳登录页,如果登录了就检查Pinia里的permissions有没有值,如果没有就调用接口获取用户信息和权限标识;然后根据权限标识或者路由树生成动态路由,动态路由的component需要用import()动态引入,这样可以实现代码分割,提高首屏加载速度;然后把动态路由添加到路由表中,用router.addRoute();最后跳转到用户访问的页面或者首页。

然后是按钮权限,按钮权限一般是根据后端返回的权限标识来控制的,比如用户管理页面的编辑按钮需要有user:edit权限,删除按钮需要有user:delete权限,可以用自定义指令来实现按钮权限,比如建一个v-permission的自定义指令,在src/directives/permission.ts里写:import { useUserStore } from '@/stores/user'; export default { mounted(el, binding) { const userStore = useUserStore(); const permissions = userStore.permissions; const value = binding.value; if (value && value instanceof Array && value.length > 0) { const hasPermission = permissions.some(permission => value.includes(permission)); if (!hasPermission) { el.parentNode?.removeChild(el); } } else { throw new Error('请设置操作权限标识,例如v-permission="[\'user:edit\', \'user:delete\']"'); } }, }; ,然后在main.ts里注册这个自定义指令:import permission from '@/directives/permission'; app.directive('permission', permission); ,然后在组件里用的时候就可以这样写:<a-button type="link" v-permission="['user:edit']" @click="handleEdit(record)">编辑 ,如果用户没有user:edit权限,这个按钮就会被移除。

数据权限,数据权限一般是根据后端返回的用户权限或者角色来控制的,比如普通用户只能看到自己创建的数据,管理员可以看到所有数据,这个一般是后端来做的,前端只需要把用户的权限标识或者角色ID传给后端,后端根据这个来返回对应的数据,不过有时候前端也需要做一些简单的数据权限控制,比如隐藏某些列,这个可以根据权限标识来动态生成表格的columns。

Vue3结合Ant Design Vue是现在做后台管理系统的最佳技术栈之一,只要搭好项目的骨架,用好表格、表单的优化技巧和避坑指南,做好权限控制,就能快速开发出一个功能完善、体验良好的后台管理系统,这只是基础的内容,还有很多高级的技巧可以学习,比如自定义主题、动态表单、图表集成、国际化等等,以后有机会再跟大家分享。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

上一篇:.env.development
热门