自顶向下Web开发-1 前端部分-5 前端工程化

0 前后端分离开发

0.1 接口文档管理平台:Yapi

Yapi的两个主要功能:

  • API接口管理
  • Mock服务(生成接口的模拟测试数据)

使用:

  • 添加项目
  • 添加分类
  • 添加接口

示例:

1 前端工程化:

指在企业级的前端项目开发中,把前端开发所需的工具、技术、流程、经验等进行规范化、标准化。

  • 模块化:JS、CSS
  • 组件化:UI结构、样式、行为
  • 规范化:目录结构、编码、接口
  • 自动化:构建、部署、测试

1.1 环境准备(Vue-cli):

  • 介绍:Vue-cli是Vue官方提供的一个脚手架,用于快速生成一个Vue项目模板。
  • 功能:
    • 统一的目录结构
    • 本地测试
    • 热部署
    • 单元测试
    • 集成打包上线
  • 依赖环境:Node.js

具体步骤直接参考:Day03-04. 前端工程化-环境准备_哔哩哔哩_bilibili

此处npm下载镜像站:npmmirror 镜像站

1.2 Vue项目简介:

创建:

在目标文件夹内打开cmd,输入:

  • 命令行:vue create vue-project01
  • 图形化界面:vue ui

创建过程详情参考:Day03-05. 前端工程化-Vue项目_哔哩哔哩_bilibili

Vue项目-目录结构:

Vue项目-运行:

Vue项目-配置端口(默认8080):

在vue.config.js文件中修改:

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  // 配置端口
  devServer:{
    port:7000,
  }
})

1.3 Vue项目开发流程:

开发项目:

  • 在开发项目过程中,您主要会编辑src目录中的Vue文件(.vue文件),这些文件包含了项目的组件、路由、样式等内容。
  • 您还需编辑src目录中的App.vue文件,这是项目的根组件。
  • 修改src目录中的main.js文件来初始化Vue应用程序。
  • 如果需要引入外部库或插件,可以在src目录中的main.js文件中进行配置。

  • 默认首页:index.html
  • 默认首页index默认引入 入口文件: main.js ,如下:
import Vue from 'vue'
import App from './App.vue'
import router from './router'

Vue.config.productionTip = false

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')
  • 此处 import 代表引入模块
  • 对应 export 将对象或函数导出为模块

下面创建Vue对象相当于之前的:

new Vue({
  el:'#app',//index中的id=app
  router:router,//路由 
  render:h=>h(App)// 将上面导入的app视图创建出对应的虚拟DOM元素,挂载到上面的#app
})
  • Vue的组件文件以 .vue 结尾,每个组件由三个部分组成:
    • <template>:模板部分:定义HTML代码.一个<template>必须有且只能有一个div
    • <script>:主要控制模板中的数据来源和行为
    • <style>:CSS样式

示例:

App.vue:

此处data中function是一个匿名函数,可以简写如下:

<template>
<!-- 在一个.vue文件中只能有一个Vue实例对象,通常不需要为<template>中的<div>绑定ID -->
  <div>
    {{message}}
  </div>
</template>

<script>
export default {
  //这里的data与之前的data:XXX 数据模型不一样,export出去的是函数,所以这样写:
  data:function() {
    return {
      message:"Hello Vue!"
    }
  },
/*
也可简写为:
data() {
    return {
      message:"Hello Vue!"
    }
  },
*/
  methods: {
    
  }
}

</script>

<style>

</style>

进行Vue工程开发,很少去操作 index.html 与 main.js ,主要操作组件,即.vue文件

2 Vue组件库Element

2.0 介绍:

  • Element:是饿了么团队研发的,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库;
  • 组件:组成网页的部件,例如 超链接、按钮、图片、表格、表单、分页条等等。

2.1 快速入门

  • 安装ElementUI组件库(在当前工程的目录下),在命令行执行指令:
npm install element-ui@2.51.3
  • 在main.js中引入Element组件库
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);
  • 定义组件文件,访问官网,复制组件代码,调整

这里将其他组件放在views/element 下

ElementView.vue:

