------ 本文章内容持续更新 ------
一、介绍
银行管理端开发大多数使用的是vue2框架语法,使用内网开发,没有外部网络,所以在工具的使用和开发方式上会有一些差异。
本文主要介绍银行支付系统管理端(前端)的开发和针对管理端服务的后台开发,以及Nginx配置和项目部署,是一篇为新入职或刚接触内网开发的朋友们打造的持续更新系列内容。
文章内容包括:开发编译器配置与常用快捷键、项目启动与登录、Vue框架详解、样例代码解析、开发相关技巧、前后端联调、请求报文、管理端后台服务解析、管理端数据库解析、服务器部署、Nginx配置等
下面,我将详细介绍各部分内容:
二、管理端项目结构介绍

三、管理端项目启动和登录
1.node.js安装与环境变量配置
node.js是vue管理端项目开发的前提必要环境,在开发前必须安装
如果是本机开发,建议先下载nvm,,然后使用nvm list available查看远程仓库的node.js镜像,通过nvm install 16(版本号) 利用网络拉取安装对应版本,然后nvm list查看本机node.js,最后使用nvm use 16(版本号)命令完成node.js选择,这样的好处是方便快速切换node。
但现在是内网环境,如果不能利用网络直接下载,那么我们只需要从外界下载node.js安装包,上载到内网环境解压安装,同时配置全局系统环境变量。

2.node_modules解压
从外面联网环境下升级后的node_modules压缩包,放到本项目的根目录下,进行解压。
这里面包括了npm命令和各种工具依赖包:

3.npm run dev
切换到node_modules所在的文件夹,因为npm命令在里面,否则找不到命令

4.访问指定地址和端口


5.登录(先启动Auth服务)
登录的前提是先启动Auth服务(控制前端的后台,比如:菜单 角色 机构 权限 登录密码校验等)
查看你的vue.confifg文件,看你配置的代理转发Auth服务在哪里:
!如果包含/uaa的路径代理到的target是服务器上的Auth那你就不用自己本地启动Auth;
!如果包含/uaa的路径代理到的target是本地的Auth,那你就必须在本地启动Auth服务。


确保Auth是启动着且可以调用的,那么就可以进行登录:
通常开发人员首先可以使用管理员用户名密码: admin/123456
或者你可以连接上数据库,找到Auth数据库里的sys_user表查看登录用户有哪些
然后登录后就也可以找到系统管理下的用户管理,添加新用户然后重新登录。
开发环境不开验证码功能,随便输个东西就可以登录

六、目录菜单与用户角色配置
此功能实际是依赖管理端的专属后台-ManagerAuth服务端,通常也是部署在服务器上的,目录菜单、角色、机构法人等都存储在管理端对应的服务器数据库里,这样你可以通过管理端(前端)可视化的点击操作,实现目录菜单配置和角色配置。其实本质上就是发请求给后台服务端,然后写入数据库的过程。内部逻辑后续再详细分析,这里只介绍操作方式。
1.目录菜单配置
a.配置页面展示
在左侧目录栏:系统管理-菜单管理 可以添加编辑删除目录和菜单:

b.添加顶层目录
点击添加按钮进行添加,注意:输入的菜单名称和组件名称要和编译器严格对应!!!

c.添加菜单


d.效果展示



2.用户配置


3.角色配置

