后端工程师快速上手前后端分离开发

998 阅读7分钟

通过前端页面进行后端数据的展示,使得功能调试更加方便,开发思维更为连贯。现在大部分是以json的数据形式实现前后端的分离开发。SSM中来自jsp或thymeleaf模板引擎的方式也是经典的使用方式。

本文主要讲述如何实现这样的项目搭建和数据传输,重点是前端模板的引入。不涉及es6,到babel,webpack,node的讲解。

前端模板 vue-admin-template

vue-element-admin 是一个后台前端解决方案,它基于 vueelement-ui实现。这个一款很优秀的后端管理系统的前端模板。当然里面的组件太丰富,这里使用它的基础模板 vue-admin-template即可,熟悉vue开发后,可根据开发需要参考集成方案来扩充基础版本。

建议先仔细仔细阅读vue-admin-template项目官方文档

引入步骤

克隆项目(本文展示的是v4版本,较v3有差异)

git clone https://github.com/PanJiaChen/vue-admin-template.git

进入项目目录

cd vue-admin-template

设置淘宝镜像

npm config set registry https://registry.npm.taobao.org
# 或者
npm install --registry=https://registry.npm.taobao.org

安装依赖

npm install

若提示缺少node-sass,尝试

npm config set sass_binary_site=https://npm.taobao.org/mirrors/node-sass
npm install node-sass

启动服务

npm run dev

启动后,浏览器自动打开并访问localhost:9528端口,端口可在配置文件vue.config.js中修改。

点击登录后,可以看到后台管理系统的主页面。这里登录过程中,用户信息,token等信息均是mock数据,也就是mocker文件价中的内容,并不真正来自后端服务器。

本文示例展示前端页面展示后端的订单数据

后端项目搭建

  • 本文注重极简开发,后端以springboot单体项目为例,引入web和lombok依赖即可
<artifactId>flow-microservice-order</artifactId>
<description>订单模块</description>
// ...
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
  • 启动端口
server:
  port: 7000
  • 数据接口
@RestController
@RequestMapping("/api/v1/orders")
public class OrderController {

    Order order1 = new Order(1, "apple", 12, "aaa");
    Order order2 = new Order(2, "amazon", 16, "bbb");
    Order order3 = new Order(3, "mi", 18, "ccc");
    Order order4 = new Order(4, "face", 5, "ddd");

    // 默认订单数据集合
    public List<Order> orders = Arrays.asList(order1, order2, order3, order4);

    /**
     * 获取所有订单数据
     */
    @GetMapping("/list")
    public RespResult listUsers() {
        Map<String, Object> data = new HashMap<>();
        data.put("items", orders);
        RespResult result = new RespResult(20000, "请求成功", data);
        return result;
    }

    /**
     * 获取指定id订单
     */
    @GetMapping("/{id}")
    public RespResult findById(@PathVariable Integer id) {
        Order order = this.orders.stream().filter(i -> i.getId() == id).findFirst().orElse(null);
        Map<String, Object> data = new HashMap<>();
        data.put("item", order);
        RespResult result = new RespResult(20000, "请求成功", data);
        return result;
    }

