VUE构建前后端分离的前端项目

VUE构建前后端分离的前端项目(超详细)

1.使用vue-cli创建项目
2.使用elementUI组件编写页面
3.使用axios与后台交互
4.使用webpack构建工具打包
5.部署到Tomcat

1.技术背景

前后端分离的优势:

  1. 分工明确,提高工作效率,前端主要关注页面、用户体验,后端主要关注业务、安全。
  2. 性能提升,前端通过路由配置实现按需加载,后端无需解析前端页面。
  3. 前后端同时开发,提升开发效率。
  4. 发现BUG可以快速定位问题,代码的重构和可维护性强,降低维护成本。
  5. 分离部署,静态资源由前端服务器处理,减轻后端服务器压力。

技术背景

  1. VUE:轻量级,单页面,只关注视图层不操作DOM,MVVM响应式双向数据绑定,组件化思想,运行速度快,社区活跃,简单易上手。
  2. elementUI:饿了么前端团队开发的组件库,文档详细,风格简洁,内置过渡动画,组件切换效果生动,
  3. axios:vue官方建议使用,从浏览器中创建XMLHTTPRequests、支持Promise
  4. API、拦截器请求和响应、自动转换JSON数据、客户端支持防止CSRF
  5. webpack:把所有依赖打包成一个整体,通过代码分割成单元片段并按需加载

2.创建项目

1.安装node环境和vue

在控制台分别输入node –vvue –V检测是否安装成功
VUE构建前后端分离的前端项目_第1张图片

2.*使用淘宝镜像仓库,加速npm下载

1.由于npm的服务器是在国外的,下载速度慢,配置国内淘宝镜像仓库 npm install cnpm -g --registry=https://registry.npm.taobao.org
2. 使用命令 cnpm install

3.新建项目

打开VS Code,选择一个目录打开,在控制台输入
vue init webpack login(项目名称是login)
按照弹出的项目进行对应配置
VUE构建前后端分离的前端项目_第2张图片
最后一步确定之后需要等待几分钟下载模板
VUE构建前后端分离的前端项目_第3张图片

4.目录结构

build – 构建相关
config – 配置
assets – 静态资源
components – 全局公用组件
router – 路由
utils – 公用方法
APP.vue – 入口页面
main.js – 入口文件,加载组件和初始化
static – 静态资源
VUE构建前后端分离的前端项目_第4张图片

5.vue文件结构

html模板写在template标签里面,且内部只能包含一个根元素。
components:组件注册,局部声明组件。
data:数据。
mounted:模板渲染成html后调用。
methods:方法定义。

vue的生命周期(vue实例从创建到销毁的过程)

beforeCreate: 创建前(数据观测和事件配置之前),实例初始化之后调用
created: 创建(实例已经创建完成之后被调用)
beforeMount:挂载前
mounted:挂载
beforeUpdate: 更改前
updated: 更新
beforeDestroy:销毁前
destroyed:销毁

VUE构建前后端分离的前端项目_第5张图片

6.启动项目

下载完成后根据提示:进入login目录,运行项目

cd login
npm run dev

VUE构建前后端分离的前端项目_第6张图片
可以看到vue的专属欢迎页面
VUE构建前后端分离的前端项目_第7张图片

7.安装elementUI组件库,创建页面

在控制台输入npm - element-ui –S 开始下载模块
在这里插入图片描述
下载完毕后,在main.js引用组件库
VUE构建前后端分离的前端项目_第8张图片
使用el-form/ el-input/ el-button组件完成如图所示的登录页面
VUE构建前后端分离的前端项目_第9张图片

8.配置路由

进入router目录下的index.js 文件配置路由,将默认的HelloWorld删掉,路由根节点改成新增加的登录页面。这样打开项目默认显示的就是登录页面

import Vue from 'vue'
import Router from 'vue-router'
// import HelloWorld from '@/components/HelloWorld'
import Login from '@/views/login'

Vue.use(Router)

export default new Router({
  mode: 'hash',
  routes: [
    {
      path: '/',
      name: 'login',
      component: Login,
    }
  ]
})

9.实现登录功能