七、Vue框架详解(ElementUI)
1.Template部分
Template 是 Vue 的视图层,负责渲染页面结构,结合 ElementUI 可以快速搭建管理端页面。
1.1 Vue 基础模板语法
1.1.1 插值表达式 {``{ }}
- 用法:用于在模板中渲染 JavaScript 表达式、data 中的数据、计算属性等
- 注意事项:
- 只能写单个表达式,不能写语句(如
if/for等) - 会自动转义 HTML,防止 XSS 攻击,若要渲染 HTML 需用
v-html - 支持简单运算、三元表达式、方法调用
- 只能写单个表达式,不能写语句(如
- 示例:
html
<!-- 基础数据渲染 -->
<span>{{ username }}</span>
<!-- 表达式运算 -->
<span>{{ age + 1 }}</span>
<!-- 三元表达式 -->
<span>{{ isAdmin ? '管理员' : '普通用户' }}</span>
<!-- 方法调用 -->
<span>{{ formatDate(createTime) }}</span>
1.1.2 指令 v-bind(缩写 :)
- **用法:**动态绑定 HTML 标签的属性(如
class、style、src、disabled等) - 注意事项:
- 绑定
class支持对象语法、数组语法 - 绑定
style支持对象语法(驼峰式属性名)、数组语法 - 可绑定自定义属性
- 绑定
- 示例:
html
<!-- 基础绑定 -->
<img :src="imgUrl" :alt="imgAlt">
<button :disabled="isDisabled">提交</button>
<!-- class 绑定(对象语法:条件生效) -->
<div :class="{ 'active': isActive, 'error': hasError }"></div>
<!-- class 绑定(数组语法:多个类名) -->
<div :class="[baseClass, { 'active': isActive }]"></div>
<!-- style 绑定(对象语法) -->
<div :style="{ color: textColor, fontSize: fontSize + 'px' }"></div>
<!-- style 绑定(数组语法:多个样式对象) -->
<div :style="[baseStyle, customStyle]"></div>
1.1.3 指令 v-on(缩写 @)
- **用法:**绑定事件监听器,触发 methods 中的方法
- 注意事项:
- 支持事件修饰符(
.stop、.prevent、.once、.native等) - 支持按键修饰符(
.enter、.esc等)、系统修饰符(.ctrl、.alt等) - 可传递自定义参数,
$event代表原生事件对象
- 支持事件修饰符(
- 示例:
html
<!-- 基础点击事件 -->
<button @click="handleSubmit">提交</button>
<!-- 传递参数 + 事件对象 -->
<button @click="handleDelete(id, $event)">删除</button>
<!-- 事件修饰符:阻止冒泡、阻止默认行为 -->
<a @click.stop.prevent="handleLink">链接</a>
<!-- 只触发一次 -->
<button @click.once="handleOnlyOnce">仅点击一次</button>
<!-- 按键修饰符:回车触发 -->
<input @keyup.enter="handleSearch">
<!-- 系统修饰符:ctrl+enter 触发 -->
<input @keyup.ctrl.enter="handleSubmit">
1.1.4 指令 v-if / v-else-if / v-else
- **用法:**条件渲染,根据表达式真假控制元素的销毁 / 创建
- 注意事项:
- 是惰性渲染:初始条件为假时,不渲染元素
- 必须紧跟在兄弟元素后,不能被其他元素隔开
- 可配合
key区分不同元素,避免复用 DOM
- 示例:
html
<div v-if="status === 1">待审核</div>
<div v-else-if="status === 2">审核通过</div>
<div v-else>审核驳回</div>
<!-- 多元素条件渲染(template 包裹,不渲染额外标签) -->
<template v-if="isAdmin">
<el-button>新增</el-button>
<el-button>编辑</el-button>
<el-button>删除</el-button>
</template>
1.1.5 指令 v-show
- **用法:**条件渲染,根据表达式真假控制元素的
display样式(显示 / 隐藏) - 注意事项:
- 元素始终被渲染,仅切换 CSS
display属性 - 适合频繁切换的场景(性能优于
v-if) - 不支持
v-else,不能用在<template>标签上
- 元素始终被渲染,仅切换 CSS
- 示例:
html
<!-- 频繁切换的弹窗/面板 -->
<div v-show="showPanel">内容面板</div>
1.1.6 指令 v-for
- **用法:**列表渲染,遍历数组 / 对象生成重复元素
- 注意事项:
- 必须绑定
:key属性,且key必须唯一(推荐用id,不推荐用index) - 可遍历数组、对象、数字、字符串
- 不能和
v-if写在同一个元素上(优先级v-for更高,逻辑混乱),需用<template>包裹
- 必须绑定
- 示例:
html
<!-- 遍历数组 -->
<el-table-column
v-for="col in tableColumns"
:key="col.prop"
:prop="col.prop"
:label="col.label"
></el-table-column>
<!-- 遍历对象 -->
<div v-for="(value, key, index) in userInfo" :key="key">
{{ index + 1 }}. {{ key }}: {{ value }}
</div>
<!-- 配合 v-if 正确写法(template 包裹) -->
<template v-for="item in list" :key="item.id">
<div v-if="item.show">{{ item.name }}</div>
</template>
1.1.7 指令 v-model
- **用法:**双向数据绑定,常用于表单元素(
input、select、textarea等) - 注意事项:
- 本质是语法糖:
v-bind:value+v-on:input - 支持修饰符:
.lazy(失去焦点后更新)、.number(转为数字)、.trim(去除首尾空格) - ElementUI 组件(如
el-input、el-select)原生支持v-model
- 本质是语法糖:
- 示例:
html
<!-- 基础 input 绑定 -->
<el-input v-model="form.username" placeholder="请输入用户名"></el-input>
<!-- 修饰符使用 -->
<el-input v-model.number="form.age" placeholder="请输入年龄"></el-input>
<el-input v-model.trim="form.phone" placeholder="请输入手机号"></el-input>
<!-- select 绑定 -->
<el-select v-model="form.status" placeholder="请选择状态">
<el-option label="启用" :value="1"></el-option>
<el-option label="禁用" :value="0"></el-option>
</el-select>
1.1.8 指令 v-html
- **用法:**渲染 HTML 字符串,将内容作为 HTML 解析
- 注意事项:
- 存在 XSS 风险,仅在信任的内容上使用,绝对不能用在用户输入的内容上
- 会覆盖元素内原本的内容
- 示例:
html
<!-- 渲染富文本内容(后台返回的安全HTML) -->
<div v-html="richTextContent"></div>
1.1.9 指令 v-pre
- 用法:跳过元素和其子元素的编译,直接显示原始内容
- 注意事项:
- 用于展示原始的
{``{ }}语法,避免被 Vue 编译 - 可提升大量静态内容的渲染性能
- 用于展示原始的
- 示例:
html
<!-- 展示原始模板语法 -->
<div v-pre>{{ 这里不会被编译,直接显示 }}</div>
1.1.10 指令 v-cloak
- **用法:**在 Vue 实例编译完成前隐藏元素,编译完成后自动移除
- 注意事项:
- 需配合 CSS
[v-cloak] { display: none; }使用 - 解决页面加载时显示
{``{ }}原始语法的问题
- 需配合 CSS
- 示例:
css
/* 全局CSS */
[v-cloak] {
display: none;
}
html
<div v-cloak>{{ username }}</div>
1.1.11 指令 v-once
- **用法:**元素和组件只渲染一次,之后不再更新
- 注意事项:
- 用于大量静态内容,提升页面性能
- 嵌套的子元素也会被标记为静态
- 示例:
html
<!-- 静态页头,只渲染一次 -->
<div v-once>
<h1>管理系统后台</h1>
<p>版本号:v1.0.0</p>
</div>
1.2 ElementUI 布局类组件
1.2.1 el-container / el-header / el-aside / el-main / el-footer(容器布局)
- **用法:**快速搭建管理端侧边栏 + 顶栏 + 主内容的经典布局
- 注意事项:
el-container是父容器,嵌套子容器自动识别布局el-aside宽度可通过width属性自定义,默认 300pxel-header高度默认 60px,可通过height自定义
- 示例(管理端经典布局):
html
<el-container style="height: 100vh; border: 1px solid #eee;">
<!-- 顶栏 -->
<el-header style="background-color: #545c64; color: #fff; line-height: 60px; padding: 0 20px;">
<span>管理系统后台</span>
<el-dropdown style="float: right;">
<span class="el-dropdown-link">
{{ username }} <i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click="handleLogout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-header>
<el-container>
<!-- 侧边栏 -->
<el-aside width="200px" style="background-color: #2f363c;">
<el-menu :default-active="activeMenu" class="el-menu-vertical-demo" background-color="#2f363c" text-color="#fff" active-text-color="#ffd04b">
<el-menu-item index="/home">
<i class="el-icon-s-home"></i>
<span slot="title">首页</span>
</el-menu-item>
<el-submenu index="/user">
<template slot="title">
<i class="el-icon-s-custom"></i>
<span>用户管理</span>
</template>
<el-menu-item index="/user/list">用户列表</el-menu-item>
<el-menu-item index="/user/role">角色管理</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
<!-- 主内容区 -->
<el-main style="background-color: #f5f7fa; padding: 20px;">
<!-- 路由视图,渲染子页面 -->
<router-view></router-view>
</el-main>
</el-container>
</el-container>
1.2.2 el-row / el-col(栅格布局)
- 用法:基于 24 栅格系统,实现响应式页面布局
- 注意事项:
el-row是行容器,el-col是列,总份数为 24- 支持
:gutter设置列间距,type="flex"开启弹性布局 - 支持响应式断点:
xs(<768px)、sm(≥768px)、md(≥992px)、lg(≥1200px)、xl(≥1920px)
- 示例:
html
<!-- 基础栅格:两列布局,各占12份 -->
<el-row :gutter="20">
<el-col :span="12">
<el-card>左侧内容</el-card>
</el-col>
<el-col :span="12">
<el-card>右侧内容</el-card>
</el-col>
</el-row>
<!-- 响应式栅格:大屏4列,中屏6列,小屏12列 -->
<el-row :gutter="20">
<el-col :xl="6" :lg="8" :md="12" :sm="24">
<el-card>卡片1</el-card>
</el-col>
<el-col :xl="6" :lg="8" :md="12" :sm="24">
<el-card>卡片2</el-card>
</el-col>
<el-col :xl="6" :lg="8" :md="12" :sm="24">
<el-card>卡片3</el-card>
</el-col>
</el-row>
<!-- flex布局:对齐方式 -->
<el-row type="flex" justify="center" align="middle" style="height: 100px;">
<el-col :span="4">居中内容</el-col>
</el-row>
1.2.3 el-card(卡片组件)
- **用法:**用于内容区块展示,带阴影、标题、操作区
- 注意事项:
shadow属性控制阴影:always(始终显示)、hover( hover 显示)、never(不显示)- 可通过
header插槽自定义头部
- 示例:
html
<el-card class="box-card" shadow="hover">
<div slot="header" class="clearfix">
<span>用户统计</span>
<el-button style="float: right; padding: 3px 0" type="text" @click="handleRefresh">刷新</el-button>
</div>
<div style="height: 200px;">
<!-- 图表内容 -->
<div id="userChart"></div>
</div>
</el-card>
1.2.4 el-divider(分割线)
- 用法:内容区分割线,支持文字
- 注意事项:
content-position控制文字位置:left/center/rightdirection控制方向:horizontal(水平)、vertical(垂直)
- 示例:
html
<el-divider content-position="left">基础信息</el-divider>
<el-divider direction="vertical"></el-divider>
1.3 ElementUI 表单类组件(管理端核心)
1.3.1 el-form / el-form-item(表单容器)
- 用法:表单的根容器,用于表单验证、数据绑定、布局
- 注意事项:
model属性绑定表单数据对象,必须rules属性绑定验证规则,配合el-form-item的prop使用label-width统一设置标签宽度,label-position设置标签位置- 常用方法:
validate()(整体验证)、resetFields()(重置表单)、clearValidate()(清除验证)
- 示例(完整表单 + 验证):
html
<el-form
ref="userForm"
:model="form"
:rules="rules"
label-width="120px"
label-position="right"
style="max-width: 600px; margin: 0 auto;"
>
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" placeholder="请输入用户名"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="form.password" type="password" placeholder="请输入密码"></el-input>
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input v-model="form.phone" placeholder="请输入手机号"></el-input>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio :label="1">启用</el-radio>
<el-radio :label="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSubmit">提交</el-button>
<el-button @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
1.3.2 el-input(输入框)
- 用法:文本输入、密码输入、数字输入、带图标输入等
- 注意事项:
- 支持
v-model双向绑定 clearable可清空,show-password密码显示切换,disabled禁用prefix-icon/suffix-icon前后图标,placeholder占位符
- 支持
- 示例:
html
<!-- 普通输入框 -->
<el-input v-model="form.username" placeholder="请输入用户名" clearable></el-input>
<!-- 密码输入框 -->
<el-input v-model="form.password" type="password" show-password placeholder="请输入密码"></el-input>
<!-- 带图标输入框 -->
<el-input v-model="form.keyword" placeholder="请输入搜索关键词" prefix-icon="el-icon-search"></el-input>
<!-- 禁用输入框 -->
<el-input v-model="form.id" disabled placeholder="ID不可修改"></el-input>
1.3.3 el-select / el-option(下拉选择框)
- **用法:**下拉选择、多选、远程搜索、分组选择
- 注意事项:
v-model绑定选中值,multiple开启多选(值为数组)filterable开启搜索,remote开启远程搜索clearable可清空,placeholder占位符
- 示例:
html
<!-- 单选 -->
<el-select v-model="form.deptId" placeholder="请选择部门" clearable style="width: 100%;">
<el-option
v-for="dept in deptList"
:key="dept.id"
:label="dept.name"
:value="dept.id"
></el-option>
</el-select>
<!-- 多选 -->
<el-select v-model="form.roleIds" multiple placeholder="请选择角色" clearable style="width: 100%;">
<el-option
v-for="role in roleList"
:key="role.id"
:label="role.name"
:value="role.id"
></el-option>
</el-select>
<!-- 远程搜索 -->
<el-select
v-model="form.userId"
filterable
remote
placeholder="请输入用户名搜索"
:remote-method="remoteSearchUser"
:loading="loading"
style="width: 100%;"
>
<el-option
v-for="user in userList"
:key="user.id"
:label="user.username"
:value="user.id"
></el-option>
</el-select>
1.3.4 el-radio / el-radio-group(单选框)
- **用法:**单选选择,
el-radio-group用于分组管理 - 注意事项:
v-model绑定选中值,label为选项值border显示边框,disabled禁用
- 示例:
html
<el-radio-group v-model="form.gender">
<el-radio label="1" border>男</el-radio>
<el-radio label="2" border>女</el-radio>
<el-radio label="0" border>未知</el-radio>
</el-radio-group>
1.3.5 el-checkbox / el-checkbox-group(多选框)
- **用法:**多选选择,
el-checkbox-group用于分组管理 - 注意事项:
v-model绑定选中值(数组),label为选项值border显示边框,disabled禁用,indeterminate半选状态
- 示例:
html
<el-checkbox-group v-model="form.permissionIds">
<el-checkbox
v-for="item in permissionList"
:key="item.id"
:label="item.id"
border
>
{{ item.name }}
</el-checkbox>
</el-checkbox-group>
<!-- 全选/取消全选 -->
<el-checkbox
:indeterminate="isIndeterminate"
v-model="checkAll"
@change="handleCheckAllChange"
>
全选
</el-checkbox>
1.3.6 el-date-picker(日期选择器)
- **用法:**日期、时间、日期范围、时间范围选择
- 注意事项:
type控制类型:date(日期)、datetime(日期时间)、daterange(日期范围)、timerange(时间范围)format显示格式,value-format绑定值格式(推荐yyyy-MM-dd HH:mm:ss)placeholder/start-placeholder/end-placeholder占位符
- 示例:
html
<!-- 单个日期 -->
<el-date-picker
v-model="form.birthday"
type="date"
placeholder="选择日期"
value-format="yyyy-MM-dd"
style="width: 100%;"
></el-date-picker>
<!-- 日期时间 -->
<el-date-picker
v-model="form.createTime"
type="datetime"
placeholder="选择日期时间"
value-format="yyyy-MM-dd HH:mm:ss"
style="width: 100%;"
></el-date-picker>
<!-- 日期范围(用于列表筛选) -->
<el-date-picker
v-model="dateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
style="width: 100%;"
></el-date-picker>
1.3.7 el-upload(文件上传)
- 用法:文件上传、图片上传、多文件上传、上传前校验
- 注意事项:
action是上传地址(必填),headers设置请求头(携带 token)before-upload上传前校验(文件大小、类型),on-success上传成功回调limit限制上传数量,file-list绑定已上传文件列表auto-upload控制是否自动上传,list-type控制列表样式
- 示例(图片上传 + token):
html
<el-upload
class="avatar-uploader"
action="/api/upload"
:headers="{ Authorization: token }"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
:limit="1"
>
<img v-if="form.avatar" :src="form.avatar" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
1.3.8 el-cascader(级联选择器)
- **用法:**多级联动选择(如省市区、部门层级)
- 注意事项:
options绑定数据源,props配置选项字段(label/value/children)v-model绑定选中值(数组),clearable可清空show-all-levels显示全部层级,filterable可搜索
- 示例(省市区级联):
html
<el-cascader
v-model="form.area"
:options="areaOptions"
:props="{ label: 'name', value: 'code', children: 'children' }"
placeholder="请选择省市区"
clearable
style="width: 100%;"
></el-cascader>
1.4 ElementUI 数据展示类组件
1.4.1 el-table / el-table-column(表格,管理端核心)
- **用法:**数据列表展示,支持分页、排序、筛选、自定义列、行操作
- 注意事项:
data绑定表格数据(必填),border显示边框,stripe斑马纹height固定表头,max-height最大高度,fit自适应宽度@selection-change多选事件,@sort-change排序事件,@filter-change筛选事件el-table-column常用属性:prop(数据字段)、label(列名)、width(宽度)、fixed(固定列)、formatter(自定义格式化)
- 示例(完整管理端表格 + 操作 + 多选):
html
<el-table
:data="tableData"
border
stripe
style="width: 100%;"
@selection-change="handleSelectionChange"
@sort-change="handleSortChange"
>
<!-- 多选列 -->
<el-table-column type="selection" width="55" align="center"></el-table-column>
<!-- 序号列 -->
<el-table-column type="index" label="序号" width="80" align="center"></el-table-column>
<el-table-column prop="username" label="用户名" min-width="120"></el-table-column>
<el-table-column prop="phone" label="手机号" min-width="120"></el-table-column>
<el-table-column prop="deptName" label="所属部门" min-width="120"></el-table-column>
<el-table-column prop="status" label="状态" min-width="80" align="center">
<template slot-scope="scope">
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
{{ scope.row.status === 1 ? '启用' : '禁用' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" min-width="180" sortable="custom"></el-table-column>
<!-- 操作列 -->
<el-table-column label="操作" width="200" align="center" fixed="right">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="handleEdit(scope.row)">编辑</el-button>
<el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination
style="margin-top: 20px; text-align: right;"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNum"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
1.4.2 el-pagination(分页)
- 用法:表格分页,支持页码、每页条数、总数、跳转等
- 注意事项:
layout自定义布局:total(总数)、sizes(每页条数)、prev(上一页)、pager(页码)、next(下一页)、jumper(跳转)@size-change每页条数变化事件,@current-change页码变化事件current-page当前页,page-size每页条数,total总数
- 示例:见
el-table示例
1.4.3 el-tag(标签)
- **用法:**状态标记、标签展示
- 注意事项:
type控制类型:success/warning/info/dangerclosable可关闭,hit描边,color自定义颜色
- **示例:**见
el-table示例
1.4.4 el-badge(徽标数)
- 用法:消息提示、未读计数
- 注意事项:
value计数,max最大值(超过显示max+)is-dot小红点,hidden隐藏
- 示例:
html
<el-badge :value="12" class="item">
<el-button>消息</el-button>
</el-badge>
<el-badge is-dot class="item">
<i class="el-icon-bell"></i>
</el-badge>
1.4.5 el-tree(树形控件)
- 用法:层级数据展示(如菜单、部门、权限)
- 注意事项:
data绑定数据源,props配置字段(label/children/disabled)default-expand-all全部展开,show-checkbox多选@node-click节点点击事件,@check-change选中变化事件
- 示例(菜单树形):
html
<el-tree
:data="menuList"
:props="{ label: 'name', children: 'children' }"
default-expand-all
show-checkbox
@node-click="handleNodeClick"
@check-change="handleCheckChange"
></el-tree>
1.5 ElementUI 反馈类组件
1.5.1 el-dialog(弹窗)
- **用法:**新增 / 编辑 / 详情弹窗,管理端高频使用
- 注意事项:
title标题,visible.sync控制显示 / 隐藏(必须用.sync修饰符)width宽度,fullscreen全屏,modal遮罩层before-close关闭前回调,@close关闭事件
- 示例(编辑弹窗):
html
<el-dialog
title="编辑用户"
:visible.sync="dialogVisible"
width="600px"
:before-close="handleDialogClose"
>
<el-form ref="editForm" :model="editForm" :rules="rules" label-width="120px">
<el-form-item label="用户名" prop="username">
<el-input v-model="editForm.username"></el-input>
</el-form-item>
<!-- 其他表单项 -->
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleEditSubmit">确定</el-button>
</span>
</el-dialog>
1.5.2 el-message(消息提示)
- **用法:**操作成功 / 失败提示,全局方法
- 注意事项:
- 支持
this.$message.success()/error()/warning()/info() duration持续时间(默认 3000ms),center居中,showClose关闭按钮
- 支持
- 示例:
javascript
// 成功提示
this.$message.success('操作成功!')
// 失败提示
this.$message.error('操作失败,请重试!')
// 自定义时长
this.$message({
message: '自定义提示',
type: 'warning',
duration: 5000,
center: true
})
1.5.3 el-message-box(弹框)
- 用法:确认 / 取消弹框(如删除确认)
- 注意事项:
this.$msgbox.confirm()确认框,alert()警告框,prompt()输入框confirmButtonText确认按钮文字,cancelButtonText取消按钮文字type图标类型:success/warning/info/error
- 示例(删除确认):
javascript
this.$msgbox.confirm('确定要删除该用户吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 点击确定,执行删除
return this.$api.user.delete(this.deleteId)
}).then(() => {
this.$message.success('删除成功!')
this.getTableList() // 刷新列表
}).catch(() => {
// 点击取消
this.$message.info('已取消删除')
})
1.5.4 el-notification(通知)
- **用法:**右上角通知提示,用于重要消息
- 注意事项:
this.$notify.success()/error()等,title标题,message内容duration持续时间,position位置(top-right等)
- 示例:
javascript
this.$notify({
title: '系统通知',
message: '您有新的订单待处理',
type: 'warning',
duration: 0, // 不自动关闭
position: 'top-right'
})
1.5.5 el-loading(加载)
- **用法:**页面 / 区域加载中状态
- 注意事项:
- 支持指令
v-loading,服务式调用this.$loading() text加载文字,spinner自定义图标,background背景色
- 支持指令
- 示例:
html
<!-- 指令式 -->
<div v-loading="loading" element-loading-text="加载中..." style="height: 400px;">
表格内容
</div>
javascript
// 服务式(全屏加载)
const loading = this.$loading({
lock: true,
text: '加载中...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
// 关闭加载
loading.close()
2.Script部分
Script 是 Vue 的逻辑层,负责数据定义、方法实现、生命周期、状态管理等,以下是管理端开发全场景常用函数 / API,包含用法、注意事项和示例。
2.1 Vue 实例核心配置
2.1.1 data(数据对象)
- **用法:**定义组件的响应式数据,所有模板中用到的数据都需在此声明
- 注意事项:
- 必须是函数(组件中),返回一个对象(根实例可直接是对象)
- 数据必须提前声明,否则不会响应式
- 避免在
data中存放复杂的非响应式数据(如 DOM 元素、定时器)
- 示例:
javascript
export default {
data() {
return {
// 表单数据
form: {
username: '',
password: '',
status: 1
},
// 表格数据
tableData: [],
// 分页数据
pageNum: 1,
pageSize: 10,
total: 0,
// 弹窗状态
dialogVisible: false,
// 加载状态
loading: false,
// 下拉选项
deptList: []
}
}
}
2.1.2 methods(方法集合)
- **用法:**定义组件的方法,包括事件处理、业务逻辑、工具方法等
- 注意事项:
- 方法中
this指向 Vue 实例,可访问data、computed、props等 - 避免在方法中使用箭头函数(会改变
this指向) - 异步方法需处理错误(
try/catch或.catch())
- 方法中
- 示例:
javascript
export default {
methods: {
// 表单提交
async handleSubmit() {
// 表单验证
const valid = await this.$refs.userForm.validate()
if (!valid) return this.$message.warning('请完善表单信息')
this.loading = true
try {
// 调用接口
await this.$api.user.add(this.form)
this.$message.success('新增成功!')
this.dialogVisible = false
this.getTableList() // 刷新列表
} catch (err) {
this.$message.error('新增失败:' + err.message)
} finally {
this.loading = false
}
},
// 获取表格数据
async getTableList() {
this.loading = true
try {
const res = await this.$api.user.list({
pageNum: this.pageNum,
pageSize: this.pageSize
})
this.tableData = res.data.list
this.total = res.data.total
} catch (err) {
this.$message.error('获取列表失败')
} finally {
this.loading = false
}
},
// 分页变化
handleSizeChange(val) {
this.pageSize = val
this.getTableList()
},
handleCurrentChange(val) {
this.pageNum = val
this.getTableList()
}
}
}
2.1.3 computed(计算属性)
- 用法:基于依赖缓存的计算属性,用于复杂数据计算、数据过滤、状态派生
- 注意事项:
- 必须有返回值,本质是 getter(可设置 setter)
- 依赖的 data 变化时自动重新计算,否则使用缓存(性能优于 methods)
- 不能异步操作,不能修改依赖的数据
- 示例:
javascript
export default {
data() {
return {
list: [],
keyword: ''
}
},
computed: {
// 过滤后的列表(搜索)
filterList() {
return this.list.filter(item =>
item.username.includes(this.keyword) || item.phone.includes(this.keyword)
)
},
// 全选状态
isCheckAll: {
get() {
return this.list.length > 0 && this.list.every(item => item.checked)
},
set(val) {
this.list.forEach(item => item.checked = val)
}
}
}
}
2.1.4 watch(监听器)
- **用法:**监听数据变化,执行回调函数
- 注意事项:
- 支持监听单个数据、多个数据、深度监听(对象 / 数组)
immediate立即执行,deep深度监听- 避免在监听器中修改被监听的数据(造成死循环)
- 示例:
javascript
export default {
data() {
return {
keyword: '',
form: {
username: '',
password: ''
},
pageNum: 1
}
},
watch: {
// 监听单个数据
keyword(newVal, oldVal) {
console.log('搜索关键词变化:', newVal, oldVal)
this.getTableList()
},
// 深度监听对象
form: {
handler(newVal) {
console.log('表单变化:', newVal)
},
deep: true,
immediate: true // 初始化时执行
},
// 监听多个数据(数组形式)
{
this.getTableList()
}
}
}
2.1.5 props(父组件传参)
- 用法:接收父组件传递的数据,实现组件通信
- 注意事项:
- 支持类型校验、默认值、必填校验
- 不要直接修改
props数据(单向数据流),如需修改用data拷贝 - 命名使用驼峰式,模板中使用 kebab-case
- 示例:
javascript
export default {
props: {
// 基础类型+默认值
title: {
type: String,
default: '默认标题'
},
// 必填校验
userId: {
type: Number,
required: true
},
// 对象类型+默认值(必须用函数返回)
form: {
type: Object,
default: () => ({})
},
// 数组类型
list: {
type: Array,
default: () => []
}
}
}
2.1.6 components(组件注册)
- **用法:**注册子组件,在模板中使用
- 注意事项:
- 局部注册:仅在当前组件可用
- 全局注册:在
main.js中Vue.component()注册,所有组件可用
- 示例(局部注册):
javascript
import UserForm from './UserForm.vue'
import TableFilter from './TableFilter.vue'
export default {
components: {
UserForm,
TableFilter
}
}
2.2 Vue 生命周期钩子
- **用法:**组件从创建到销毁的各个阶段执行的函数,用于初始化、资源管理等
- 注意事项:
- 不能使用箭头函数(
this指向问题) - 按顺序执行:
beforeCreate→created→beforeMount→mounted→beforeUpdate→updated→beforeDestroy→destroyed
- 不能使用箭头函数(
- 各钩子用法 + 示例:
javascript
export default {
// 1. 实例创建前,无法访问 data、methods、$el
beforeCreate() {
console.log('beforeCreate:实例创建前')
},
// 2. 实例创建后,可访问 data、methods,未挂载 DOM
created() {
console.log('created:实例创建后')
// 常用:调用接口获取初始数据
this.getTableList()
},
// 3. 挂载前,模板编译完成,未渲染到页面
beforeMount() {
console.log('beforeMount:挂载前')
},
// 4. 挂载后,DOM 已渲染完成,可访问 $el
mounted() {
console.log('mounted:挂载后')
// 常用:操作 DOM、初始化第三方插件(如 ECharts)
this.initChart()
// 监听窗口变化
window.addEventListener('resize', this.handleResize)
},
// 5. 更新前,数据变化后,DOM 更新前
beforeUpdate() {
console.log('beforeUpdate:更新前')
},
// 6. 更新后,DOM 已更新完成
updated() {
console.log('updated:更新后')
},
// 7. 销毁前,组件销毁前执行,用于清理资源
beforeDestroy() {
console.log('beforeDestroy:销毁前')
// 常用:清除定时器、移除事件监听、取消请求
window.removeEventListener('resize', this.handleResize)
clearInterval(this.timer)
},
// 8. 销毁后,组件已销毁
destroyed() {
console.log('destroyed:销毁后')
}
}
2.3 Vue 常用实例方法 / 属性
2.3.1 $refs(获取 DOM / 组件实例)
- 用法:通过
ref属性获取 DOM 元素或子组件实例 - 注意事项:
- 仅在
mounted后才能访问(DOM 未渲染时为undefined) - 用于操作 DOM、调用子组件方法
- 仅在
- 示例:
html
<!-- 模板 -->
<el-form ref="userForm"></el-form>
<div ref="chartContainer"></div>
javascript
// 表单验证
this.$refs.userForm.validate()
// 操作 DOM
this.$refs.chartContainer.style.height = '400px'
// 调用子组件方法
this.$refs.userForm.resetFields()
2.3.2 $emit(子组件向父组件传值)
- 用法:触发自定义事件,向父组件传递数据
- 注意事项:
- 第一个参数是事件名,后续参数是传递的数据
- 父组件通过
@事件名监听
- 示例:
javascript
// 子组件
this.$emit('update:dialogVisible', false)
this.$emit('submitSuccess', data)
html
<!-- 父组件 -->
<UserForm @update:dialogVisible="dialogVisible = $event" @submitSuccess="handleSubmitSuccess"></UserForm>
2.3.3 $on / $off / $emit(事件总线)
- **用法:**全局事件总线,用于兄弟组件、跨层级组件通信
- 注意事项:
- 需在
main.js中挂载:Vue.prototype.$bus = new Vue() - 组件销毁前必须
$off移除监听,避免内存泄漏
- 需在
- 示例:
javascript
// 1. main.js 挂载
Vue.prototype.$bus = new Vue()
// 2. 发送事件(组件A)
this.$bus.$emit('refreshTable', data)
// 3. 监听事件(组件B)
created() {
this.$bus.$on('refreshTable', this.handleRefresh)
},
beforeDestroy() {
this.$bus.$off('refreshTable', this.handleRefresh) // 必须移除
}
2.3.4 $nextTick(DOM 更新后回调)
- **用法:**在下次 DOM 更新循环结束后执行回调,用于获取更新后的 DOM
- 注意事项:
- 数据变化后,DOM 是异步更新的,直接获取 DOM 是旧值
- 常用于:修改数据后操作 DOM、弹窗打开后聚焦输入框
- 示例:
javascript
// 弹窗打开后聚焦输入框
this.dialogVisible = true
this.$nextTick(() => {
this.$refs.usernameInput.focus()
})
// 修改表格数据后获取最新高度
this.tableData = newData
this.$nextTick(() => {
console.log(this.$refs.table.$el.offsetHeight)
})
2.3.5 $set / $delete(响应式数据操作)
- 用法:向响应式对象添加 / 删除属性,确保视图更新
- 注意事项:
- Vue 无法检测对象属性的添加 / 删除、数组下标修改,需用
$set/$delete $set(target, key, value),$delete(target, key)
- Vue 无法检测对象属性的添加 / 删除、数组下标修改,需用
- 示例:
javascript
// 错误写法:直接添加属性,不会响应式
this.form.newProp = 'value'
// 正确写法:$set
this.$set(this.form, 'newProp', 'value')
// 数组下标修改
this.$set(this.list, 0, newItem)
// 删除属性
this.$delete(this.form, 'oldProp')
2.3.6 $router / $route(路由相关)
- 用法:路由跳转、路由参数获取
- 注意事项:
$router是路由实例,用于跳转、后退等$route是当前路由信息,包含params/query/path等
- 示例:
javascript
// 路由跳转(编程式导航)
this.$router.push('/user/list')
this.$router.push({ path: '/user/detail', query: { id: 1 } })
this.$router.push({ name: 'UserDetail', params: { id: 1 } })
// 后退
this.$router.go(-1)
// 获取路由参数
const id = this.$route.query.id
const id = this.$route.params.id
2.4 管理端常用工具函数
2.4.1 日期格式化
javascript
/**
* 日期格式化
* @param {Date|string|number} date 日期
* @param {string} fmt 格式(yyyy-MM-dd HH:mm:ss)
* @returns {string} 格式化后的日期
*/
export function formatDate(date, fmt = 'yyyy-MM-dd HH:mm:ss') {
if (!date) return ''
const d = new Date(date)
const o = {
'M+': d.getMonth() + 1,
'd+': d.getDate(),
'H+': d.getHours(),
'm+': d.getMinutes(),
's+': d.getSeconds(),
'q+': Math.floor((d.getMonth() + 3) / 3),
'S': d.getMilliseconds()
}
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (d.getFullYear() + '').substr(4 - RegExp.$1.length))
}
for (const k in o) {
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
}
}
return fmt
}
2.4.2 表单验证规则(常用)
javascript
// 手机号验证
export const phoneRule = [
{ required: true, message: '请输入手机号', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
]
// 密码验证(6-20位字母+数字)
export const passwordRule = [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, max: 20, message: '密码长度6-20位', trigger: 'blur' },
{ pattern: /^(?=.*[a-zA-Z])(?=.*\d).+$/, message: '密码必须包含字母和数字', trigger: 'blur' }
]
// 身份证验证
export const idCardRule = [
{ required: true, message: '请输入身份证号', trigger: 'blur' },
{ pattern: /(^\d{18}$)|(^\d{17}(\d|X|x)$)/, message: '请输入正确的身份证号', trigger: 'blur' }
]
2.4.3 深拷贝
javascript
/**
* 深拷贝
* @param {*} obj 要拷贝的对象
* @returns {*} 拷贝后的对象
*/
export function deepClone(obj) {
if (obj === null || typeof obj !== 'object') return obj
if (obj instanceof Date) return new Date(obj)
if (obj instanceof Array) return obj.map(item => deepClone(item))
if (obj instanceof Object) {
const newObj = {}
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = deepClone(obj[key])
}
}
return newObj
}
}
3.Style部分
Style 是 Vue 的样式层,负责页面样式、布局美化,以下是管理端开发常用样式写法、scoped 用法、注意事项和示例。
3.1 scoped 样式作用域
- 用法:给
<style>添加scoped属性,样式仅作用于当前组件 - 原理:Vue 会给组件内所有元素添加唯一的
data-v-xxx属性,通过属性选择器实现样式隔离 - 注意事项:
- 父组件样式不会渗透到子组件,子组件的根元素会继承父组件的
scoped样式 - 如需修改子组件样式,需用
::v-deep(深度选择器,Vue2 中/deep/也可,推荐::v-deep) - 全局样式不要加
scoped,放在App.vue或单独的 CSS 文件中
- 父组件样式不会渗透到子组件,子组件的根元素会继承父组件的
- 示例:
css
<style scoped>
/* 当前组件样式,仅作用于本组件 */
.container {
padding: 20px;
}
/* 修改子组件样式(深度选择器) */
::v-deep .el-input__inner {
border-radius: 4px;
}
::v-deep .el-table th {
background-color: #f5f7fa;
}
</style>
<!-- 全局样式 -->
<style>
/* 全局重置样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;
-webkit-font-smoothing: antialiased;
}
</style>
3.2 管理端常用样式规范
3.2.1 布局样式
css
/* 页面容器 */
.page-container {
padding: 20px;
background-color: #f5f7fa;
min-height: calc(100vh - 84px); /* 减去顶栏高度 */
}
/* 搜索栏样式 */
.search-bar {
background-color: #fff;
padding: 20px;
margin-bottom: 20px;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
/* 表格容器 */
.table-container {
background-color: #fff;
padding: 20px;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
3.2.2 ElementUI 样式覆盖(常用)
css
/* 全局修改ElementUI主题色 */
:root {
--el-color-primary: #409eff; /* 主色 */
--el-color-success: #67c23a; /* 成功色 */
--el-color-warning: #e6a23c; /* 警告色 */
--el-color-danger: #f56c6c; /* 危险色 */
--el-color-info: #909399; /* 信息色 */
}
/* 表格样式优化 */
::v-deep .el-table {
font-size: 14px;
}
::v-deep .el-table th {
background-color: #f5f7fa;
color: #606266;
font-weight: 500;
}
::v-deep .el-table td, .el-table th {
padding: 12px 0;
}
/* 按钮样式优化 */
::v-deep .el-button {
border-radius: 4px;
}
/* 弹窗样式优化 */
::v-deep .el-dialog {
border-radius: 8px;
}
::v-deep .el-dialog__header {
padding: 20px 20px 0 20px;
}
::v-deep .el-dialog__body {
padding: 20px;
}
::v-deep .el-dialog__footer {
padding: 0 20px 20px 20px;
}
3.2.3 响应式样式
css
/* 适配移动端/小屏 */
@media screen and (max-width: 768px) {
.page-container {
padding: 10px;
}
.search-bar {
padding: 10px;
}
/* 表格横向滚动 */
.table-container {
overflow-x: auto;
}
/* 隐藏侧边栏 */
.el-aside {
display: none;
}
}
3.3 样式注意事项
- 样式隔离:组件样式必须加
scoped,避免全局污染,全局样式统一放在App.vue或assets/css/global.css - 深度选择器:修改 ElementUI 组件样式必须用
::v-deep,否则无法生效 - 避免内联样式:尽量用 CSS 类,避免在模板中写大量
:style - 性能优化:避免使用通配符选择器、深层嵌套选择器,减少样式计算时间
- 主题统一:管理端需统一主题色、字体、间距,可通过 CSS 变量全局管理
- 浮动清除:使用
clearfix类清除浮动,避免布局错乱
css
.clearfix::after {
content: '';
display: block;
clear: both;
visibility: hidden;
height: 0;
}
八、样例代码解析
九、前后端联调流程
十、Axios拦截与请求报文组装
十一、管理端(前端)后台服务解析
十二、管理端(前端)数据库解析
十三、管理端(前端)项目部署服务器
1.安装Linux可视化命令工具
个人推荐使用MobaXterm,界面整洁美观,方便拖拽文件

2.点击左上角Session连接服务器

3. 输入登录密码

登录成功 ↓

4.前端项目打包dist文件





5.将dist文件放到nginx/html目录里



6.重启nginx服务

没有任何提示则重启成功...
十四、Nginx代理转发配置




十五、
十六、浏览器访问
十七、总结
