store.js
import Vue from "vue"
import Vuex from "vuex"
/**
Vuex持久化存储之vuex-persist
Vuex 解决了多视图之间的数据共享问题。但是运用过程中又带来了一个新的问题是,
Vuex 的状态存储并不能持久化。也就是说当你存储在 Vuex 中的 store 里的数据,
只要一刷新页面,数据就丢失了。
引入vuex-persist 插件,它就是为 Vuex 持久化存储而生的一个插件。
不需要你手动存取 storage ,而是直接将状态保存至 cookie 或者 localStorage 中
*/
import VuexPersistence from "vuex-persist"
Vue.use(Vuex)
const vuexLocal = new VuexPersistence({
storage: window.localStorage,
})
/**
* State 提供唯一的公共数据源,所有共享的数据都要统一放到 Store 的 State 中进行存储。
*
* 只能通过 mutations 变更 Store 数据,不可以直接操作 Store 中的数据。
* 通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化。
*
* actions 用于处理异步任务。
* 如果通过异步操作变更数据,必须通过 actions,而不能使用 mutations,但是在 actions 中还是要通过触发
* mutations 的方式间接变更数据。
*
* getters 用于对 Store 中的数据进行加工处理形成新的数据。
*/
export default new Vuex.Store({
state: {
access_token: "",
refresh_token: "",
},
mutations: {
setAccessToken(state, param) {
state.access_token = param
},
setRefreshToken(state, param) {
state.refresh_token = param
},
removeAccessToken(state) {
state.access_token = ''
},
removeRefreshToken(state) {
state.refresh_token = ''
},
},
actions: {
setAccessToken(context, param) {
context.commit('setAccessToken', param)
},
setRefreshToken(context, param) {
context.commit('setRefreshToken', param)
},
removeAccessToken(context) {
context.commit('removeAccessToken')
},
removeRefreshToken(context) {
context.commit('removeRefreshToken')
}
},
getters: {
getAccessToken(state) {
return state.access_token
},
getRefreshToken(state) {
return state.refresh_token
}
},
plugins: [vuexLocal.plugin]
})
/*******************************************************************/
request.js
import axios from 'axios'
import store from '@/store'
import {
Toast
} from 'vant';
import router from '@/router/index';
export function request(config) {
// 1.创建axios的实例
const instance = axios.create({
baseURL: 'http://*********.com',
timeout: 5000
})
// 2.axios的拦截器
// 2.1.请求拦截的作用
instance.interceptors.request.use(config => {
// 获取token
//const token = store.getters.getToken
//token && (config.headers.Authorization = token)
return config
}, err => {
return Promise.reject(err);
})
// 2.2.响应拦截
instance.interceptors.response.use(res => {
if (res.data.code == 100101) {
Toast.success({
message: res.data.msg,
duration: 1.5 * 1000
})
store.dispatch('removeAccessToken')
store.dispatch('removeRefreshToken')
setTimeout(() => {
router.replace('/login')
}, 1500)
} else if (res.data.code == 100102 || res.data.code == 100103) {
store.dispatch('removeAccessToken')
store.dispatch('removeRefreshToken')
setTimeout(() => {
router.replace('/login')
}, 1500)
} else if (res.data.code == 100000) {
//处理正确结果
if (res.data.usertoken.length != 0) {
store.dispatch('setAccessToken',res.data.usertoken.access_token)
store.dispatch('setRefreshToken',res.data.usertoken.refresh_token)
}
return res.data
} else {
return res.data
}
}, err => {
Toast.fail({
message: err.message,
duration: 1.5 * 1000
})
return Promise.reject(err)
})
// 3.发送真正的网络请求
return instance(config)
}
/*********************************************************************************/
Login.vue
<template>
<div class="wm-login">
<div class="SignFlowHeader">
<h1></h1>
<p></p>
</div>
<div class="wm-form">
<van-form @submit="onSubmit">
<van-field
v-model="username"
name="username"
label="用户名"
placeholder="用户名"
:rules="[{ required: true, message: '请填写用户名' }]"
class="yonghuming"
/>
<van-field
v-model="password"
type="password"
name="password"
label="密码"
placeholder="密码"
:rules="[{ required: true, message: '请填写密码' }]"
/>
<div style="margin: 40px;">
<van-button round block type="info" native-type="submit">
登录
</van-button>
</div>
</van-form>
</div>
</div>
</template>
<script>
import Vue from 'vue'
import {login} from '@/model/login.js'
import { mapActions } from 'vuex'
import { Toast } from 'vant';
Vue.use(Toast);
//import axios from 'axios'
export default {
name:'Login',
data() {
return {
username:'',
password:''
}
},
methods: {
//将指定的 actions 函数,映射为当前组件的 methods 函数
...mapActions(['setAccessToken', 'setRefreshToken']),
onSubmit(values) {
//会员登录
login(this.username,this.password).then(res=>{
if(res.code == 100000){
this.setAccessToken(res.usertoken.access_token)
this.setRefreshToken(res.usertoken.refresh_token)
Toast.success({
message: res.msg,
duration: 1.5 * 1000
})
setTimeout(()=>{
this.$router.replace('/')
},1500)
}else{
Toast.fail({
message: res.msg,
duration: 1.5 * 1000
})
}
})
},
},
}
</script>
<style scoped="scoped">
.wm-login .SignFlowHeader{
padding-top: 10px;
text-align: center;
margin-top: 0px;
height: 108px;
color: #fff;
background: #1989fa;
}
.wm-login .SignFlowHeader h1 {
font-size: 30px;
margin-bottom: 10px;
}
.wm-login .SignFlowHeader p {
font-size: 16px;
}
.wm-form {
margin-top: 60px;
}
.van-field {
font-size: 20px;
}
.yonghuming {
margin-bottom: 30px;
}
</style>
/********************************************************************************/
<template>
<div class="home">
<van-sticky>
<van-nav-bar style="background-color: #FF5777;">
<template #title>
<span style="color: #FFFFFF;">首页</span>
</template>
</van-nav-bar>
</van-sticky>
<div class="wm-baodao">
<p>列表</p>
<van-cell title="查看" size='large' is-link to="/student" />
</div>
<div class="wm-baodao">
<p>流程</p>
<van-cell :title="report.snb_name" size='large' value="需缴费" is-link @click="gotodetail(report.snb_id)" />
</div>
</div>
</template>
<script>
// @ is an alias to /src
import Vue from 'vue';
import {
Toast
} from 'vant';
Vue.use(Toast);
import {
get_report
} from '@/model/home.js'
export default {
name: 'Home',
data() {
return {
report:{}
}
},
components: {},
created() {
//获取
get_report().then(res => {
if(res.code == 100000){
this.report = res.result
}else{
Toast.fail({
message: res.msg,
duration: 1.5 * 1000
})
}
});
},
methods: {
//将指定的 actions 函数,映射为当前组件的 methods 函数
//跳转详情
gotodetail(id) {
this.$router.push('/rep/detail/'+id)
}
},
}
</script>
<style scoped>
.wm-banzhuren {
height: 30px;
margin: 10px 15px;
}
.wm-baodao {
margin-top: 30px;
}
.wm-baodao p {
font-size: 17px;
font-weight: bold;
color: #1989fa;
margin: 10px 15px 5px;
border-bottom: 1px solid #1989FA;
}
</style>