前端开发
开发必备
- 在进行开发之前,需要搭建好项目的运行环境。具体可查看“教程”-》“环境搭建”-》“软件安装”-》“Vue环境安装”
- 需掌握一定的 Vue3 及 TypeScript 使用技能。
- 创建VueCMF前端项目。具体可查看“教程”-》“安装运行”-》“安装VueCMF前端”
一切开发相关的都准备好了之后,就可以开始使用IDE工具(如vscode、webstorm等)编写代码了。接下来开始前端代码部分介绍及如何在此基础上进行开发。
目录结构
先从代码的目录结构开始,打开你的VueCMF前端项目,你看到的项目目录结构应该是下面的形式。如下
├── node_modules # 依赖包所在目录
├── public # 项目首页及静态资源所在目录
├── src # 项目源码所在目录
| ├── assets # 样式文件目录
| ├── components # 组件目录
| ├── model # 模型层文件目录
| ├── router # 路由配置目录
| ├── service # 服务层文件目录
| ├── store # 状态管理配置目录
| ├── typings # TypeScript类型配置目录
| ├── views # 视图层文件目录
| ├── App.vue # 模板首页
| ├── main.ts # 项目入口文件
| ├── registerServiceWorker.ts # 资源缓存服务文件
| └── shims-vue.d.ts # TypeScript的.vue的适配定义文件
├── .browserslistrc # 浏览器兼容配置文件
├── .env.development # 开发环境的后端API配置
├── .env.production # 生产环境的后端API配置
├── .env.test # 测试环境的后端API配置
├── .eslintignore # 代码规范检测忽略文件配置
├── .eslintrc.js # 代码规范检测配置
├── .gitignore # git忽略文件配置
├── auto-imports.d.ts # 组件自动导入配置
├── babel.config.js # babel插件配置
├── components.d.ts # 组件自动导入配置
├── package.json # 项目依赖包配置
├── README.md # 使用说明文档
├── tsconfig.json # TypeScript配置
└── vue.config.js # webpack配置
代码架构
介绍完VueCMF前端的目录结构,下面说说代码是如何组织的。主要分为模型层、服务层、事件层及视图层。下面就一一展开介绍。
模型层
模型层的代码文件存放在项目的src下的model目录,其作用是负责与后端API的对接。刚创建的vuecmf项目由以下四个文件组成
- BaseModel.ts 基础模型抽象类:里面包含有get、post请求及获取后端URL等公共方法,主要用于其它继承用。
- DataModel.ts 数据模型类:主要封装了一些供服务层调用的获取后端数据的方法。
- LayoutModel.ts 界面布局模型类:里面含有获取导航菜单数据方法
- LoginModel.ts 登录模型类:里面含有登录后台及获取服务器信息的方法
若需要添加新的与后端API对接(如新增批量删除功能),可在DataModel.ts 文件中添加或继承BaseModel.ts, 例如
//在model目录下创建一个PhotoModel.ts文件,内容如下
import BaseModel from "./BaseModel"
/**
* 相册模型
*/
export default class PhotoModel extends BaseModel {
constructor() {
super();
}
/**
* 批量删除照片
* @param id_list 照片id,多个用英文逗号分隔
*/
batchDel = (id_list: string): Promise<AnyObject> => {
return this.request('photo', 'batch_del', {
data:{ id_list: id_list }
}).then((res) => {
if(res.status == 200 && res.data.code == 0){
return Promise.resolve(res.data)
}else{
return Promise.reject(res.data)
}
})
}
}
BaseModel.ts 中的公共API请求方法 request 的参数说明如下
- table_name: 模型表名(即在后台“模型配置”列表中的“表名”)
- action_type: 模型的动作类型(即在后台“模型配置”列表中找到“模型动作”,点击后面的“字段”按钮,在打开的列表中找到“动作类型”后点击“选项”按钮,在打开的列表中“选项值”列即是这里要填的值)
- data: 发送给后端的数据
- method: 请求方式(get或post),默认为post
模型中代码写好后,如何配置与后端接口的映射呢?可在后台的“模型配置”中设置,如下
- 默认系统中已内置了常用的动作类型,若没有你想要动作类型,可在“模型配置”列表找到“模型动作”,点击后面的“字段”按钮,在打开的弹窗列表中找到“动作类型”后,点击“动作类型”所在行后面的“选项”按钮,在打开的列表窗口中,点击“新增”按钮
- 在“模型配置”列表找到需要添加动作类型的模型(如相册管理模型),点击该模型所在行后面的“动作”按钮,在打开的“设置(相册管理)动作”弹窗列表中,点击“新增”按钮, 如下
通过上面两步操作就完成的前端与后端接口的对接。这样就可以在前端代码中通过 BaseModel 中的 request 方法传入参数table_name(photo)以及action_type(batch_del)与后端进行交互了。
注意
在新增模型的动作时,“后端请求地址”必须以“/”开头,不得以“/”结尾,否则在设置权限时不会生效。 例如
- 正确:/vuecmf/photo/batchDel
- 错误:vuecmf/photo/batchDel, vuecmf/photo/batchDel/, /vuecmf/photo/batchDel/
模型层介绍完了,接下来就是服务层了。
服务层
服务层代码文件存放在项目的src下的service目录,其作用是调用事件层及模型层供视图层中的模板(.vue文件)调用。刚创建的vuecmf项目由以下event目录和四个文件组成, 如下
- event 目录:存放事件类文件。在后面的“事件层”中有详细介绍。
- BaseService.ts 基础服务抽象类: 主要包含公共的变更及异常处理方法等,供其它服务类继承。
- ContentService.ts 内容服务类: 后台内容展示区的核心类,主要包含列表管理、用户、角色、权限、模型及事件处理。
- LayoutService.ts 后台布局服务类:主要包含调用LayoutModel来加载菜单及路由、标签页管理,界面响应式处理。
- LoginService.ts 登录服务类:主要包含调用LoginModel的登录、获取用户登录信息及服务器信息的事件方法。
例如,创建一个PhotoService服务类并添加一个批量删除方法
//在service目录下创建一个PhotoService.ts文件,内容如下
import BaseService from "@/service/BaseService";
import PhotoEvent from "@/service/event/PhotoEvent";
import PhotoModel from "@/model/PhotoModel";
/**
* 相册服务类
*/
export default class PhotoService extends BaseService{
//列表后端接口地址
api_list_server: string
constructor() {
super();
const photoModel = new PhotoModel() //实例化PhotoModel类
this.api_list_server = photoModel.getApiUrl('photo','list') //调用后端列表接口
}
/**
* 批量删除照片
* @param selectRows 选择的行数据
*/
public batchDel = (selectRows: any):void => {
if(selectRows){
let id_arr = []
selectRows.forEach((row) => {
id_arr.push(row.id)
})
const photoEvent = new PhotoEvent()
photoEvent.batchDel(id_arr.join(','))
}
}
}
现服务类创建好了,有没有发现上面的PhotoEvent事件类还没创建呢,接下来就是创建该事件类的时候了。
事件层
事件层代码文件存放在项目的src下的service目录中的event目录,其作用是调用模型层并提供事件方法供服务类调用。刚创建的vuecmf项目由以下六个文件组成,如下
- BaseEvent.ts 基础事件抽象类:主要封装了初始化列表及权限相关事件处理,供其它事件类继承。
- AdminEvent.ts 管理员事件类:主要提供管理员事件的配置及事件方法供ContentService服务类调用(如设置角色、设置权限)。
- MenuEvent.ts 菜单事件类:主要提供菜单事件的配置及菜单列表中按钮权限的控制。
- ModelConfigEvent.ts 模型配置事件类:主要提供模型配置列表的事件配置及设置字段、设置索引、设置动作及设置表单等事件方法。
- RolesEvent.ts 角色事件类:主要提供角色管理列表中的事件配置及添加子角色、设置权限及设置用户事件方法。
- DefaultEvent.ts 默认事件类:事件配置及方法继承自BaseEvent,在后台“模型配置”列表中新增的模型都是调用此事件类。你可以在此事件类中自定义自己需要的功能,可参考其它事件类写法(如AdminEvent)
下面就接着上面服务层介绍中还没有创建的PhotoEvent事件类,在这里开始创建。如下
//在event目录下创建一个PhotoEvent.ts文件,内容如下
import PhotoModel from "@/model/PhotoModel";
import {ElMessage} from "element-plus/es";
/**
* 相册事件类
*/
export default class PhotoEvent {
photoModel: any //定义一个相册模型实例
/**
* 构造方法
* @protected
*/
protected constructor()
{
//实例化PhotoModel类
this.photoModel = new PhotoModel()
}
/**
* 批量删除照片
* @param id_list 照片id,多个用英文逗号分隔
*/
public batchDel = (id_list: string):void => {
this.photoModel.batchDel(id_list).then((res:AnyObject) => {
if(res.status == 200 && res.data.code == 0){
ElMessage.success(res.data.msg)
}else{
ElMessage.error(res.data.msg)
}
})
}
}
业务逻辑代码现都写好了,那么该如何加到模板文件(.vue)中,在后台界面中实现最终用户使用的功能呢?接下来,视图层就是解决这个问题的。
视图层
视图层的模板文件存放在项目的src下的views目录中,其作用是渲染后台界面,直接面对用户的。刚创建的vuecmf项目由template目录和四个模板文件组成,如下
- template 目录:存放后台主内容展示区的模板文件(如列表页模板)。
- Layout.vue 后台界面框架布局模板:主要功能是调用LayoutService加载菜单及路由信息并渲染后台整体的框架布局。
- Login.vue 登录页模板:主要功能是调用LoginService提供用户登录后台的界面。
- Refresh.vue 刷新页模板:供后台刷新界面事件调用。
- Welcome.vue 欢迎页模板:登录后台的欢迎页,主要展示当前服务器的配置信息等。
下面就接着上面事件层留下的一个问题,在template目录下开始创建一个相册列表模板文件(PhotoList.vue),并加入调用业务逻辑代码。如下
<template>
<vuecmf-table
ref="photo_list_ref"
height="460px"
:selectable="true"
:checkbox="true"
:token="token"
:server="server"
>
<!-- 表格头部左边 自定义按钮操作 -->
<template #headerAction="selectRows">
<el-button type="danger" @click.prevent="batchDel(selectRows)">批量删除</el-button>
</template>
</vuecmf-table>
</template>
<script lang="ts" setup>
import PhotoService from "@/service/PhotoService";
const service = new PhotoService()
//调用服务类中成员变量
const server = service.api_list_server
const token = service.token
//调用服务类中成员方法
const batchDel = service.batchDel
</script>
<script lang="ts">
import {defineComponent} from "vue";
export default defineComponent({
name: "PhotoList"
})
</script>
模板文件创建好了,下面就可以将模板文件通过后台的“模型配置”列表,找到“模型配置”模型,点击后面的“字段”按钮,在弹出的“设置(模型配置)字段”列表中找到“组件模板”字段,然后点击后面的“选项”按钮,在弹出的“设置(组件模板)字段选项”窗口中,点击“新增”按钮添加即可。如下
组件模板添加好后,就可以在“模型配置”列表中新增或编辑对应模型的表单中选择添加的“组件模板”了。
到目前为止,前端项目的功能开发已全部完成了。 若你开发功能比较复杂,单个模板文件内容比较多,那你就可以按功能模块拆分将其封装成一个个组件,然后再加入模板文件中,这样可以便于代码阅读及后期模板维护。接下来就开始介绍这块了
组件
组件的.vue文件存放在项目的src下的components目录中,其作用是封装模板文件中可复用的功能供各模板文件调用。刚创建的vuecmf项目在components目录下有四个组件文件,如下
- LayoutAsideMenu.vue 后台左边菜单列表组件
- LayoutAsideMenuItem.vue 后台左边菜单列表中子菜单项组件
- LayoutHeader.vue 后台顶部导航主菜单组件
- LayoutTabs.vue 后台标签页管理组件
以下是Layout.vue模板文件中调用组件的部分代码,具体详细代码可查看项目中对应的代码文件,这里就不全部贴出来了。
<template>
<el-container>
<!-- 左侧菜单 -->
<el-aside :width="aside_width" >
<vuecmf-layout-aside-menu
:aside_menu_active="aside_menu_active"
:is_side_collapse="is_side_collapse"
:aside_menu_list="aside_menu_list"
:collapse="collapse"
:addTab="addTab"
></vuecmf-layout-aside-menu>
</el-aside>
<!-- 这里省略部分代码, 具体详细代码可查看项目中对应的代码文件-->
</el-container>
</template>
状态管理
状态管理的代码文件存放在项目的src下的store目录中,主要包含后台导航菜单列表及后端API映射列表的状态。关于状态管理如何配置及使用可查看vuex官方文档
下面是项目中状态管理的部分代码,详细的可查看src下的store目录中的index.ts文件
import { createStore } from 'vuex'
export default createStore({
state: {
nav_menu_list: [], //系统导航菜单列表
api_maps: [], //后端API映射列表
},
//后面的代码省略,详细可查看对应代码文件
})
路由
路由的代码文件存放在项目的src下的router目录中,其作用是处理菜单链接的跳转处理及界面内容切换。刚创建的vuecmf项目在router目录下有一个index.ts路由配置文件,里面已全部配置好了,一般不推荐修改此文件。若你需要在路由跳转时做一些特殊处理,可以修改此文件。关于路由如何设置,可以查阅Vue Router官方文档
以下项目中的路由配置的部分代码,详细配置可查看src下的router目录中的index.ts文件
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'home',
component: () => import('@/views/Layout.vue'),
redirect: 'welcome',
children: [
{
path: 'welcome',
component: () => import('@/views/Welcome.vue'),
name: 'welcome',
meta: { breadcrumb_list: ['欢迎页'], title: 'welcome! - Powered by www.vuecmf.com', icon: 'welcome', noCache: true,topId:0, id:0, token:'123'}
},
]
},
//后面配置代码已省略,详细配置可查看src下的router目录中的index.ts文件
]
类型配置
TypeScript的类型配置代码文件存放在项目的src下的typings目录中,其作用是定义一些类型用于TypeScript的类型检查。刚创建的vuecmf项目在typings目录下有一个vuecmf.ts文件。 你可以在此文件中添加自己的类型定义, 例如文件中已定义好的Tag类型,如下
export interface Tag {
title: string,
path: string
}
调试
代码都编写好了,下面就需要进行功能调试了,验证功能是否可用,有没有什么Bug。打开命令行终端,将目录切换到自己项目的根目录,然后输入“yarn dev”回车,即进入开发调试模式
yarn dev
部署
当调试没有问题,功能可以正常使用后,就可以打包项目,部署到生产环境了。打开命令行终端,将目录切换到自己项目的根目录,然后输入“yarn build”回车,即开始打包项目了
yarn build
详细的操作请参考:“教程”下面的 安装vuecmf前端 章节