<template>
    <el-row>
        <el-button round>圆角按钮</el-button>
        <el-button type="primary" round>主要按钮</el-button>
        <el-button type="success" round>成功按钮</el-button>
        <el-button type="info" round>信息按钮</el-button>
        <el-button type="warning" round>警告按钮</el-button>
        <el-button type="danger" round>危险按钮</el-button>
    </el-row>
</template>

<script>
export default {
    
}
</script>

<style>

</style>

修改后的App.vue:

重要:

  • components 的作用是将名为 ElementView 的组件注册为当前组件的子组件。
  • <element-view></element-view>组件是当你引入ElementView这个自定义组件并在components中注册后,Vue自动生成的标签,至于中间的 – ,是因为HTML并不分大小写,Vue自己将<ElementView>转换为<element-view>。如果是Component1组件,就通过<component1></component1>使用组件。
<template>
  <div>
    <!-- 在根组件当中引用其他组件: -->
    <element-view></element-view>
  </div>
</template>

<script>
import ElementView from './views/element/ElementView.vue'
export default {
//子组件必须在 components : 中注册
  components: { ElementView },
  
  data:function() {
    return {
      message:"Hello Vue!"
    }
  },
  methods: {
    
  }
}

</script>

<style>

</style>

2.2.1 常用组件-Table表格:

具体操作同上,注意<template> 与<script>内的内容都要复制。

ElementView.vue:

<template>
  <div>
    <el-row>
      <!-- button  按钮 -->
      <el-button round>圆角按钮</el-button>
      <el-button type="primary" round>主要按钮</el-button>
      <el-button type="success" round>成功按钮</el-button>
      <el-button type="info" round>信息按钮</el-button>
      <el-button type="warning" round>警告按钮</el-button>
      <el-button type="danger" round>危险按钮</el-button>
    </el-row>
    <br />
    <!-- table 表格 -->
    <el-table :data="tableData" border="true" style="width: 100%">
      <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>
    <br />
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData: [
        {
          date: "2016-05-02",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1518 弄",
        },
        {
          date: "2016-05-04",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1517 弄",
        },
        {
          date: "2016-05-01",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1519 弄",
        },
        {
          date: "2016-05-03",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1516 弄",
        },
      ],
    };
  },
  methods: {
  }
};
</script>

<style>
</style>

2.2.2 常用组件-Pagination 分页:

本小结引入了vue组件事件的概念,事件的函数使用了一个新概念:回调参数

如:

methods: {
    handleSizeChange(val){
        alert(val);
    },
    handleCurrentChange(val){
        alert(val); 
    }
  }

methods中的这两个val。

在此处我简单理解为当 在<el-Paginatiion> 中使用事件@size-change=”handleSizeChange”指定函数为handleSizeChange时,Vue变自动的为handleSizeChange()添加了一个参数(参数内容详见Element中该组件的官方文档),而在methods中想使用这个参数,任意的在参数表内写一个变量接收变可以使用这个参数。

<template>
  <div>
    <el-row>
      <!-- button  按钮 -->
      <el-button round>圆角按钮</el-button>
      <el-button type="primary" round>主要按钮</el-button>
      <el-button type="success" round>成功按钮</el-button>
      <el-button type="info" round>信息按钮</el-button>
      <el-button type="warning" round>警告按钮</el-button>
      <el-button type="danger" round>危险按钮</el-button>
    </el-row>
    <br />
    <!-- table 表格 -->
    <el-table :data="tableData" border="true" style="width: 100%">
      <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>
    <br />
    <!-- pagunation 分页 -->
    <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" background layout="prev, pager, next,jumper" :total="1000" ></el-pagination>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData: [
        {
          date: "2016-05-02",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1518 弄",
        },
        {
          date: "2016-05-04",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1517 弄",
        },
        {
          date: "2016-05-01",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1519 弄",
        },
        {
          date: "2016-05-03",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1516 弄",
        },
      ],
    };
  },
  methods: {
    handleSizeChange(val){
        alert(val);
    },
    handleCurrentChange(val){
        alert(val); 
    }
  }
};
</script>

<style>
</style>

2.2.3 常用组件-Dialog 对话框:

