一.前后端分离开发
前后端混合开发
缺点:沟通成本高,分工不明确,不便管理,不便维护拓展
前后端分离开发
当前最为主流的开发模式:前后端分离
前后端分离开发中很重要的是API接口文档(如:YApi:YApi是高效、易用、功能强大的api管理平台,旨在为开发、产品、测试人员提供更优雅的接口管理服务)
二.前端工程化
前端工程化:是指在企业级的前端项目开发中,把前端开发所需的工具、技术、流程、经验等进行规范化、标准化(模块化(JS、CSS)、组件化(UI结构、样式、行为)、规范化(目录结构、编码、接口)、自动化(构建、部署、测试))
2.1 环境准备
vue-cli
· 介绍:vue-cli是Vue官方提供的一个脚手架,用于快速生成一个Vue的项目模板
· Vue-cli提供了如下功能:
· 统一的目录结构
· 本地调试
· 热部署(代码变动不需要再次运行)
· 单元测试
· 集成打包上线
· 依赖环境:NodeJS
安装NodeJS和vue-cli,我参考的是下面这篇博客:
Vue脚手架的安装(超详细篇,保姆级教程)_vue脚手架安装-CSDN博客
2.2 Vue项目简介
2.2.1 Vue项目 - 创建
· 命令行: vue create vue-project01
· 图形化界面:vue ui
创建过程参考:Day03-05. 前端工程化-Vue项目_哔哩哔哩_bilibili
2.2.2 Vue项目 - 目录结构
基于Vue脚手架创建出来的工程,有标准的目录结构,如下:
2.2.3 Vue项目-启动
vscode如果里面没有NPM脚本的话,右键项目文件夹,勾选npm脚本
2.2.4 Vue项目-配置端口
2.3 Vue项目开发流程
三.Vue组件库Element
Element:是饿了么团队研发的一套为开发者、设计师和产品经理准备的基于Vue2.0的桌面端组件库
组件:组成网页的部件,例如超链接、按钮、图片、表格、表单、分页条等等
官网:Element - The world's most popular Vue UI framework
3.1 快速入门
· 安装ElementUI组件库(在当前工程的目录下),在命令行执行指令:
· 引入ElementUI组件库
· 访问官网,复制组件代码,调整
3.2 常见组件
3.2.1 常见组件-表格
Table表格:用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作
3.2.2 常见组件-分页
Pagination分页:当数据量过多时,使用分页分解数据
3.2.3 常见组件-对话框
Dialog对话框:在保留当前页面状态的情况下,告知用户并承载相关操作
3.2.4 常见组件-表单
Form表单:由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据
<!-- src/views/element/ElementView.vue -->
<template>
<!-- 格式化快捷键:shift + alt + f -->
<!-- 学会从官网粘贴想要的组件 -->
<div>
<!-- button按钮 -->
<el-row>
<el-button>默认按钮</el-button>
<el-button type="primary">主要按钮</el-button>
<el-button type="success">成功按钮</el-button>
<el-button type="info">信息按钮</el-button>
<el-button type="warning">警告按钮</el-button>
<el-button type="danger">危险按钮</el-button>
</el-row>
<!-- button按钮 -->
<br>
<!-- Table表格 -->
<el-table :data="tableData" style="width: 100%" :row-class-name="tableRowClassName">
<el-table-column prop="date" label="日期" width="180"></el-table-column>
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="address" label="地址"></el-table-column>
</el-table>
<!-- Table表格 -->
<br>
<!-- Pagination分页 -->
<el-pagination background layout="sizes, prev, pager, next, jumper, ->, total" @size-change="handleSizeChange"
@current-change="handleCurrentChange" :total="1000"></el-pagination>
<!-- Pagination分页 -->
<br>
<!-- Dialog对话框 -->
<!-- Table -->
<el-button type="text" @click="dialogTableVisible = true">打开嵌套表格的 Dialog</el-button>
<el-dialog title="收货地址" :visible.sync="dialogTableVisible"> <!--dialogTableVisible默认是false,点击的时候变成true -->
<el-table :data="tableData">
<el-table-column property="date" label="日期" width="150"></el-table-column>
<el-table-column property="name" label="姓名" width="200"></el-table-column>
<el-table-column property="address" label="地址"></el-table-column>
</el-table>
</el-dialog>
<!-- Form -->
<el-button type="text" @click="dialogFormVisible = true">打开嵌套表单的 Dialog</el-button>
<el-dialog title="收货地址" :visible.sync="dialogFormVisible">
<!-- Form表单 -->
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间">
<el-col :span="11">
<el-date-picker type="date" placeholder="选择日期" v-model="form.date1"
style="width: 100%;"></el-date-picker>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker>
</el-col>
</el-form-item>
<el-form-item label="即时配送">
<el-switch v-model="form.delivery"></el-switch>
</el-form-item>
<el-form-item label="活动性质">
<el-checkbox-group v-model="form.type">
<el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下主题活动" name="type"></el-checkbox>
<el-checkbox label="单纯品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="特殊资源">
<el-radio-group v-model="form.resource">
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="活动形式">
<el-input type="textarea" v-model="form.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">提交</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
<!-- Form表单 -->
</el-dialog>
<!-- Dialog对话框 -->
<br>
</div>
</template>
<script>
export default {
methods: {
tableRowClassName({ rowIndex }) {
if (rowIndex === 1) {
return 'warning-row';
} else if (rowIndex === 3) {
return 'success-row';
}
return '';
},
handleSizeChange(val) {
alert(`每页 ${val} 条`);
},
handleCurrentChange(val) {
alert(`当前页: ${val}`);
},
onSubmit() {
alert('submit!');
alert(JSON.stringify(this.form));
}
},
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄',
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄',
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}],
dialogTableVisible: false,
dialogFormVisible: false,
form: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
},
formLabelWidth: '120px'
}
},
}
</script>
<style>
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
<!-- src/App.vue -->
<template>
<div>
<!-- <h1>{{message}}</h1> -->
<element-view></element-view>
</div>
</template>
<script>
import ElementView from './views/element/ElementView.vue'
export default {
components: { ElementView },
data(){
return{
message: "Hello Vue"
}
},
methods: {
},
}
</script>
<style>
</style>
3.3 案例
<!-- src\views\tlias\EmpView.vue -->
<template>
<div>
<el-container style="height: 500px; border: 1px solid #eee">
<el-header> tlias 智能学习辅助系统</el-header>
<el-container>
<el-aside width="200px" style="background-color: rgb(238, 241, 246)">
<el-menu :default-openeds="['1', '3']">
<el-submenu index="1">
<template slot="title"><i class="el-icon-message"></i>系统信息管理</template>
<el-menu-item index="1-1">部门管理</el-menu-item>
<el-menu-item index="1-2">员工管理</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
<el-main>
<!-- 表单 -->
<el-form :inline="true" :model="searchForm" class="demo-form-inline">
<el-form-item label="姓名">
<el-input v-model="searchForm.name" placeholder="姓名"></el-input>
</el-form-item>
<el-form-item label="性别">
<el-select v-model="searchForm.sex" placeholder="性别">
<el-option label="男" value="1"></el-option>
<el-option label="女" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="入职时间">
<!-- 日期选择器 -->
<el-date-picker v-model="searchForm.entryDate" type="daterange" range-separator="至"
start-placeholder="开始日期" end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
</el-form>
<el-table :data="tableData" border>
<el-table-column prop="name" label="姓名" width="180">
</el-table-column>
<el-table-column prop="image" label="图像" width="180">
<template slot-scope="scope">
<img :src="scope.row.image" width="100px" height="100px">
</template>
</el-table-column>
<el-table-column label="性别" width="140">
<template slot-scope="scope">
{{ scope.row.gender == 1 ? "男" : "女" }}
</template>
</el-table-column>
<el-table-column prop="job" label="职位" width="140">
</el-table-column>
<el-table-column prop="entrydate" label="入职日期" width="140">
</el-table-column>
<el-table-column prop="updatetime" label="最后操作时间" width="140">
</el-table-column>
<el-table-column label="操作" width="140">
<template>
<el-button type="text" size="small">查看</el-button>
<el-button type="text" size="small">编辑</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页条 -->
<el-pagination background layout="sizes, prev, pager, next, jumper, ->, total"
@size-change="handleSizeChange" @current-change="handleCurrentChange"
:total="1000"></el-pagination>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
tableData: [], // https://mock.apifox.cn/m1/3128855-0-default/emp/list
searchForm: {
name: "",
gender: "",
entryDate: []
}
}
},
methods: {
handleSizeChange(val) {
alert(`每页 ${val} 条`);
},
handleCurrentChange(val) {
alert(`当前页: ${val}`);
},
onSubmit() {
alert('submit!');
}
},
mounted() {
//发送异步请求
axios.get("https://mock.apifox.cn/m1/3128855-0-default/emp/list").then((result) => {
this.tableData = result.data.data;
});
}
}
</script>
<style>
.el-header {
background-color: #B3C0D1;
color: #333;
text-align: center;
line-height: 60px;
}
.el-aside {
background-color: #D3DCE6;
color: #333;
text-align: center;
line-height: 200px;
}
.el-main {
background-color: #E9EEF3;
/* color: #333;
text-align: center;
line-height: 160px; */
}
</style>
<!-- src/App.vue -->
<template>
<div>
<!-- <h1>{{message}}</h1> -->
<!-- <element-view></element-view> -->
<!-- 员工管理 -->
<emp-view></emp-view>
</div>
</template>
<script>
import EmpView from './views/tlias/EmpView.vue'
// import ElementView from './views/element/ElementView.vue'
export default {
components: { EmpView },
// components: { ElementView },
data(){
return{
message: "Hello Vue"
}
},
methods: {
},
}
</script>
<style>
</style>
四.Vue路由
前端路由:URL中的hash(#号)与组件之间的对应关系
Vue Router
· 介绍:Vue Router是Vue的官方路由
· 组成:
· VueRouter:路由器类,根据路由请求在路由视图中动态渲染选中的组件
· <router-link>:请求链接组件,浏览器会解析成<a>
· <router-view>:动态视图组件,用来渲染展示与路由路径对应的组件
Vue路由
· 安装(创建Vue项目时已经选择):npm install vue-router@3.5.1
· 定义路由
在index.js中定义路由,将页面中需要设置跳转的地方使用<router-link>,在App.vue中添加<router-view>
五.打包部署
5.1 打包
5.2 nginx
介绍:Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少,并发能力强,在各大型互联网公司都有非常广泛的应用
官网:nginx news
5.3 部署
部署后访问:http://localhost.更改后的端口号