目录
1.5加入axios
上篇文章:【VUE】demo01-VUE做后台管理系统页面实例-创建基本环境+页面布局
工具:Visual Studio Code + Vue + Vue cil2 + Vuex + Vue Router + ElementUI + axios
项目代码地址:macrozheng_mall学习: 学习macrozheng的mall项目,进行学习记录与代码拆解 - Gitee.com
我们先尝试加入接口调用的工具,通过登录接口来测试 axios 是否成功。(mall 项目的登录接口,是通过调用 vuex 操作的,但我们还没有加入vuex ,因为暂时还用不到,vuex 比较复杂。其实是一样哒,后续会加入的!)
注意:mall 的后端项目是使用的 token 来验证用户信息。也就是调用接口时,如果不是公开的接口需要提供 token 值的。
由于 axios 是一个工具,一般来说就像我们使用 Ajax 一样,调用一个方法就行,axios 也给我们提供了封装接口得到方法,一般就需要一个创建实例的文件,然后就是封装接口的js文件。
首先创建在src下一个创建 axios 实例文件 util/request.js
import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
// 创建axios实例
const service = axios.create({
baseURL: process.env.BASE_API, // api的base_url
timeout: 15000 // 请求超时时间
})
// request请求拦截器,每次请求接口前都会执行这个
service.interceptors.request.use(config => {
//可以在这里设置请求头等内容
return config
}, error => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
})
// respone相应拦截器
service.interceptors.response.use(
response => {
//这里是获取返回值,例如mall系统的后端返回内容是 code,data,message
//所以我们拿到code,判断是否等于200,不是就走接口错误的处理方式
const res = response.data
if (res.code !== 200) { //处理错误的方式
return Promise.reject('error')
} else {//处理正确的方式
return response.data
}
},
error => {
console.log('err' + error)// for debug
Message({
message: error.message,
type: 'error',
duration: 3 * 1000
})
return Promise.reject(error)
}
)
//输出对象
export default service
这里需要注意 axios 实例中的 baseURL ,我们可以在这里写死,也可以在项目的配置文件中设置,然后获取。
baseURL: process.env.BASE_API
“process.env.BASE_API”获取的就是 config/dev.env.js 文件中的 key= BASE_API 的 value 数据.
所以我们打开 config/dev.env.js 文件,添加一个 k:v 。
// --------------------config/dev.env.js---------------------
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
//记住这里必须加上 // 或者加上 http://,否则会被认为是没有IP端口协议的,会自动带上当前前端路径,
//就像这样 :http://localhost:8080/139.196.220.24:80/***/***
BASE_API: '"http://admin-api.macrozheng.com"' //就是这里
})
注意,我们这里 BASE_API 是 mall 系统提供的测试域名和接口,这样我们就不用在本地部署一遍后端程序了(后端项目学习也会有笔记记录),感谢 macrozheng !
axios 实例准备完成!!接下来我们需要进行一下测试,保证 axios 添加成功。因为很多接口都有访问权限,也为了直观,我们从登录接口添加 axios 调用接口的封装 js 文件。
首先,我们在 src 文件夹中创建一个文件 api/login.js ,之后的接口调用文件都在 src/api 文件夹中。
//------api/login.js--------------------------------
//引入我们写的 axios
import request from '@/utils/request'
export function login(username, password) {
return request({
url: '/admin/login',
method: 'post',
//data是添加到请求体(body)中的, 用于post请求。
data: {
username,
password
}
})
}
export function getInfo() {
return request({
url: '/admin/info',
method: 'get',
})
}
export function logout() {
return request({
url: '/admin/logout',
method: 'post'
})
}
export function fetchList(params) {
return request({
url: '/admin/list',
method: 'get',
//params是添加到url的请求字符串中的,用于get请求
params: params
})
}
之后我们调用 login 相关的接口时,直接引入这个 login.js 中暴露出去的方法就可以啦!
配置都完成啦,接下来进行测试,首先在 view 文件夹添加一个登陆页面 login/index.vue
//------login/index.vue 有删减----------------
mall-admin-web
登录
我们可以直接复制mall项目里面的,注意,有些东西我们之前没有添加,如果觉得不需要也可以去掉,反正以后也要用,添加部分如下:
1.SvgIcon组件和icons文件;
复制src/components/SvgIcon所有文件到我们项目中同样位置,之后复制 src/icons 所有文件到我们的项目中同样的位置。
2.util包中的validate文件;
复制src/views/validate.js 文件到我们项目中同样的位置。
3.images文件
复制src/assets/images 文件到我们项目中同样的位置。
如果不添加,记得将index文件中对应的标签或者引入组件删除,不然会编译报错的。
添加成功后我们还不可以访问,因为我们还没有添加路由呢!
打开 router/index.js 文件,添加 login 页面路由:
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '../views/layout/Layout'
export const constantRouterMap = [
//这里添加的路由
{path: '/login', component: () => import('@/views/login/index'), hidden: true},
{
path: '',
component: Layout,
redirect: '/home',
children: [{
path: 'home',
name: 'home',
component: () => import('@/components/HelloWorld'),
meta: {title: '首页', icon: 'home'}
}]
}
]
export default new Router({
// mode: 'history', //后端支持可开
scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap
})
运行项目后,打开 http://localhost:8080/#/login 页面试一下,mall 后端接口测试提供的账号密码是: admin macro123(希望可以看看这位作者的公众号哈),
访问成功!说明我们的 axios 引入成功!
当我们能够写基本的页面,能够调用接口时,基本的使用就可以,我们可以直接通过现有的工具编写系统页面。
注意,我们之前有说后端项目是使用的 token 来验证用户信息,管理系统除了登录页面,其余的页面都是需要权限的。所以思考一下,如果仅用现有的工具是非常麻烦的,我们登录之后需要保存 token 值,每次调用接口时都需要在请求头中加入 token 值,那么在好多路由中使用时就需要不停的传递 token 参数,非常麻烦!!!!
所以我们就需要有一个总的工具帮我们保存这个 token 值,只要我们需要就从他中获取,就不需要路由跳转传递啦!
因为保存的数据很小,所以直接用cookie保存,js-cookie就是关于cookie存储的一个js的API。可以看看这篇文章vue 项目中使用 js-cookie细则。
我们登陆成功之后,就需要调用 cookie 保存,(mall 项目是通过 vuex 调用 cookie 保存的,其实是一样的,只不过我们暂时没有加入 vuex 模块),我们直接在调用登录接口成功后,就调用 cookie 进行保存。
之后就需要在每次调用接口时,都加上token,我们也不可能每个接口都逐个添加,所以 axios 就提供了拦截器,我们在 1.5 中 util/request.js 文件中就添加了请求拦截器了,每次调用接口时都会拦截请求,然后我们在拦截中加上 token 值,这样就保证每个请求都携带 token ,当然没有 token 就不加了。
首先我们需要配置 js-cookie 工具,mall 项目有提供这个工具文件,就在 util 文件夹中的 auth.js,这个就是专门保存登录 token 的,注意不是专门操作 cookie 的,而是专门操作保存登录的cookie 的。我们拷贝过来,可以修改这个 TokenKey 为自己想要的。
//----auth.js-------------
import Cookies from 'js-cookie'
const TokenKey = 'loginToken'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
然后再 login/index.vue 文件中引入 auth.js 文件,并在调用接口成功后使用 setToken,添加到cookie 中。
//
//...
//-----sidebar/sidebaeItme.vue------
这样,我们就可以获取并拿到动态路由啦,访问 http://localhost:8080/#/login 链接,登陆成功后,发现左侧并没有变化??????添加断点,发现确实在路由前置守卫中添加动态路由了,但是,并没有显示在左侧导航栏。
说明权限是有获取到的,是前端有问题!!
首先我想到了:我们 sidebar 组件中的 data 数据是跟着项目运行而初始化的,也就是说,data 已经赋值为静态路由了,并且我们也没有在这个页面中主动修改过 data 数据,就导致,这个组件的 routes 并没有改变!!!!!(这个描述不确定是不是对的,确实不清楚这样能不能拿到修改后的 routes 。但是不成功的原因不是这个!)(待学习)
but,在之后的测试中我又发现了一件事:
我们登陆之后,左侧导航并没有改变,sidebar 组件中的 data 数据也没有改变,但是确实会跳转到,我们在网址上输入 http://localhost:8080/#/pms/product 就能够打开我们添加的路由页面!!!
也就是说路由是添加进去了,但是并没有传给sidebar 组件!于是我网上搜索找到了这样一个描述:this.$router.options.routes 可以拿到初始化时配置的路由规则。所以,我们动态路由 add 后他是拿不到的,<( ̄ ﹌  ̄)@m 生气!不过还好找到原因了。
那么我们单纯的使用路由 router 来解决动态路由是不行的,所以我们需要一个缓存器,帮助我们保存动态的路由,然后在 sidebarItem 组件中拿到渲染到 router-view 中,就可以啦!mall 里面就是用 vuex 这样写的,奈何我一开始没这样试,不过也了解了这个问题,以后就不会抓头发啦!
说到缓存器,mall里面用的 vuex ,我也按照这个使用,因为我们需要进行父子组件之间传递。不清楚缓存的可以看看这个,只是说个大概:vuex和缓存的区别
下一篇就开始加入 vuex 啦!!