    /**
     * 通用结果类
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class RespResult {
        private long code;
        private String message;
        private Map<String, Object> data;
    }

    /**
     * 订单类
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class Order {
        private Integer id;
        private String product;
        private Integer total;
        private String description;
    }
}
  • 控制台测试
// 获取所有订单数据
curl http://localhost:7000/api/v1/orders/list

ok,后端数据已经准备完成,继续修改前端配置

前端开发

配置后端接口

  1. 保留mock文件夹,后期改为后端真实的用户登录凭证(PS: 项目开始构建时,不建议一开始就引入安全框架,这会对其他业务造成不必要的干扰);

  2. 增加后端代理配置,在vue.config.js中,可以看到before: require('./mock/mock-server.js'),这里是优先使用mock服务,如果没有就会找其他代理服务,因此在before后面配置我们的后端服务器地址和接口即可:

    before: require('./mock/mock-server.js'),
    proxy: {
      // change xxx-api/login => mock/login
      // detail: https://cli.vuejs.org/config/#devserver-proxy
      [process.env.VUE_APP_BASE_API]: {
        target: `http://127.0.0.1:7000/`,
        changeOrigin: true,
        pathRewrite: {
          ['^' + process.env.VUE_APP_BASE_API]: ''
        }
      }
    }
    

process.env.VUE_APP_BASE_API是一个全局配置,指定后请求后端的URL根路径

  1. EsLint设置:EsLint是前端一种语法检查工具,template默认使用了该功能,配置文件在.eslintrc.js。如何你是webstorm,默认自动话eslint,可以配置快捷键,但有格式错误时,使用快捷键可以自动格式化代码。当然也可以选择关闭,在vue.conf.js中:

    lintOnSave: process.env.NODE_ENV === 'development',
    // 改为
    lintOnSave: false
    

配置路由

我们在页面中看到左侧导航栏切换时,中间的页面也会更着切面,其中就是使用了路由。该配置在src/router/index.js中,参考已有的路由,拷贝form进行修改

{
  path: '/order',
  component: Layout,
  children: [
    {
      path: 'index',
      name: 'Order',
      component: () => import('@/views/order/index'),
      meta: { title: '订单管理', icon: 'shopping' }
    }
  ]
},

配置后端请求接口

src/api,打开已有的user.js,可以看出这是前端请求接口数据是的使用的路径,如登录时可以看到login的请求路径预user.js中login的url一致

由此创建属于订单模块的接口文件

import request from '@/utils/request'

const api_name = '/api/v1/orders'

export default {
  // 获取所有订单信息
  getOrderList() {
    return request({
      url: '/list',
      method: 'get'
    })
  },

  // 获取指定id订单
  getById(id) {
    return request({
      url: `${api_name}/${id}`,
      method: 'get'
    })
  }
}

创建订单管理页面

src/views中添加订单的vue文件,初始化为

<template>
  <div>
    订单管理vue
  </div>
</template>

template中只能有一个div标签,但div下可以有子div;vue的文件路径要与路由中配置的一致

点击订单管理的导航栏,就可以看到自定义的vue文件

调试后端数据

vue文件创建后,先不着急引入各式的组件,首先应该调试该页面的数据是否能正常调用,因此需要:

  1. 引入api接口组件;
  2. 创建获取后端数据的方法,并打印在控制台;
  3. 使用生命周期函数created或mounted,使得页面加载时自动调用方法
<template>
  <div>
    订单管理vue
  </div>
</template>
<script>
/* 引入order的api组件*/
import order from '@/api/order'

export default {
  data() {
    return {
      tableData: []
    }
  },
  /* 生命周期函数--页面加载时调用*/
  created() {
    this.fetchData()
  },
  methods: {
    // 获取后端数据--获取所有订单
    fetchData() {
      order.getOrderList().then(response => {
        console.log(response)
      })
    }
  }
}
</script>

页面已收到后端数据

后端返回成功代码默认设置是2000,可以在request.js中修改

Element UI

使用vue的一大好处就是有很多开源的组件库,而template就是以element ui为基础开发的,因此我们需要的自定义组件不仅可以从admin模板中参看,更推荐从element ui中引入,以下就使用其中一个表格组件进行开发,以其中一个为例:

点击显示代码,可以看出,我们需要将tableData中的死数据改为后端的动态数据即可,注意prop标签与json数据一致,data改为动态绑定数据即:data

完整index.vue

<template>
  <div>
    <h2>订单管理vue</h2>
    <div>
      <el-table
        :data="tableData"
        border
      >
        <el-table-column
          fixed
          prop="id"
          label="ID"
          min-width="30%"
        />
        <el-table-column
          prop="product"
          label="商品"
          min-width="100%"
        />
        <el-table-column
          prop="total"
          label="总数"
          min-width="100%"
        />
        <el-table-column
          prop="description"
          label="描述"
          min-width="100%"
        />
        <el-table-column
          fixed="right"
          label="操作"
          min-width="100%"
        >
          <template slot-scope="scope">
            <el-button type="text" size="small" @click="handleClick(scope.row)">查看</el-button>
            <el-button type="text" size="small">编辑</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
  </div>
</template>

<script>
/* 引入order的api组件*/
import order from '@/api/order'
export default {
  name: 'Index',
  data() {
    return {
      tableData: []
    }
  },
  /* 生命周期函数--页面加载时调用*/
  created() {
    this.fetchData()
  },

  methods: {
    // 获取后端数据--获取所有订单
    fetchData() {
      order.getOrderList().then(response => {
        this.tableData = response.data.items
        console.log(this.tableData)
      })
    }
  }
}
</script>

<style scoped>

</style>

ok,现在页面就能展示后端传输过来的数据了

附: 若考虑使用微服务的架构,那么前后端1对1的端口配置就不适用了,需要使用代理对前端请求进行转发。已nginx为例: 前端统一接口:

target: `http://127.0.0.1:9100/`,

后端接口--订单模块:

server:
  port: 9610

nginx配置: 原有server不变,新增一个server,加入订单模块的监听,订单模块根路径固定/api/v1/orders:

server {

	listen 9100;
	server_name localhost;

	location ~ /orders/ {           
		proxy_pass http://localhost:9610;
	}			
}

**结语:**本文比较入门,对于想要开始前后端开发的朋友们来说应该会有一定的帮助,毕竟有了可视化的页面以后,对功能或业务的思考会更具体。如果不想使用template模板,可以参考参考之前的文章:SpringBoot+Vue之表格的CRUD与导入导出


详细代码可参考:

前端:github.com/chetwhy/clo…

后端:github.com/chetwhy/clo…