前後端分離

什麼是前後端分離模式

是web應用的一種架構模式。在開發階段,前後端工程師約定好數據交互接口,實現並行開發和測試;在運行階段前後端分離模式需要對web應用進行分離部署,前後端之前使用HTTP或者其他協議進行交互請求。

從四個方面理解前後端分離
交互模式不一樣

在前後端分離架構中,後端只需要負責按照約定的數據格式向前端提供可調用的API服務即可。前後端之間通過HTTP請求進行交互,前端獲取到數據後,進行頁面的組裝和渲染,頁面跳轉,最終返回給瀏覽器。

elementui 前端鏡像_#vue

代碼的組織形式不一樣

在傳統架構模式中,前後端代碼存放於同一個代碼庫中,甚至是同一工程目錄下。頁面中還夾雜着後端代碼。前後端工程師進行開發時,都必須把整個項目導入到開發工具中。而前後端分離模式在代碼組織形式上有以下兩種:

半分離

前後端共用一個代碼庫,但是代碼分別存放在兩個工程中。後端不關心或很少 關心前端元素的輸出情況,前端不能獨立進行開發和測試,項目中缺乏前後端 交互的測試用例。

真分離

前後端代碼庫分離,前端代碼中有可以進行Mock測試(通過構造虛擬測試對 象以簡化測試環境的方法)的偽後端,能支持前端的獨立開發和測試。而後端 代碼中除了功能實現外,還有着詳細的測試用例,以保證API的可用性,降低 集成風險。

elementui 前端鏡像_elementui 前端鏡像_02

開發模式不一樣

elementui 前端鏡像_#java_03

部署方式也不一樣

elementui 前端鏡像_#js_04

總結

前後端分離是一種架構模式,前後端人員先預定好接口,並行開發與測試.上線時進行分別部署.對開發人員能力要求高.對於小型公司或剛轉型前後端分離模式公司,開發人員能力有限,採用是後端先行前後端分離開發模式.

ElementUI的使用

環境搭建

1.創建一個static web項目
2.初始化vue項目

vue init webpack

3.運行項目

npm run dev

4.訪問首頁

localhost:8080
ElementUI基於vue前段ui框架

1.安裝elementui

npm i element-ui -S

2.main.js中導入elementui

import Vue from 'vue';
import ElementUI from 'element-ui'; //引入核心js組件
import 'element-ui/lib/theme-chalk/index.css';//引入依賴的樣式
Vue.use(ElementUI)

3.開始使用框架:以button為例
codeDemo
3.1先在components組件中新建一個.vue文件button.vue

<template>
  <div class="hello">
    <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>

    <el-row>
      <el-button plain>樸素按鈕</el-button>
      <el-button type="primary" plain>主要按鈕</el-button>
      <el-button type="success" plain>成功按鈕</el-button>
      <el-button type="info" plain>信息按鈕</el-button>
      <el-button type="warning" plain>警告按鈕</el-button>
      <el-button type="danger" plain>危險按鈕</el-button>
    </el-row>

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

    <el-row>
      <el-button icon="el-icon-search" circle></el-button>
      <el-button type="primary" icon="el-icon-edit" circle></el-button>
      <el-button type="success" icon="el-icon-check" circle></el-button>
      <el-button type="info" icon="el-icon-message" circle></el-button>
      <el-button type="warning" icon="el-icon-star-off" circle></el-button>
      <el-button type="danger" icon="el-icon-delete" circle></el-button>
    </el-row>


    <el-button type="primary" icon="el-icon-edit"></el-button>
    <el-button type="primary" icon="el-icon-share"></el-button>
    <el-button type="primary" icon="el-icon-delete"></el-button>
    <el-button type="primary" icon="el-icon-search">搜索</el-button>
    <el-button type="primary">上傳<i class="el-icon-upload el-icon--right"></i></el-button>

  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

3.2在router路由中的index.js中導入上面建好的組件

import Button from '@/components/button'

在再index.js中寫路由配置

{
      path: '/button',
      name: 'button',
      component: Button
    }

3.3npm run dev運行起來後在網頁打開
localhost:8080/button可見效果

ElementUI&axios&Mockjs實現前端模擬數據展示

codeDemo


1.先將前端的頁面模板展示出來
components中建立一個crud.vue文件

<template>
  <div>
    <el-table
      :data="users"
      style="width: 100%">
      <el-table-column
        prop="createTime"
        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-column
        prop="email"
        label="郵件">
      </el-table-column>
      <el-table-column
        prop="phone"
        label="電話">
      </el-table-column>
    </el-table>
    <el-pagination layout="prev, pager, next" @current-change="handleCurrentChange" :page-size="10" :total="total" style="float:right;">
    </el-pagination>
  </div>