在保留当前页面信息的情况下,告知用户并承载相关操作。

<template>
  <div>
      <el-button type="text" @click="dialogTableVisible = true">打开嵌套表格的 Dialog</el-button>

      <el-dialog title="收货地址" :visible.sync="dialogTableVisible">
        <el-table :data="gridData">
          <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>

  </div>
</template>

<script>
export default {
  data() {
    return {
      gridData: [{
          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
    };
  },
  methods: {
    
  }
};
</script>

<style>
</style>

此处Vue帮你做的事有很多,感觉有点过于智能了,比如:

当你关闭对话框后,dialogTableVisible 将会变成 false。这是因为在模板中,对话框的可见性是通过 :visible.sync="dialogTableVisible" 进行控制的,.sync 修饰符确保了 dialogTableVisible 的变化会同步更新到对话框的可见性。虽然确实没有直接看到对 dialogTableVisible 的值进行修改的代码,但是在 Vue.js 中,<el-dialog> 组件的 :visible.sync 属性会创建一个名为 update:visible 的事件监听器,以便在对话框的可见性发生变化时更新 dialogTableVisible 的值。简而言之,dialogTableVisible 的值会在对话框的可见性发生变化时自动更新。所以,当你关闭对话框时,Vue.js 会自动将 dialogTableVisible 的值设置为 false

2.2.4 常用组件-Form 表单:

由输入框、选择器、点选框、多选框、等控件构成,用以收集、校验、提交数据。

<template>
  <div>
    <el-button type="text" @click="dialogFormVisible = true"
      >打开Form表单的Dialog</el-button
    >

    <el-dialog title="活动申请表单" :visible.sync="dialogFormVisible">
      <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>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dialogFormVisible: false,
      form: {
          name: '',
          region: '',
          date1: '',
          date2: '',
          delivery: false,
          type: [],
          resource: '',
          desc: ''
        }
    };
  },
  methods: {
    onSubmit() {
        alert(JSON.stringify(this.form));
    }
  }
};
</script>

<style>
</style>

2.3 综合案例:

实现员工管理页面开发,并通过Axois实现异步数据加载。

1 创建EmpView.vue组件,并在App.vue根组件中引入:

App.vue:

<template>
    <emp-view></emp-view>
</template>

<script>
import EmpView from './views/EmpView.vue';
export default {
  components: { EmpView },

  data: function () {
    return {
      
    };
  },
  methods: {},
};
</script>

<style>
</style>

2 实现基本页面布局:

使用Container 布局容器。

3 实现各个组件:

EmpView.vue:

<template>
  <el-container style="height: 500px; border: 1px solid #eee">
    <el-header>Element管理系统</el-header>
    <el-container>
      <el-aside width="200px">
        <el-menu>
          <el-submenu index="1">
            <template slot="title">
              <i class="el-icon-message"></i>系统信息管理</template
            >
            <el-menu-item-group>
              <el-menu-item index="1-1">部门管理</el-menu-item>
              <el-menu-item index="1-2">员工管理</el-menu-item>
            </el-menu-item-group>
          </el-submenu>
        </el-menu>
      </el-aside>
      <el-container>
        <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>&nbsp;&nbsp;&nbsp;

            <el-form-item label="性别">
              <el-select v-model="searchForm.gender" placeholder="性别">
                <el-option label="男" value="1"></el-option>
                <el-option label="女" value="2"></el-option>
              </el-select>
            </el-form-item>&nbsp;&nbsp;&nbsp;

            

            <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>&nbsp;&nbsp;&nbsp;
           

            <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"
            ></el-table-column>
            <el-table-column
              prop="gender"
              label="性别"
              width="140"
            ></el-table-column>
            <el-table-column
              prop="job"
              label="职位"
              width="140"
            ></el-table-column>
            <el-table-column
              prop="entrydate"
              label="入职日期"
              width="180"
            ></el-table-column>
            <el-table-column
              prop="updatetime"
              label="最后操作时间"
              width="230"
            ></el-table-column>
            <el-table-column label="操作">
              <el-button type="primary" size="mini">编辑</el-button>
              <el-button type="danger" size="mini">删除</el-button>
            </el-table-column>
          </el-table>

          <!-- 分页条 -->
          <center>
          <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" background layout="prev, pager, next,jumper" :total="1000" ></el-pagination>
          </center>
          
        </el-main>
      </el-container>
    </el-container>
    <el-footer>Footer</el-footer>
  </el-container>
