# WEB 端系统框架使用说明
# 基础和特性
参照上方移动端框架使用说明。
# 入门
# 安装与运行
下载项目后,执行下面命令安装依赖包。(推荐 node 版本:10.3.0)
yarn install
本地环境代理启动命令
npm run serve
代码提交前 eslint 规则校验与修复
npm run lint --fix
发布测试环境打包命令
npm run build:test
布线上环境打包命令
npm run build:prod
# 请求路径配置
本地开发调试时在根目录的vue.config.js
中进行配置
devServer: {
open: true, //是否自动在浏览器打开
https: false, //是否配置https
hot: true,
hotOnly: true, //是否热更新
disableHostCheck: true,
proxy: {
"/proxy": {
target: "http://0.0.0.0/api", // 配置后台Api地址
ws: true,
changOrigin: true,
pathRewrite: {
"^/proxy": ""
}
}
}
}
# 公用组件库
全局组件库,可直接在页面调用,无需引入
# Banner 组件
代码
<y-bannershow imgBannerSrcName="`zhengwu@2x.png`" imgDesName="`后台管理系统`" />
参数说明:
参数 | 类型 | 默认 | 说明 |
---|---|---|---|
bWidth | String | 430 | banner 宽度 |
bHeight | String | 40 | banner 高度 |
bMarginLeft | String | 0 | banner 文字的左边距 |
bFontSize | String | 26 | banner 文字的大小 |
imgDesName | String | 描述图片的文字的图片 | |
imgBannerSrcName | String | zhengwu@2x.png | banner 图片名称 |
需要将 banner 图片放入 src/assets/banner 文件夹中
# 面包屑组件
代码
<y-breadcrumb :breadcrumbList="breadcrumbList" />
参数说明:
参数 | 类型 | 默认 | 说明 |
---|---|---|---|
breadcrumbList | Array | 430 | 面包屑数据列表 |
marginBottom | String | 30 | 距离底部 |
marginTop | String | 0 | 距离顶部 |
面包屑数据格式
[
{ "path": "/", "meta": { "title": "首页" } },
{ "path": "/Title", "meta": { "title": "标题" } },
{ "path": "", "meta": { "title": "信息展示" } }
]
# 头部组件
代码
<y-header :headerList="headerList" />
参数说明:
参数 | 类型 | 默认 | 说明 |
---|---|---|---|
headerList | Array | 头部标题列表 |
标题列表数据格式
[
{
link: "/", #跳转链接
name: "首页" #标题
},
{
link: "/ServiceCatalog",
name: "服务目录"
},
{
link: "/AnnouncementList",
name: "政务中心"
},
{
link: "/Communication",
name: "互动交流"
}
]
# 底部组件
代码
<y-footer :marginTop="`10`" />
参数说明:
参数 | 类型 | 默认 | 说明 |
---|---|---|---|
marginTop | String | 50 | 距离顶部 |
# 分页组件
代码
<y-pagination :total="'100'" @pagination="pageChange" />
参数说明:
参数 | 类型 | 默认 | 说明 |
---|---|---|---|
total | Number | null | 数据总数 |
page | Number | 1 | 当前页 |
limit | Number | 20 | 每页条数 |
pageSizes | Array | [10, 20, 30, 50] | 每页可选择展示条数 |
autoScroll | Boolean | true | 切换页是否自动回滚 |
在父页面编写自定义方法 pageChange 接收参数
pageChange (target) {
this.pageForm.cpage = target.page // 切换页码后的页数
this.pageForm.rows = target.limit // 切换页码后的条数
this.handleSearch() // 重新调用查询方法
}
# svg 组件
代码
<SvgIcon :iconClass="iconClass" :className="className" />
参数说明:
参数 | 类型 | 默认 | 说明 |
---|---|---|---|
iconClass | String | require | 图片线上地址 |
className | String | "" | 图片类型 |
# 标题组件
代码
<y-title :fontContSize="`20`" :content="`只是一个标题`" :colorCont="`666`" />
参数说明:
参数 | 类型 | 默认 | 说明 |
---|---|---|---|
border | Boolean | false | 是否有边框 |
fontContSize | String | 14 | 标题字大小 |
colorCont | String | 333 | 标题内容颜色 |
content | String | 标题 2 | 标题内容 |
pleft | String | 30 | 左边间距 |
fontWeight | String | normal | 是否可以加粗 |
lineWidth | String | 6 | 线宽度 |
lineHeight | String | 28 | 线高度 |
lineLeft | String | -17 | 线左边距 |
lineTop | String | 5 | 线头部边距 |
# 验证码组件
代码
<y-valid-code @validCodeChange="validCodeChange" :length="`6`" />
参数说明:
参数 | 类型 | 默认 | 说明 |
---|---|---|---|
width | String | 120 | 宽度 |
height | String | 50 | 高度 |
length | Number | 4 | 验证码长度 |
content | String | 标题 2 | 标题内容 |
pleft | String | 30 | 左边间距 |
fontWeight | String | normal | 是否可以加粗 |
lineWidth | String | 6 | 线宽度 |
lineHeight | String | 28 | 线高度 |
lineLeft | String | -17 | 线左边距 |
lineTop | String | 5 | 线头部边距 |
在父页面编写自定义方法 validCodeChange 接收参数
pageChange (target) {
// target.code - 当前验证码
// target.refresh // 是否刷新
}
# Layout 组件(页面布局)
Layout 组件是整个框架页面的基础组成。主要由图中的这几部分组成。可根据项目需求来进行适当修改,完成项目基础风格。 组件代码:
<div :class="classObj" class="app-wrapper">
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
<header-box v-if='showHeader' />
<sidebar class="sidebar-container" :class="{'show-header':showHeader}" />
<div class="main-container">
<div :class="{'fixed-header':fixedHeader}">
<navbar />
</div>
<app-main />
<y-footer/>
</div>
</div>
# 顶部组件 HeaderBox
位置 src/layout/components/HeaderBox.vue
通过根目录中的 settings.js 来设定顶部标题以及是否展示。
通过修改 src/layout/components/Sidebar/Logo.vue 中的 logo: require("@pic/logo@2x.png") 修改顶部图标。
通过修改组件内的 style 来修改 header 的样式。
# 侧边导航 Sidebar
位置 src/layout/components/Sidebar/index.vue
侧边导航栏,通过遍历路由表动态生成。 配置导航图标,可将 Svg 图标文件放入 src/icons/svg 中,在路由表中,meta.icon 属性配置 svg 文件名即可生效。
{
"path": "/",
"component": Layout,
"redirect": "/Home",
"children": [
{
"path": "Home",
"name": "Home",
"component": () =>
import(/* webpackChunkName: "loginModule" */ "@/views/Home.vue"),
"meta": {
"title": "首页",
"icon": "dashboard" // svg文件夹中的图标名称
}
}
]
}
# 面包屑 Navbar
位置 src/layout/components/Navbar.vue
已自动获取侧边导航栏点击路径生成面包屑,可根据项目需求来决定是否展示。 组件中代码位置:
<breadcrumb class="breadcrumb-container" />
# 底部组件 footer
位置 src/layout/components/Footer.vue 组件代码:
<div class="footer-container">
<span>Copyright@2020易联众民生(厦门)科技有限公司 闽ICP备 15XXXX89号</span>
</div>
# 主题配置
1.通过 src/styles/variables.scss
设置管理系统整体主题风格
$menuText: #bfcbd9; #菜单通用文字颜色
$menuActiveText: #3ca0f6; #菜单激活文字颜色
$subMenuActiveText: #1677ff; #多级下拉,子集被选中,父级的显示颜色
$menuBg: #fff; #sidebar菜单所有tab的默认展示背景色
$menuHover: #e7f1ff; #sidebar 鼠标 tab 的 hover 颜色和 tab 选中 active 颜色
$menuActive: #1677ff;#选中的右边边框
$subMenuBg: #fff; #sidebar整个区块的背景色
$subMenuHover: #e7f1ff; #sidebar 二级 tab 的 hover 颜色
$sideBarWidth: 210px; #sidebar 的宽度
#设置主题颜色
$theme-blue: #1677ff;
$blue-assist: #3ca0f6;
$main-color: #f5f5f5;
$main-blue: #1677ff; #常用蓝色
$main-bg: #f5f5f5; #主要背景色
2.通过 src/theme/reset.scss
统一重置 element 组件的样式
#搜索表单
.el-form-item {
margin-bottom: 8px;
}
#表内容会
.el-table__body tr td {
height: 40px;
background: $color-white;
text-align: center;
}
#表格加载页面
.el-table .el-loading-spinner .circular {
width: 36px;
height: 36px;
}
...
# 新增页面
以新增一个简单的用户管理页面为例。
# 创建 vue 文件
首先明确创建的页面属于哪个模块,然后去查找或者新建对应的文件目录
如用户管理属于系统管理模块,文件路径便为
views/system-module/user-managemenet
可通过脚本命令生成
npm run new:view
页面会生成在 views/目录下 如需要多层级请按照路径格式如:
输入:system-module/user-managemenet
则会在 views
创建 system-module
文件夹,再在 system-module
中创建 user-managemenet
文件夹,最后创建 index.vue 文件。
需要在已有目录中创建也是一样,输入多级路径即可。
生成的模板代码
<template>
<div class="user-managemenet">user-managemenet组件</div>
</template>
<script>
export default {
name: 'user-managemenet',
data() {
return {}
},
created() {}, // 页面初始化调用
methods: {}, // 自定义方法
}
</script>
<style lang="scss" scoped>
.user-managemenet {
}
</style>
# 添加路由
找到路由文件 src/router/common/index.js
{
path: "/system",
component: Layout,
meta: {
title: "系统管理",
icon: "mul"
},
children: [
{ // 字典管理
path: "/dict-management", // 路由路径
name: "dictManagement", // 路由名称
component: () => import("@/views/system-module/dict-management/index.vue"), // 页面组件
meta: {
title: "字典管理" //路由标题
}
},
{ // 新增用户管理
path: "/user-management", // 填写页面路径,一般为组件名
name: "userManagement", // 填写路由名称
component: () =>import("@/views/system-module/user-management/index.vue"),// 引入新增的页面组件
meta: {
title: "用户管理" // 填写路由标题
}
}
}
如新增的为一级菜单,则在与系统管理同级新增对象即可。
# 页面基础组成
# 顶部条件框
代码:
<div class="header-filter">
<el-form ref="conditiontForm" :inline="true" size="small">
<el-form-item label="姓名">
<el-input v-model="conditiontForm.name" placeholder="请输入应用名称" />
</el-form-item>
<el-form-item label="性别">
<el-select class="item-select" placeholder="请选择" v-model="conditiontForm.sex">
<el-option v-for="item in sexList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" size='small' @click="HandleSearch()">查询</el-button>
<el-button size='small' @click="conditiontForm = {}">重置</el-button>
</el-form-item>
</el-form>
</div>
写好header-filter
的样式后,统一使用。el-form
不再单独填写样式。
将查询条件都绑定一个同一个对象 conditionForm
,方便之后接口调用。
# 表单内容框
代码:
<div class="content-container">
<div class="table-oper">
<el-button type="success" @click="handleAdd()">新增用户</el-button>
</div>
<div class="table-content">
<el-table :data="tableData">
<el-table-column type="index" width="50" label="序号" />
<el-table-column label="姓名" prop="name" />
<el-table-column label="性别" prop="sex" />
<el-table-column label="年龄" prop="age" />
<el-table-column label="角色" prop="role" />
<el-table-column label="操作" fixed="right" width="180">
<template slot-scope="scope">
<el-link type="primary" @click="handleEdit(scope.row)">编辑</el-link>
<el-link type="danger" @click="handleDel(scope.row)">删除</el-link>
</template>
</el-table-column>
</el-table>
<y-pagination @pagination="pagination" :total="pageForm.totalCount"></y-pagination>
</div>
</div>
表格数据
data () {
return {
data: [{
id: 1,
name: "王一",
sex: "男",
age: "20",
role: "管理员",
}, {
id: 2,
name: "王一",
sex: "男",
age: "20",
role: "管理员",
}, {
id: 3,
name: "王一",
sex: "男",
age: "20",
role: "管理员",
}]
}
}
基础页面采用统一的布局和Class
,避免重复改写样式。
# 弹窗
弹窗代码:
<el-dialog :visible.sync="postDialogVisible" width="50%" class="edit-dialog" :title="dialogName">
<el-form ref="postForm" :rules="rules" :model="postForm" :inline="true" size="small">
<el-form-item label="姓名" prop="name" required>
<el-input v-model="postForm.name" placeholder="请输入姓名" />
</el-form-item>
<el-form-item label="性别" prop="sex" required>
<el-select class="item-select" placeholder="请选择" v-model="postForm.sex">
<el-option v-for="item in sexList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="年龄" prop="age" required>
<el-input v-model="postForm.age" placeholder="请输入年龄" />
</el-form-item>
<el-form-item label="角色" prop="role" required>
<el-select class="item-select" placeholder="请选择" v-model="postForm.role">
<el-option v-for="item in roleList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="handleSave('postForm')">保 存</el-button>
<el-button @click="postDialogVisible = false">取 消</el-button>
</span>
</el-dialog>
新增与编辑建议采用同一个弹窗,通过handleAdd()
,handleEdit()
改变弹窗标题dialogName
。
# 新增接口
与新增 Vue 页面思路类似,需要找到src/api/modules
下对应的 api 文件。
不清楚可通过查询路由。系统管理即对应 system-api。
api 文件的命名通常为一级路由 +
-api
{
"path": "/system",
"component": Layout,
"meta": {
"title": "系统管理",
"icon": "mul"
}
}
在 system-api 文件中编写新接口
推荐写法
/**
* 系统管理-用户管理-查询用户
*
* @param {*} params
* @param {*} options
* @returns
*/
export function findAllUser(params) {
return request({
url: '/allUserInfo',
method: 'get',
params: params,
})
}
当请求方式为get
时 参数为 params: params。
当请求方式为post
时 参数为 data: params。
最后在src/api/index.js
中导出接口 Api。
import * as systemApi from './modules/system-api'
export { systemApi }
# 表单查询
在 vue 文件中引入 api
import { systemApi } from '@api/index'
页面的基础表单查寻,建议采用统一命名。 handleSearch(){} // 查询
这样多个页面只需要修改里面调用的 Api 名称,方便后续版本的迭代更新。
参数使用扩展运算符赋值,这样之后接口变动(增加或者删除字段)只需修改页面代码,无需改动方法。
handleSearch () {
const params = { ...this.conditiontForm, ...this.pageForm } // 条件对象 和 分页对象
userManageApi.findAllUser(params).then(res => {
this.tableData = res.data
this.pageForm.totalCount = this.tableData.length
})
}
# 表单提交
在 vue 文件中引入 api
import { systemApi } from '@api/index'
页面的基础增删改表单提交,建议采用统一命名。 handleAdd(){} // 新增 handleEdit(){} // 编辑 handleDel(){} // 删除
这样新增多个页面只需要修改里面调用的 Api 名称,方便后续版本的迭代更新。
参数使用扩展运算符赋值,这样之后接口变动(增加或者删除字段)只需修改页面代码,无需改动方法。
handleAdd () {
const params = { ...this.postForm }
systemApi.addUser(params).then(res => {
if (res.code === "00") {
this.postDialogVisible = false
}
})
}
# 表单校验
Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。 Form 表单代码:
<el-form ref="postForm" :rules="rules" :model="postForm" :inline="true" size="small">
<el-form-item label="姓名" prop="name" required>
<el-input v-model="postForm.name" placeholder="请输入姓名" />
</el-form-item>
<el-form-item label="性别" prop="sex" required>
<el-select class="item-select" placeholder="请选择" v-model="postForm.sex">
<el-option v-for="item in sexList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="年龄" prop="age" required>
<el-input v-model="postForm.age" placeholder="请输入年龄" />
</el-form-item>
<el-form-item label="角色" prop="role" required>
<el-select class="item-select" placeholder="请选择" v-model="postForm.role">
<el-option v-for="item in roleList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-form>
data 里的 rule 规则代码:
rules: {
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' }
],
age: [
{ required: true, message: '请输入年龄', trigger: 'blur' }
],
sex: [
{ required: true, message: '请选择性别', trigger: 'blur' }
],
role: [
{ required: true, message: '请选择角色', trigger: 'blur' }
]
}
表单提交时调用校验方法代码:
this.$refs['postForm'].validate((valid) => {
if (valid) {
// 验证通过调用接口
} else {
console.log('error submit!!')
return false
}
})
# *关于表单生成器
# 打包发布
发布测试环境:
修改根目录下的.env.test
文件
NODE_ENV='production'
BASE_URL="http://192.168.44.86:8007/api" #填写测试服务器Api地址
VUE_APP_TIMEOUT = 8000
VUE_APP_TOKEN='_app_token_'
运行脚本命令
vue-cli-service build --mode test
或者点击 VSCode-NPM 脚本中的 build:test。 项目中根目录 dist 文件夹即为打包后的代码。
发布正式环境:
修改根目录下的.env.prod
文件
NODE_ENV='production'
BASE_URL="http://www.12333.gov.cn/cloud-app/api/service" #填写正式服务器Api地址
VUE_APP_TIMEOUT = 8000
VUE_APP_ENABLE_MOCK = false
VUE_APP_MOCK_SERVER = ''
VUE_APP_TOKEN='_app_token_'
运行脚本命令
vue-cli-service build --mode prod
或者点击 VSCode-NPM 脚本中的 build:prod。 项目中根目录 dist 文件夹即为打包后的代码。