一个文笔一般,想到哪是哪的唯心论前端小白。
🧠 - 简介
前面对模板项目进行了一全局的展望,本篇则从细节方面上说明一下具体怎么去想办法解决提出来的问题。
👁️ - 分析
模板项目的使用场景只有一个,就是B端类CURD项目。
第一步、需要考虑的是有哪些通用组件需要择出来,以及为什么要择出来?
第二步、则是如何做到 高内聚、低耦合、易扩展、好上手?
第三步、更多的复杂功能如何支持?主题切换、国际化、水印管理...
🫀 - 拆解
我梳理的通用组件:
- layout:布局,配合布局的还有:
- header:统一头部及头部工具
- footer:统一底部及底部工具
- menu:菜单,主要是纵向菜单
- drawer:抽屉,element-plus提供的抽屉,需要自己声明开关方法,并且需要自己修改头部等等信息,为了保持整站抽屉样式一致,将项目中需要定义的一些样式(padding、header、footer、color)进行预置,改一处,全局变化。并统一暴露 open 和 close 方法。
- dialog:弹窗,和抽屉同理。
- message:提示信息,element-plus 的 ElMessage 是用 js 调用的,其支持配置,单独包一层主要就是为了保存这个配置。
- form:表单
- table:表格(分页)
- chart:图表
做这个的目的就是能够统一调度这些通用组件,至少在扩展业务的时候,原有的逻辑能够很快的融入进来,不会为了配合一个新的业务,而花费很多的时间成本。
我在设计 layout 的时候,增加了几个字段:hasBread
、hasFooter
、hasAside
、hasHeader
,在这个基础上进行简单的设计,就可以兼容多个业务场景的页面。例如:登录页面是没有页面布局的,营销页面则只有头部和底部,还有外挂页面,其实是只有 main 部分的。
抽屉和弹窗则是只是把自身的头部和底部进行了预处理,对外暴露了 cancel 和 confirm 并且增加了一个支持扩展其他操作按钮的插槽。
因为表格是一个和同页面内的所有组件都有关联,所以在设计 hooks 的时候,会传入多个 Ref 实例,以保证在任何地方都和在 page 中操作是一样的。
诸如此类的考虑,后面会慢慢的记录。
💪 - 落实
🎺 各命名规范
- 文件夹:中线连接,例如:common-table
- vue文件:大驼峰,顺序依次为 类别 + 模块 + 功能,例如:DialogLoginForm.vue,这样的目的是保证编辑器排序的时候更方便的找到,当然了,需要根据实际情况,最长的话一般三级也就足够了。
- ts/js文件:小驼峰,例如:dataExcmple.ts
- 特殊文件:*.class.ts *.type.ts
文件内部的话就由自己习惯来了,或者根据惯例:常量(全大写)、临时(_xxx)、标签(el-dialog)、标签class名(el-dialog)、js方法名(小驼峰)、js类名(大驼峰)...
🎺 assets 中 styles
styles 里面会有一个 index.scss 被 main.ts 引用,index.scss 则整合了所有的scss样式表:
- base.scss:基础样式
- element-plus:element-plus 自带样式
- element-reset:自己对 element-plus 的覆盖与补充,注意顺序
- iconfont
- mixin
- . . .
🎺 components 中的全局组件
在 components 中有一个 globalPlugin.ts 文件,将需要挂载在全局的组件进行对外暴露,这样就不用在每个 vue 文件中再引入了,很方便。
ts
// globalPlugin.ts
import { App } from 'vue';
import Searcher from './common-form/Searcher.vue';
import Saver from './common-form/Saver.vue';
import BaseTable from './common-table/BaseTable.vue';
import Former from './common-form/Former.vue';
import PageTools from './common-block/CommonPageTools.vue';
import Loger from './common-loger/Loger.vue';
import Drawer from './common-drawer/Drawer.vue'
const globalComp = {
install(Vue: App) {
Vue.component('Searcher', Searcher);
Vue.component('PageTools', PageTools);
Vue.component('BaseTable', BaseTable);
Vue.component('Saver', Saver);
Vue.component('Loger', Loger);
Vue.component('Drawer', Drawer);
Vue.component('Former', Former);
},
};
export default globalComp;
// main.ts
import globalComp from '@/components/globalPlugin';
createApp(App)
.use(ElementPlus, {
locale: zhCn,
})
.use(globalComp)
.use(router)
.use(pinia)
.mount('#app');
🎺 axios 的功能总结
axios 主要需要考虑几件事情:
- 全局配置:超时、baseUrl...
- 拦截器
- 请求拦截器:对请求的统一处理,如 token 的添加,请求头的处理,防SQL注入...
- 响应拦截器:
- 对异常状态的处理:401/403/404/500/...
- 响应体的预处理,不合法数据的过滤
- 接口 restful 化,并进行静态方法的扩展,例如:upload、download 等
至于方案,我声明了一个名为 Http 的 class,并挂载了多个静态方法(static)。
- get
- put
- post
- delete
- download
后面需要的话,再加强一下优化程度:
- 取消请求
- 重复请求
- 超时自动重启
- . . .
🎺 message 的全局统一化处理
主要是两个组件的处理:ElMessage 和 ElMessageBox。
我声明了一个名为 Message 的 class,并挂载了多个静态方法(static)。
- error:报错
- success:成功
- warning:警告
- info:文本
- confirm:二次确认
- delete:删除
因为静态方法的存在,所以理论上可以扩展更多的场景。
🛀 - 总结
至此,已经实现了整个模板项目的整体方向。
在麻雀虽小五脏俱全中,已经实现了一个麻雀,但是五脏还待完成。
系列文章:
- 脚手架开发
- 模板项目初始化
- 模板项目开发规范与设计思路
- layout设计与开发
- login 设计与开发
- CURD页面的设计与开发
- 监控页面的设计与开发
- 富文本编辑器的使用与页面设开发设计
- 主题切换的设计与开发并页面
- 水印切换的设计与开发
- 全屏与取消全屏
- 开发提效之一键生成模块(页面)