</template>

<script>
export default {
  data() {
    return {
      tableData: [],
      searchForm: {
        name: " ",
        gender: "",
        entrydate:[],
      },
    };
  },
  methods: {
    onSubmit: function () {
      alert("查询数据!");
    },
    handleSizeChange(val){
        alert(val);
    },
    handleCurrentChange(val){
        alert(val); 
    },
  },
};
</script>

<style>
.el-header {
  background-color: #b3c0d1;
  color: #333;
  text-align: center;
  font-size: 40px;
  line-height: 60px;
}

.el-footer {
  background-color: #b3c0d1;
  color: #333;
  text-align: center;
  font-size: 10px;
  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>

4 列表项目的异步加载,并渲染展示:

mock:https://mock.apifox.cn/m1/3128855-0-default/emp/list

注意这里图像和性别在表格中的处理方式:

<template slot-scope="scope">的使用

EmpView.vue:

<template>
  <el-container style="height: 500px; border: 1px solid #eee">
    <el-header>Element管理系统</el-header>
    <el-container>
      <el-aside width="200px">
        <el-menu>
          <el-submenu index="1">
            <template slot="title">
              <i class="el-icon-message"></i>系统信息管理</template
            >
            <el-menu-item-group>
              <el-menu-item index="1-1">部门管理</el-menu-item>
              <el-menu-item index="1-2">员工管理</el-menu-item>
            </el-menu-item-group>
          </el-submenu>
        </el-menu>
      </el-aside>
      <el-container>
        <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
            >&nbsp;&nbsp;&nbsp;

            <el-form-item label="性别">
              <el-select v-model="searchForm.gender" placeholder="性别">
                <el-option label="男" value="1"></el-option>
                <el-option label="女" value="2"></el-option>
              </el-select> </el-form-item
            >&nbsp;&nbsp;&nbsp;

            <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
            >&nbsp;&nbsp;&nbsp;

            <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
              label="图像"
              width="180"
            >
              <template slot-scope="scope">
                <img :src="scope.row.image" height="100px">
              </template>
            </el-table-column>

          

            <!-- <el-table-column
              prop="gender"
              label="性别"
              width="140"
            ></el-table-column> -->

            <!-- <el-table-column
             v-if="tableData.gender==1"
              prop="gender"
              label="性别"
              width="140"
            >男</el-table-column>

            <el-table-column
             v-else-if="tableData.gender==2"
              prop="gender"
              label="性别"
              width="140"
            >女</el-table-column> -->

            <el-table-column prop="gender" 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="180"
            ></el-table-column>
            <el-table-column
              prop="updatetime"
              label="最后操作时间"
              width="230"
            ></el-table-column>
            <el-table-column label="操作">
              <el-button type="primary" size="mini">编辑</el-button>
              <el-button type="danger" size="mini">删除</el-button>
            </el-table-column>
          </el-table>

          <!-- 分页条 -->
          <center>
            <el-pagination
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
              background
              layout="prev, pager, next,jumper"
              :total="1000"
            ></el-pagination>
          </center>
        </el-main>
      </el-container>
    </el-container>
    <el-footer>Footer</el-footer>
  </el-container>
</template>

<script>
import axios from "axios";

export default {
  data() {
    return {
      tableData: [],
      searchForm: {
        name: " ",
        gender: "",
        entrydate: [],
      },
    };
  },
  methods: {
    onSubmit: function () {
      alert("查询数据!");
    },
    handleSizeChange(val) {
      alert(val);
    },
    handleCurrentChange(val) {
      alert(val);
    },
  },
  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;
  font-size: 40px;
  line-height: 60px;
}

.el-footer {
  background-color: #b3c0d1;
  color: #333;
  text-align: center;
  font-size: 10px;
  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>

最终效果如下:

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