</template>
<script>
    export default {
        data(){
            return {
                users:[],
                total:100,
                page:1
            }
        },
        methods: {
            handleCurrentChange(val){
                //page當前頁
                this.page =  val;
                //發送請求查詢
                this.getUsers();
            },
            getUsers(){
                //發送請求 獲取數據 axios
                /*  axios.get('/getUser').then(res=>{

                  })*/
                let params = {
                    page:this.page
                }
                //發送請求  controller {data:[],total:100}
                this.$http.post('/user/list',params).then(res=>{
                    console.log("-------------------res.data {data: total}");
                    console.log(res);
                    this.users =  res.data.data;
                    this.total = res.data.total;
                })
            }

        },
        mounted(){
            //頁面加載完之後 執行該方法
            this.getUsers();
        }
    }
</script>

2.Mock.js模擬數據
2.1安裝mockjs

npm install mockjs

2.2新建mockdemo.js文件
生成列表數據

// 使用 Mock
var Mock = require('mockjs')
/*
  數據模板定義規範 DTD
var data = Mock.mock({
  // 屬性 list 的值是一個數組,其中含有 1 到 10 個元素
  'list|1-10': [{
    // 屬性 id 是一個自增數,起始值為 1,每次增 1
    'id|+1': 1
  }]
})*/
/**
 *  DPD 數據佔位符定義規範
 */
var data = Mock.mock({
  name: {
    first: '@FIRST',
    middle: '@FIRST',
    last: '@LAST',
    full: '@first @middle @last',
    email:'@email',
    ip:'@ip'
  }
})
// 輸出結果
console.log(JSON.stringify(data, null, 4))

2.3crud數據模擬
新建UserMock.js文件,模擬產生的數據,上面的相當於一個模板,這裏是產生實際的數據。

import Mock from 'mockjs' // 引入mock
//var Mock = require('mockjs')
var dataList = []
for (var i = 0; i < 15; i++) {
  dataList.push(Mock.mock({
    'id': '@increment',
    'name': '@cname',
    'phone': /^1[0-9]{10}$/,
    'email': '@email',
    'address': '@county(true)',
    'createTime': '@date("yyyy-MM-dd")'
  }))
}

console.log(JSON.stringify(dataList));

//index 當前頁 size: 每頁條數 list 總的數據
/**
 *
 * @param index = 2
 * @param size = 10
 * @param list 15
 * @returns
 */
function pagination(index, size, list){
  return list.slice((index-1)*size,index*size);
}
//攔截請求
Mock.mock(new RegExp('/user/list'),'post',(opts) => {
  //賦值
  var list =dataList;
  console.log(opts.body) ;// "{page:2}"
  //json字符串轉換成JSON對象
  var index = JSON.parse(opts.body).page; //2
  //每頁條數
  var size = 10;
  //公共的條數
  var total = list.length
  //分頁方法
  list = pagination(index, size, list);
  return {
    'total': total,
    'data': list
  }
})

2.4、知識點:Ajax請求優化-axios

vue更新到2.0之後,官方推薦使用axios請求服務器數據。Axios和其他的ajax庫都很類似,他是基於promise的http庫,可以用在瀏覽器和node.js中
理解 就是ajax請求 --在vue裏面axios
安裝axios

npm install axios --save

佈局到main.js中

import axios from 'axios'
//配置axios的全局基本路徑 t
axios.defaults.baseURL=''
//全局屬性配置,在任意組件內可以使用this.$http獲取axios對象
Vue.prototype.$http = axios

2.5Axios發送請求
在crud.js中發送請求【包含分頁】

methods: {
            handleCurrentChange(val){
                //page當前頁
                this.page =  val;
                //發送請求查詢
                this.getUsers();
            },
            getUsers(){
                //發送請求 獲取數據 axios
                /*  axios.get('/getUser').then(res=>{

                  })*/
                let params = {
                    page:this.page
                }
                //發送請求  controller {data:[],total:100}
                this.$http.post('/user/list',params).then(res=>{
                    console.log("-------------------res.data {data: total}");
                    console.log(res);
                    this.users =  res.data.data;
                    this.total = res.data.total;
                })
            }

        },
        mounted(){
            //頁面加載完之後 執行該方法
            this.getUsers();
        }

2.6mock攔截請求 獲取參數,並返回

//index 當前頁 size: 每頁條數 list 總的數據
/**
 *
 * @param index = 2
 * @param size = 10
 * @param list 15
 * @returns
 */
function pagination(index, size, list){
  return list.slice((index-1)*size,index*size);
}
//攔截請求
Mock.mock(new RegExp('/user/list'),'post',(opts) => {
  //賦值
  var list =dataList;
  console.log(opts.body) ;// "{page:2}"
  //json字符串轉換成JSON對象
  var index = JSON.parse(opts.body).page; //2
  //每頁條數
  var size = 10;
  //公共的條數
  var total = list.length
  //分頁方法
  list = pagination(index, size, list);
  return {
    'total': total,
    'data': list
  }
})