# 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": ""
				}
			}
        }
    }

# 公用组件库

全局组件库,可直接在页面调用,无需引入

An image

代码

<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 文件夹中

# 面包屑组件

An image

代码

<y-breadcrumb :breadcrumbList="breadcrumbList" />

参数说明:

参数 类型 默认 说明
breadcrumbList Array 430 面包屑数据列表
marginBottom String 30 距离底部
marginTop String 0 距离顶部

面包屑数据格式

[
  { "path": "/", "meta": { "title": "首页" } },
  { "path": "/Title", "meta": { "title": "标题" } },
  { "path": "", "meta": { "title": "信息展示" } }
]

# 头部组件

An image

代码

<y-header :headerList="headerList" />

参数说明:

参数 类型 默认 说明
headerList Array 头部标题列表

标题列表数据格式

[
        {
          link: "/",   #跳转链接
          name: "首页" #标题
        },
        {
          link: "/ServiceCatalog",
          name: "服务目录"
        },
        {
          link: "/AnnouncementList",
          name: "政务中心"
        },
        {
          link: "/Communication",
          name: "互动交流"
        }
      ]

# 底部组件

An image

代码

<y-footer :marginTop="`10`" />

参数说明:

参数 类型 默认 说明
marginTop String 50 距离顶部

# 分页组件

An image

代码

<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 组件

An image

代码

<SvgIcon :iconClass="iconClass" :className="className" />

参数说明:

参数 类型 默认 说明
iconClass String require 图片线上地址
className String "" 图片类型

# 标题组件

An image

代码

<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 线头部边距

# 验证码组件

An image

代码

<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 组件(页面布局)

An image

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" />

位置 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;
}
...

# 新增页面

以新增一个简单的用户管理页面为例。 An image

# 创建 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: "用户管理" // 填写路由标题
        }
      }
}

如新增的为一级菜单,则在与系统管理同级新增对象即可。

# 页面基础组成

# 顶部条件框

An image 代码:

<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,方便之后接口调用。

# 表单内容框

An image 代码:

<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,避免重复改写样式。

# 弹窗

An image

弹窗代码:

<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
	 }
	})
}

# 表单校验

An image

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
  }
})

# *关于表单生成器

一个在线表单生成器 (opens new window)

# 打包发布

发布测试环境: 修改根目录下的.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 文件夹即为打包后的代码。

更新时间: 11/17/2020, 5:43:20 PM