目录
一、封装本地存储操作模块
新建文件src\utils\storage.js封装操作token的方法
二、vuex处理用户登陆后的token值
新建文件:src\store\index.js
安装导入:npm install vuex
三、封装 axios 请求模块
下载导入:npm install axios
四、在main.js文件内全局注册store、axios
五、新建api文件夹,存放接口文件
六、在组件页面内调接口拿数据
接口使用例子1
1. 登录接口的使用(同注册),在页面导入接口
2. 通过async await 来拿到用户输入的值,根据返回结果进行判断返回相应提示
接口使用例子2
1. 通过接口获取数据进行渲染,这里把需要的接口解构出来
2. data定义需要渲染的数据(可与后端字段一致)
3. 在方法里面调用接口,把拿到的数据放到一个自己定义的数组里面list
4. 通过v-for渲染获取到的数据
一、封装本地存储操作模块
新建文件src\utils\storage.js封装操作token的方法
/* 存储数据 */
export const setItem = (key, value) => {
// 将数组、对象类型的数据转换为 JSON 格式字符串进行存储
if (typeof value === "object") {
value = JSON.stringify(value);
}
window.localStorage.setItem(key, value);
};
/* 获取数据 */
export const getItem = (key) => {
const data = window.localStorage.getItem(key);
try {
return JSON.parse(data);
} catch (err) {
return data;
}
};
/* 删除数据 */
export const removeItem = (key) => {
window.localStorage.removeItem(key);
};
二、vuex处理用户登陆后的token值
新建文件:src\store\index.js
安装导入:npm install vuex
import Vue from "vue";
import Vuex from "vuex";
// 加载storage模块:获取token,存储token
import { getItem, setItem } from "@/utils/storage";
Vue.use(Vuex);
// 用户登陆后的token值
const TOKEN_KEY = "X-Token";
export default new Vuex.Store({
// 处理用户 Token,定义容器当中数据
state: {
// 用户的登录状态信息,存储当前登录用户信息(token等数据)
// 1. user: null
// 2. user: JSON.parse(window.localStorage.getItem(TOKEN_KEY))
user: getItem(TOKEN_KEY),
},
mutations: {
setUser(state, data) {
state.user = data;
// 为了防止刷新丢失,我们需要把数据备份到本地存储
// window.localStorage.setItem(TOKEN_KEY, JSON.stringify(state.user))
setItem(TOKEN_KEY, state.user);
},
},
actions: {},
modules: {},
});
三、封装 axios 请求模块
下载导入:npm install axios
// 封装 axios 请求模块
import axios from "axios";
import router from "@/router";
// axios.create 方法创建一个axios的实例
const request = axios.create({
baseURL: "/localhost", // 接口的基准路径,改成自己的项目基地址
});
// 请求拦截器:是否注入token
request.interceptors.request.use(
function (config) {
return config;
},
function (error) {
return Promise.reject(error);
}
);
// store文件中vuex和localstorage对token进行处理之后响应拦截器中统一处理 token 过期
// 处理流程:在axios拦截器中加入token刷新逻辑;用户token过期时,向服务器请求新的 token;旧token替换为新token;然后继续用户当前的请求
// 响应拦截器
request.interceptors.response.use(
function (response) {
return response;
},
async function (error) {
console.dir(error);
if (error.response && error.response.status === 401) {
// 校验是否有 refresh_token
const user = store.state.user;
if (!user || !user.refresh_token) {
router.push("/login");
return;
}
// 如果有refresh_token,则请求获取新的 token
try {
const res = await axios({
method: "PUT",
url: "/admin/waterMeter/login", // 改成自己的项目的登录地址
headers: {
Authorization: `Bearer ${user.refresh_token}`,
},
});
// 如果获取成功,则把新的 token 更新到容器中
console.log("刷新 token 成功", res);
store.commit("setUser", {
token: res.data.data.token, // 最新获取的可用 token
refresh_token: user.refresh_token, // 还是原来的 refresh_token
});
return request(error.config);
} catch (err) {
// 如果获取失败,直接跳转 登录页
console.log("请求刷线 token 失败", err);
router.push("/login");
}
}
return Promise.reject(error);
}
);
export default request;
四、在main.js文件内全局注册store、axios
import Vue from "vue";
import App from "./App.vue";
import router from "./router"; // 路由对象
import store from "./store"; // 管理用户token
import axios from "axios";
... ...
new Vue({
router,
store,
render: (h) => h(App),
}).$mount("#app");
五、新建api文件夹,存放接口文件
// 存储接口封装,用户相关的请求模块
import request from "@/utils/request.js";
// export const login = (user) => {
// return request({
// url: '', // 接口地址
// method: 'POST', 'GET', // 请求方式
// // 如果参数通过请求体来发(post),用data是请求体参数
// // 如果参数通过请求行来发(get),用params是路径参数
// data: user
// })
// }
// 用户登录
export const login = (data) => {
return request({
method: "POST",
url: "/admin/login",
data,
});
};
// 需要携带 token 获取数据时,携带登陆成功后存储在本地的token值
// 查询所有使用记录
export const listRecord = () => {
return request({
method: "GET",
url: "/admin/record/listRecord",
headers: {
"X-Token": localStorage.getItem("X-Token"),
},
});
};
// 携带params参数,也是手动输入的值
export const others = (params) => {
return request({
method: "GET",
url: "/admin/others",
params,
});
};
六、在组件页面内调接口拿数据
接口使用例子1
1. 登录接口的使用(同注册),在页面导入接口
// 调用登录接口
import { login } from '@/api/user'
2. 通过async await 来拿到用户输入的值,根据返回结果进行判断返回相应提示
async onSubmit (values) {
// 手动输入提交的数据:登录、注册、修改密码等提交的值
let { mobile: vcPhone, password: vcLoginpassword } = values
const { data } = await login({ vcPhone, vcLoginpassword, })
console.log(data);
console.log("submit", values);
if (data.code == "200") {
this.$toast.success("登录成功");
this.$router.push({ name: "shouye" });
} else if (data.message == "没有注册,请先注册") {
this.$toast.fail(data.message);
} else if (data.message == "密码错误") {
this.$toast(data.message);
} else {
this.$toast.fail('操作异常,请重试')
}
console.log("submit", values);
},
注意:mobile、password是用户在data里定义的值,这里需要将拿到的值赋给自己定义的。
或者把data里的值改成和后端字段相同,此时可简写。
例如:
let { vcPhone, vcLoginpassword } = values
const { data } = await login({ vcPhone, vcLoginpassword, })
接口使用例子2
1. 通过接口获取数据进行渲染,这里把需要的接口解构出来
import { listRecord } from '@/api/user'
2. data定义需要渲染的数据(可与后端字段一致)
data () {
return {
recordFrom: {
vcReadid: "",
vcReaddate: "",
vcCurrremainmoney: "",
},
list: [], // 存放所有使用记录数据
loading: false,
finished: false,
};
},
3. 在方法里面调用接口,把拿到的数据放到一个自己定义的数组里面list
methods: {
async getAllusedRecord () {
try {
const { data } = await listRecord()
this.list = data
this.loading = false; // 加载状态结束
this.finished = true;
// console.log(this.list);
} catch (err) {
this.$toast('获取使用记录失败')
}
},
},
4. 通过v-for渲染获取到的数据
<ul v-for="item in list" :key="item.name" :title="item">
<li>
编号:{{ item.vcReadid }}
时间:{{ item.vcReaddate }}
金额:{{ item.vcCurrremainmoney }}
</li>
</ul>