前言📋
上一篇主要介绍了如何安装通过webpack安装一个具有完整线上依赖的项目,其中我们通过webpack-template
安装了vue2.0项目的Vue-Core
、Vue-Router
以及ESLint
依赖。下面我们来完成前后端接口通信操作:
配置🔨
因为webpack-template
已经默认帮我们配置好了vue-router
,因此我们下面可以直接在router
文件夹下的index.js
直接使用,下面我们开始正式进行完成前后端分离的关键步骤——跨域
首先,因为使用npm init webpack you-project
命令创建的webpack-template
模板是适用于大型的、工程化的项目,所以项目中的config
文件夹下自带了关于跨域的webpack
的配置文件index.js
以及用于各种生产环境的js配置文件,所以我们只需要修改port
以及proxyTable[]
即可完成项目的跨域!
port: 8081
因为首先需要测试一下axios的请求能不能够成功,因此端口与代理跨域先注释:
proxyTable: {
// proxy all requests starting with /api to jsonplaceholder
'/api': {
target: 'http://jsonplaceholder.typicode.com',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
},
但是完成跨域代理设置后,还需要axios
(ajax到vue 2.0就不再更新了,这里推荐axios)进行跨域请求的构建,这里提一下因为后端请求还不一定能成功通过axios
获取到,因此先进行axios的测试使用:
测试方案有两种:
1.直接使用公用API返回的JSON;
2.使用mock
测试
第一种方案显然可以在后台数据已经存在的情况下使用,第二中方案更适合在前后端刚刚分工好并且前端还拿不到数据的情况下,就可以使用mock.js模拟数据的请求。我么这里采用第一种方式测试axios
:
一、安装axios
npm install axios --save
1. 引入方式
引入插件可以直接在 main.js 中引入并使用 Vue.use()来注册,但是 axios并不是vue插件,所以不能 使用Vue.use()。但是,可以通过修改axios原型链(即:原生函数)来达到全局引入的方式。
2. main.js引入axios
axios
是目前前端几乎完美的跨域请求工具,其次是ajax
(但这里推荐官方使用的axios)。axios
是基于Express
构建的Http请求工具,并且支持Promise.js
请求(ECMAScript标准,即欧洲国际标准委员会(前身为计算机制造商协会)——前端Javascript
标准制定机构——扩展:JavaScript
与ECMAScript
均由网景公司创立,因此后者也就作为了JavaScript
的标准化规范脚本语言)。在main.js中(全局)引入(如果只需要局部引入的话在相应文件中直接引入就好了)
//main.js
import axios from 'axios'
//把axios对象挂到Vue实例上面,使用axios的时候直接全局调用this.$axios就可以了
Vue.prototype.$axios = axios
在components
目录下创建Home.vue
,并导入HelloWorld.vue
到Home.vue
中合并为一个大的组件;然后在router
目录下的index.js
中导入Home
组件,删除原来的HelloWorld.vue
组件的引入,最后将HelloWorld
改为Home
即可完成Home.vue
组件的声明与两个组件的合并。
3. 修改vue-router
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
// import HelloWorld from '@/components/HelloWorld'
import Home from '@/components/Home.vue'
Vue.use(Router)
export default new Router({
routes: [
// {
// path: '/',
// name: 'HelloWorld',
// component: HelloWorld
// }
{
path: '/',
name: 'Home',
component: Home
}
]
})
注意:因为这里的组件都是用于测试,因此为了按需加载(弃用后还会创建)的必要性,这里将Home.vue
注册为了局部组件;因为两个组件不能有同一个路径,否则会发生覆盖从未导致某一个组件显示异常;而且我们将两个组件合并了,实际上我们只用注册一个总组件(即:import和components: { }所有其他组件的哪一个组件)的路径即可完成组件的整体显示(显示方式为div重叠),全局注册可以使其他组件作为父(总)组件的子组件显示在不同的界面。
4. 创建Home.vue组件测试使用
这里请求的地址来自 音乐API调用平台alapi.cn
Home.vue
<template>
<div class="home">
<button @click="mockTest()">试试</button>
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'Home',
components: {
HelloWorld
},
methods: {
mockTest () {
this.$axios.get('https://v1.alapi.cn/api/music/search?keyword=我爱你')
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
}
}
}
</script>
可以看到已经返回了data,axios测试成功!
到了这里,因为axios测试成功,已经可以直接与java
后端的数据进行交互了!
下面使用mock.js
模拟真实数据请求,是给前端开发的小伙伴提供的,可以为项目的无缝对接提供可靠性!
二、安装mock.js
cnpm install mockjs --dev
简介
之前,前端在开发时,需要等后端把接口完成,前端再把接口接入,获取数据。这样前端一般会遇到一个问题:PI接口未及时输出时,前端开发进度会被延误。这个时候就需要前后端分离了,后接未输出API接口时,你也要使用工具来模拟API接口生成数据。这个工具就是Mockjs,你也可以使用Easy-mock。mock.js实现原理是promise+ajax。
特征
- 根据数据模板生成模拟数据
- 为ajax请求提供请求/响应模拟
1. mockjs的安装:
npm install mockjs --save-dev
2. 配置
为了只在开发环境使用mock.js
,而打包到生产环境时自动不使用mock.js
,做以下配置:
config
目录下dev.env.js
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
Mock: true
})
config
目录下prod.env.js
'use strict'
module.exports = {
NODE_ENV: '"production"',
Mock: false
}
src
目录下main.js
process.env.Mock && require('./mock/mock.js')
3. 新建一个mock.js的文件
4. 在mock.js文件中编写响应数据
mock.js
// 引入mockjs
const Mock = require('mockjs')
// 获取 mock.Random 对象
const Random = Mock.Random
// mock一组数据
const produceNewsData = function () {
let articles = []
for (let i = 0; i < 100; i++) {
let newArticleObject = {
title: Random.csentence(5, 30), // Random.csentence( min, max )
thumbnail_pic_s: Random.dataImage('300x250', 'mock的图片'), // Random.dataImage( size, text ) 生成一段随机的 Base64 图片编码
author_name: Random.cname(), // Random.cname() 随机生成一个常见的中文姓名
date: Random.date() + ' ' + Random.time() // Random.date()指示生成的日期字符串的格式,默认为yyyy-MM-dd;Random.time() 返回一个随机的时间字符串
}
articles.push(newArticleObject)
}
return {
data: articles
}
}
// 拦截ajax请求,配置mock的数据
Mock.mock('/api/test', 'get', produceNewsData)
设置请求延迟时间
mock.js
// 设置请求延时时间
Mock.setup({
timeout:2000
})
我们这里有许多模拟mock数据服务的方案,所有的http请求构建工具都可以(比如:apizza、postman)构建mock-server,我们这里使用ajax和axios(推荐)的方式构建:
5. 使用ajax请求数据
根据请求函数的不同($http
与$axios
),这里有两种方式进行http请求的构建,分别是Ajax
和Axios
,而在vue
中ajax
构建的请求库是vue-resource
,下面是关于vue-resource
与axios
的介绍:
- Vue 要实现异步加载需要使用到 vue-resource 库。
- Vue.js 2.0 版本推荐使用 axios 来完成 ajax 请求。
安装
npm i vue-resource --save-dev
引入
main.js
import VueResource from 'vue-resource'
注册
main.js
Vue.use(VueResource)
使用测试
因为这里暂时模拟没有axios
库,因此使用axios
设置全局请求路径前缀的方法先注释,请求api与mock.js
保持一致
// axios.defaults.baseURL = '/api' // 设置跨域代理基本路径前缀
main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
// 自定义全局项目配置
// import axios from 'axios'
import vueResource from 'vue-resource'
Vue.use(vueResource) // 注册vue-resouce
// 把axios对象挂到Vue实例上面,使用axios的时候直接 this.$axios就可以了
// Vue.prototype.$axios = axios
// axios.defaults.baseURL = '/api' // 设置跨域代理基本路径前缀
process.env.Mock && require('./mock/mock.js') // 打开并引入mock数据
// 将整体生产环境配置关闭
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
注意: 这里不用关闭config/index.js的请求代理,因为本地的数据请求优先级大于代理请求数据;当然,为了模拟没有配置axios
与代理,可以将proxyTable
配置关闭:
<script>
export default {
name: 'MockTest', // 局部注册的组件名,自己测试的话可以直接在已有的组件中执行方法
mounted: function () {
this.getMock()
},
methods: {
getMock () { // 引入vue-resource库进行ajax请求
this.$http.get('/api/test').then(function (res) {
console.log(res.data)
})
}
// getMock () {
// this.$axios.get('/api/test').then(function (res) {
// console.log(res.data)
// })
// }
}
}
</script>
启动项目,成功读取到数据:
6. 使用axios请求数据
安装axios(虽然上面已经安装过了)
npm install axios --save
因为上面设置了全局api前缀
,这里如果为了测试页面API与mock.js
文件中json数据
对应的匹配度,同样也可以将全局的axios请求路径前缀注释掉:
// axios.defaults.baseURL = '/api' // 设置跨域代理基本路径前缀
当然,我们这里推荐不注释!
注意:
1.因为vue-resource
与axios
构建请求都是异步的,因此这里也不需要关闭代理;
2.如果没有在main.js(全局)或者MockTest.vue(局部)引入mock.js文件,那么会报502错误:
Your application is running here: http://localhost:8081
[HPM] Error occurred while trying to proxy request /test from localhost:8081 to http://localhost:8080/ (ECONNREFUSED) (https://nodejs.org/api/errors.html#errors_common_system_errors)
引入
import axios from 'axios'
注册
// 把axios对象挂到Vue实例上面,使用axios的时候直接 this.$axios就可以了
Vue.prototype.$axios = axios
axios.defaults.baseURL = '/api' // 设置跨域代理基本路径前缀
使用测试
main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
// 自定义全局项目配置
import axios from 'axios'
// import vueResource from 'vue-resource'
// Vue.use(vueResource) // 注册vue-resouce
// 把axios对象挂到Vue实例上面,使用axios的时候直接 this.$axios就可以了
Vue.prototype.$axios = axios
axios.defaults.baseURL = '/api' // 设置跨域代理基本路径前缀
process.env.Mock && require('./mock/mock.js') // 打开并引入mock数据
// 将整体生产环境配置关闭
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
使用
MockTest.vue
<template>
<div>
<h1>{{msg}}</h1>
</div>
</template>
<script>
export default {
name: 'MockTest', // 局部注册的组件名,自己测试的话可以直接在已有的组件中执行方法
data () {
return {
msg: '南街北巷'
}
},
mounted: function () { // 组件挂载后自动执行方法
this.getMock()
},
methods: {
// getMock () { // 引入vue-resource库进行ajax请求
// this.$http.get('/api/test').then(function (res) {
// console.log(res.data)
// })
// }
getMock () { // 使用axios请求
this.$axios.get('/test').then(function (res) {
console.log(res.data)
})
}
}
}
</script>
启动项目,同样也测试成功!
到这里,mock
与axios
的集成已经结束了,下面就是正式的前后端分离开发了!
【学无止境❤️谦卑而行】欢迎关注白羊🐏,感谢观看ヾ(◍°∇°◍)ノ゙