①安装axios和qs模块:分别在控制台输入npm install axiosnpm install qs
在这里插入图片描述
在这里插入图片描述
②前后端分离项目存在跨域问题,开发的时候需要配置proxyTable代理解决跨域问题
打开config目录下的index.js文件,在dev项的ProxyTable添加代码

proxyTable: {
      '/ppu/web/*': {
        target: 'http://172.16.28.186:8080', // 目标接口域名
        changeOrigin: true // 是否跨域
      }
    },

tip:在ProxyTable下面有个port项,默认值是8080,这是前端启动的端口号,可以将它改掉,否则如果先启动前端,后端就会因为端口占用而无法启动了。
在这里插入图片描述
③访问接口
由于ppu登录需要使用aes对用户名和密码进行加密,所以这边需要先下载相关插件JAVA VUE前后端使用aes对用户名密码加密

④在登录页面login.vue 引入axios和qs

import axios from 'axios'
import qs from 'qs'

⑤在登录按钮的点击事件login里面添加代码访问登录接口,post需要配置请求头和参数格式(这部分代码后文会改,就不贴代码了)
VUE构建前后端分离的前端项目_第10张图片

3.axios和接口封装

在前后端交互方面采用axios,为了便于维护和复用,避免每个页面都引入一次axios和qs、避免每个接口都进行请求头配置,我们可以对axios进行封装。

1.封装axios

在src目录下创建utils目录,在utils目录下新建文件http.js,用来封装axios
①首先引入axios和qs

import axios from 'axios'
import qs from 'qs'

②设置请求接口的超时时间是10秒

axios.defaults.timeout = 10000

③由于例子使用的接口有公共的部分/ppu/web,直接设置axios请求的公共路径/ppu/web

axios.defaults.baseURL = '/ppu/web'

③添加请求拦截器

