JavaWeb - 5 - 前端工程化

一.前后端分离开发

前后端混合开发

缺点:沟通成本高,分工不明确,不便管理,不便维护拓展

前后端分离开发

当前最为主流的开发模式:前后端分离

前后端分离开发中很重要的是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表单:由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据

html 复制代码
<!-- 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 案例

html 复制代码
<!-- 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.更改后的端口号

相关推荐
蜡台34 分钟前
Node 安装 awesome-qr 失败解决
javascript·vue·qrcode·awesome-qr
格子软件1 小时前
2026年GEO优化系统源码级状态机与多模型调度拆解
java·前端·vue.js·人工智能·vue·geo
HUMHSX2 小时前
Vue 项目启动全流程解析:从入口文件到全局指令注册与页面渲染
前端·javascript·vue.js
有颜有货2 小时前
PMC生产排产的4种算法,一次讲清
java·服务器·前端
小虎牙0072 小时前
Android kotlin图片库Coil源码详解
android·前端
随风一样自由2 小时前
【前端领域】前端开发核心应用场景与落地实践
前端·前端框架
an317423 小时前
弹窗数据流设计的两种高阶架构实践
前端·vue.js·架构
谢尔登3 小时前
【React】 状态管理方案
前端·react.js·前端框架
用户2136610035723 小时前
Vue商品详情与放大镜组件
前端·javascript
半个落月3 小时前
从Tapas小Demo理清localStorage、事件与this
前端·javascript