axios.interceptors.request.use(
  config => {
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

④添加响应拦截器(常见错误代码)

axios.interceptors.response.use(
  response => {
    return response
  },
  error => {
    let result = ''
    if (error.response) {
      const code = error.response.status
      if (code === 403) {
        result = '登录失效,请重新登录'
        sessionStorage.clear()
        window.location.href = '/login'
      } else if (code === 404) {
        result = '请求的页面失踪了~'
      }
    } else {
      result = error + ''
    }
    alert(result)
    return Promise.reject(result)
  }
)

⑤get方法封装

/**
 * 封装get请求
 * @param url
 * @param params
 * @returns {Promise}
 */
export function fetch(url, params = {}) {
  return new Promise((resolve, reject) => {
    axios.get(url, {
      params: params
    }).then(response => {
      console.log(response);
      
      resolve(response.data)
    }).catch(error => {
      reject(error)
    })
  })
}

⑥post方法封装

/**
 * 封装post请求
 * @param url
 * @param data
 * @returns { Promise }
 */
export function post(url, data = {}) {
  return new Promise((resolve, reject) => {
    axios.post(url, data, {
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      transformRequest: [function(data) { // 对传递的数据进行格式转换,以便传递给后台
        data = qs.stringify(data)
        return data
      }]
    }).then(response => {
      resolve(response.data)
    }).catch(error => {
      reject(error)
    })
  })
}

⑦在登录页面调用封装好的post方法

import { post } from '../utils/http'  // 引入post
login: function() {
      const data = {
        // encrypt()加密
        username: encrypt(this.username),
        password: encrypt(this.password)
      } 
     post('/login', data).then(response => { 
       console.log(response.data); 
     })    
}

在控制台看到登陆成功返回的结果
VUE构建前后端分离的前端项目_第11张图片
2.接口封装
为了方便对接口进行管理,实现复用,在utils目录下新建一个api.js文件,用来定义所有的接口

①首先引入封装好的axios方法

import { fetch, post } from './http'

VUE构建前后端分离的前端项目_第12张图片
②定义登录接口的方法为login,params是要传的参数,’/login’是请求的接口,并且将方法暴露出去

export const login = (params) => post('/login', params)
export const menu = () => fetch('/user')
export const logout = (params) => post('/login/logout', params)

③在登录页面引入封装好的登录接口

import { login } from '../utils/api'

④在登录函数引用接口

login: function() {
      const data = {
        username: encrypt(this.username),
        password: encrypt(this.password)
      }
      login(data).then(response => {
        sessionStorage.setItem('token', response.data._csrf) // 将token存到本地
        this.$router.push({ path: '/main' }) // 跳转页面
      })
    }

4.打包部署

打包原理:

webpack与其他的打包模块不同的是,webpack是把项目当作一个整体, 通过一个给定的的主文件,webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包成一个或多个浏览器可识别的js文件,实现按需加载。

优点:
    1.模块化开发(import  require)
    2.预处理(less sass ES6)
    3.主流框架脚手架支持(Vue React Angular)
    4.庞大的社区(资源丰富,降低学习成本)

打包后访问的后端地址会被一同打包了,由于static目录是不会被打包的,所以可以在static目录下新建一个config.js文件
①将访问的后端地址定义为window全局变量

window.global_config = {
  BASE_URL: 'http://172.16.28.186:8080'
}

VUE构建前后端分离的前端项目_第13张图片
②在项目入口文件index.html引入这个js文件
VUE构建前后端分离的前端项目_第14张图片
③修改http.js里面的axios公共地址
VUE构建前后端分离的前端项目_第15张图片
④此时直接打包部署后会出现静态文件找不到的404错误,需要在config目录下的index.js文件里面将打包的assetsPublicPath改成’./'当前目录
VUE构建前后端分离的前端项目_第16张图片
⑤在控制台输入npm run build打包命令
打包成功后项目中会出现一个dist文件夹,里面就是打包后的文件,只剩下一个入口文件index.html和static文件夹,里面包含css和javascript代码以及一些图片或者图标文件

VUE构建前后端分离的前端项目_第17张图片
⑥在tomcat的webapps目录下创建create文件夹,将打包好的文件复制到create目录下,然后启动Tomcat
VUE构建前后端分离的前端项目_第18张图片
⑦在浏览器的地址栏输入http://172.16.28.186:8580/create/index.html#/即可访问到项目
VUE构建前后端分离的前端项目_第19张图片
修改后端地址只需要在打包后static目录下的config.js文件里面修改,无需重新打包
VUE构建前后端分离的前端项目_第20张图片
附上登录页面的代码

<template>
  <div class="page-container">
    <div class="login-box">
      <span class="login-title">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
      <el-form>
        <el-form-item>
          <span>账号:</span>
          <el-input v-model="username" class="login-item" />
        </el-form-item>
        <el-form-item>
          <span>密码:</span>
          <el-input v-model="password" type="password" class="login-item" />
        </el-form-item>
      </el-form>
      <el-button class="login-button" plain type="primary" @click="login">登录</el-button>
    </div>
    <!-- <div class="page-foot" /> -->
  </div>
</template>

<script>
import { encrypt, decrypt } from '../utils/aes'
import { login } from '../utils/api'
import router from '../router'

export default {
  data() {
    return {
      username: 'ppu_wbzxryA',
      password: 'Dm123456',
      list: []
    }
  },
  methods: {
    login: function() {
      const data = {
        username: encrypt(this.username),
        password: encrypt(this.password)
      }
      login(data).then(response => {
        sessionStorage.setItem('token', response.data._csrf)
        this.$router.push({ path: '/main' })
      })
    }
  }
}
</script>

<style scoped>
.page-container {
  /* background-color: antiquewhite; */
  width: 100%;
  height: calc(100vh);
}
.page-head {
  background-color: rgba(56, 148, 223, 0.253);
  height: 90px;
  width: 100%;
}
.page-foot {
  background-color: rgba(56, 148, 223, 0.253);
  height: 50px;
  width: 100%;
  position: absolute;
  bottom: 0;
}
.login-box {
  padding-top: 20px;
  height: 350px;
  width: 300px;
  position: fixed;
  top: 20%;
  left: 50%;
  margin-left: -150px;
  border: rgb(132, 182, 216) 1px solid;
  box-shadow: 10px 10px 5px #888888;
  background-color: rgb(255, 255, 255);
}
.login-title {
  display: block;
  height: 60px;
  line-height: 45px;
  font-size: 24px;
  font-weight: 500;
}
.login-item {
  width: 200px;
}
.login-button {
  width: 80%;
}
</style>

你可能感兴趣的:(vue)