刷新页面时vue实例重新加载,store就会被重置,可以把定义刷新前把store存入本地localStorage、sessionStorage、cookie中,localStorage是永久储存,重新打开页面时会读取上一次打开的页面数据,sessionStorage是储存到关闭为止,cookie不适合存大量数据。根据我的需求,最合适的是sessionStorage。beforeunload在页面刷新时触发,可以监听这个方法,让页面在刷新前存store到sessionStorage中。当然,在页面刷新时还要读取sessionStorage中的数据到store中,读取和储存都写在app.vue中。
export default {
name: 'app',
created () {

// 在页面加载时读取sessionStorage

if (sessionStorage.getItem('store')) {

this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('store'))))

}

// 在页面刷新时将store保存到sessionStorage里

window.addEventListener('beforeunload', () => {

sessionStorage.setItem('store', JSON.stringify(this.$store.state))

})
}
}
export default {
name: 'app',
created () {

// 在页面加载时读取sessionStorage

if (sessionStorage.getItem('store')) {

this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('store'))))

}

// 在页面刷新时将store保存到sessionStorage里

window.addEventListener('beforeunload', () => {

sessionStorage.setItem('store', JSON.stringify(this.$store.state))

})
}
}补充知识:vue项目将token存在(vuex)store和localstorage中补充知识:补充知识:vue项目将token存在(vuex)store和localstorage中一、准备工作和token一、准备工作和token1、准备工作1、准备工作了解(session,cookie)tokenToken的引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。token 是在服务端产生的一串字符串,以作客户端进行请求的一个令牌。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位。如果这个 Token 在服务端持久化(比如存入数据库),那它就是一个永久的身份令牌(除非设置了有效期)。token 优点Token 完全由应用管理,所以它可以避开同源策略Token 可以避免 CSRF 攻击Token 可以是无状态的,可以在多个服务间共享减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。安装vuex安装vuex
cnpm install vuex --save
cnpm install vuex --save2、介绍token用法2、介绍token用法在前后端完全分离的情况下,Vue项目中实现token验证大致思路如下:1、第一次登录的时候,前端调后端的登陆接口,发送用户名和密码2、后端收到请求,验证用户名和密码,验证成功,就给前端返回一个token3、前端拿到token,将token存储到localStorage和vuex中,并跳转路由页面4、前端每次跳转路由,就判断 localStroage 中有无 token ,没有就跳转到登录页面,有则跳转到对应路由页面5、每次调后端接口,都要在请求头中加token6、后端判断请求头中有无token,有token,就拿到token并验证token,验证成功就返回数据,验证失败(例如:token过期)就返回401,请求头中没有token也返回4017、如果前端拿到状态码为401,就清除token信息并跳转到登录页面二、创建storage,store,request二、创建storage,store,request1、src目录:注:创建storage是可选的,因为我把localstorage(缓存)封装到了storage.js(本文后续代码均是用自己封装的js);创建store是必须的!2、创建storage(可选)
// 封装操作localstorage本地存储的方法 模块化

var storage = {

set(key, value) {

localStorage.setItem(key, JSON.stringify(value));

// localStorage.key = value;

// localStorage[key] = value;

},

get(key) {

return JSON.parse(localStorage.getItem(key));

},

getForIndex(index) {

return localStorage.key(index);

},

getKeys(){

let items = this.getAll();

let keys = [];

for (let index=0;index
keys.push(items[index].key);

}

return keys;

},

getLength() {

return localStorage.length;

},

getSupport() {

return (typeof (Storage) !== "undefined") ? true : false;

},

remove(key) {

localStorage.removeItem(key);

},

removeAll() {

localStorage.clear();

},

getAll() {

let len = localStorage.length; // 获取长度

let arr = new Array(); // 定义数据集

for (var i = 0; i < len; i++) {

// 获取key 索引从0开始

var getKey = localStorage.key(i);

// 获取key对应的值

var getVal = localStorage.getItem(getKey);

// 放进数组

arr[i] = {

'key': getKey,

'val': getVal,

}

}

return arr;

}
}

export default storage;

// 封装操作localstorage本地存储的方法 模块化

var storage = {

set(key, value) {

localStorage.setItem(key, JSON.stringify(value));

// localStorage.key = value;

// localStorage[key] = value;

},

get(key) {

return JSON.parse(localStorage.getItem(key));

},

getForIndex(index) {

return localStorage.key(index);

},

getKeys(){

let items = this.getAll();

let keys = [];

for (let index=0;index
keys.push(items[index].key);

}

return keys;

},

getLength() {

return localStorage.length;

},

getSupport() {

return (typeof (Storage) !== "undefined") ? true : false;

},

remove(key) {

localStorage.removeItem(key);

},

removeAll() {

localStorage.clear();

},

getAll() {

let len = localStorage.length; // 获取长度

let arr = new Array(); // 定义数据集

for (var i = 0; i < len; i++) {

// 获取key 索引从0开始

var getKey = localStorage.key(i);

// 获取key对应的值

var getVal = localStorage.getItem(getKey);

// 放进数组

arr[i] = {

'key': getKey,

'val': getVal,

}

}

return arr;

}
}

export default storage;
3、创建store
import Vue from 'vue'
import Vuex from 'vuex'
import storage from '@/model/storage'

Vue.use(Vuex);
// 用Vuex.Store对象用来记录token
const store = new Vuex.Store({

state: {

// 存储token

// token: storage.get('token') ? storage.get('token') : '',

token:"",

userName:"" // 可选
},

actions: {

// removeToken: () => {

// context.commit('set_token')

// }
},

// 计算属性
mutations: {

// 修改token,并将token存入localStorage

set_token(state,token) {

state.token = token;

storage.set('token', token);

console.log('store、localstorage保存token成功!');

},

del_token(state) {

state.token = "";

storage.remove("token");

},

// 可选

setUserInfo(state, userName) {

state.userName = userName;

}
}
});

export default store;

import Vue from 'vue'
import Vuex from 'vuex'
import storage from '@/model/storage'

Vue.use(Vuex);
// 用Vuex.Store对象用来记录token
const store = new Vuex.Store({

state: {

// 存储token

// token: storage.get('token') ? storage.get('token') : '',

token:"",

userName:"" // 可选
},

actions: {

// removeToken: () => {

// context.commit('set_token')

// }
},

// 计算属性
mutations: {

// 修改token,并将token存入localStorage

set_token(state,token) {

state.token = token;

storage.set('token', token);

console.log('store、localstorage保存token成功!');

},

del_token(state) {

state.token = "";

storage.remove("token");

},

// 可选

setUserInfo(state, userName) {

state.userName = userName;

}
}
});

export default store;
4、创建request
import axios from 'axios'
import store from '@/store'
import router from '@/router'

// create an axios instance
const service = axios.create({

// index.js设置了代理(解决跨域) invoice = http://58.246.79.142:25005

baseURL: "/invoice", // url = base url + request url

timeout: 5000, // request timeout

}

})

//添加请求拦截器,若token存在则在请求头中加token,不存在也继续请求
service.interceptors.request.use(

config => {

// 每次发送请求之前检测都vuex存有token,那么都要放在请求头发送给服务器,没有则不带token

// Authorization是必须的

if (store.state.token) {

config.headers.Authorization = store.state.token;

}

return config;

},

error => {

console.log("在request拦截器显示错误:", error.response)

return Promise.reject(error);

}
);

//respone拦截器
service.interceptors.response.use(

response => {

// 在status正确的情况下,code不正确则返回对应的错误信息(后台自定义为200是正确,并且将错误信息写在message),正确则返回响应

return response.data.code == 200 ? response : Promise.reject(response.data.message);

},

error => {

// 在status不正确的情况下,判别status状态码给出对应响应

if (error.response) {

console.log("在respone拦截器显示错误:", error.response)

switch (error.response.status) {

case 401:

//可能是token过期,清除它

// this.$store.commit("del_token");

store.commit("del_token");


router.replace({ //跳转到登录页面

path: '/login',

// 将跳转的路由path作为参数,登录成功后跳转到该路由

query: { redirect: router.currentRoute.fullPath }

});

}

}

return Promise.reject(error.response.data);

}
);


export default service

import axios from 'axios'
import store from '@/store'
import router from '@/router'

// create an axios instance
const service = axios.create({

// index.js设置了代理(解决跨域) invoice = http://58.246.79.142:25005

baseURL: "/invoice", // url = base url + request url

timeout: 5000, // request timeout

}

})

//添加请求拦截器,若token存在则在请求头中加token,不存在也继续请求
service.interceptors.request.use(

config => {

// 每次发送请求之前检测都vuex存有token,那么都要放在请求头发送给服务器,没有则不带token

// Authorization是必须的

if (store.state.token) {

config.headers.Authorization = store.state.token;

}

return config;

},

error => {

console.log("在request拦截器显示错误:", error.response)

return Promise.reject(error);

}
);

//respone拦截器
service.interceptors.response.use(

response => {

// 在status正确的情况下,code不正确则返回对应的错误信息(后台自定义为200是正确,并且将错误信息写在message),正确则返回响应

return response.data.code == 200 ? response : Promise.reject(response.data.message);

},

error => {

// 在status不正确的情况下,判别status状态码给出对应响应

if (error.response) {

console.log("在respone拦截器显示错误:", error.response)

switch (error.response.status) {

case 401:

//可能是token过期,清除它

// this.$store.commit("del_token");

store.commit("del_token");


router.replace({ //跳转到登录页面

path: '/login',

// 将跳转的路由path作为参数,登录成功后跳转到该路由

query: { redirect: router.currentRoute.fullPath }

});

}

}

return Promise.reject(error.response.data);

}
);


export default service
三、配置代理,封装路由router、设置路由守卫,在main.js中引入router三、配置代理,封装路由router、设置路由守卫,在main.js中引入router一、配置代理一、配置代理二、封装路由router,并设置路由守卫二、封装路由router,并设置路由守卫
/* eslint-disable */
import Vue from 'vue'
import Router from 'vue-router'
import Main from '@/main/index'

import store from '@/store'
import storage from '@/model/storage'

Vue.use(Router)

const routes = [
{

path: '/',

name: 'Main',

redirect: '/login',

// 某些页面规定必须登录后才能查看 ,可以在router中配置meta,将需要登录的requireAuth设为true,

meta: {

requireAuth: true,

}
},

{

path: '/login',

component: () => import('@/views/login'),
},

{

path: '/invoice',

redirect: '/invoice',

component: Main,
},


]
},
{

path: '*',

component: Main
}
]

const router = new Router({ routes: routes })

// 设置路由守卫,在进页面之前,判断有token,才进入页面,否则返回登录页面
if (storage.get("token")) {
store.commit("set_token", storage.get("token"));
}
router.beforeEach((to, from, next) => {
// 判断要去的路由有没有requiresAuth
// to.matched.some(r => r.meta.requireAuth) or to.meta.requiresAuth
if (to.matched.some(r => r.meta.requireAuth)) {

if (store.state.token) {

next(); //有token,进行request请求,后台还会验证token

} else {

next({

path: "/login",

// 将刚刚要去的路由path(却无权限)作为参数,方便登录成功后直接跳转到该路由,这要进一步在登陆页面判断

query: { redirect: to.fullPath }

});

}
} else {

next(); //如果无需token,那么随它去吧
}
});

export default router

/* eslint-disable */
import Vue from 'vue'
import Router from 'vue-router'
import Main from '@/main/index'

import store from '@/store'
import storage from '@/model/storage'

Vue.use(Router)

const routes = [
{

path: '/',

name: 'Main',

redirect: '/login',

// 某些页面规定必须登录后才能查看 ,可以在router中配置meta,将需要登录的requireAuth设为true,

meta: {

requireAuth: true,

}
},

{

path: '/login',

component: () => import('@/views/login'),
},

{

path: '/invoice',

redirect: '/invoice',

component: Main,
},


]
},
{

path: '*',

component: Main
}
]

const router = new Router({ routes: routes })

// 设置路由守卫,在进页面之前,判断有token,才进入页面,否则返回登录页面
if (storage.get("token")) {
store.commit("set_token", storage.get("token"));
}
router.beforeEach((to, from, next) => {
// 判断要去的路由有没有requiresAuth
// to.matched.some(r => r.meta.requireAuth) or to.meta.requiresAuth
if (to.matched.some(r => r.meta.requireAuth)) {

if (store.state.token) {

next(); //有token,进行request请求,后台还会验证token

} else {

next({

path: "/login",

// 将刚刚要去的路由path(却无权限)作为参数,方便登录成功后直接跳转到该路由,这要进一步在登陆页面判断

query: { redirect: to.fullPath }

});

}
} else {

next(); //如果无需token,那么随它去吧
}
});

export default router
三、在main.js中引入router三、在main.js中引入router
import Vue from 'vue'
// import Vuex from 'vuex'
import App from './App'
import router from './router'

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'
// import VueResource from 'vue-resource'
// import axios from 'axios'

// 兼容ie
// import 'babel-polyfill';

Vue.use(ElementUI);
// Vue.use(Vuex);
// Vue.use(VueResource);
// Vue.use(axios);

Vue.config.productionTip = false
Vue.component(CollapseTransition.name, CollapseTransition)
// this.$ajax 全局使用axios
// Vue.prototype.$ajax=axios;

new Vue({
el: '#app',
router:router,
components: { App },
template: ''
})

import Vue from 'vue'
// import Vuex from 'vuex'
import App from './App'
import router from './router'

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'
// import VueResource from 'vue-resource'
// import axios from 'axios'

// 兼容ie
// import 'babel-polyfill';

Vue.use(ElementUI);
// Vue.use(Vuex);
// Vue.use(VueResource);
// Vue.use(axios);

Vue.config.productionTip = false
Vue.component(CollapseTransition.name, CollapseTransition)
// this.$ajax 全局使用axios
// Vue.prototype.$ajax=axios;

new Vue({
el: '#app',
router:router,
components: { App },
template: ''
})
四、登录页面实际使用四、登录页面实际使用只给出表单提交示例函数和依赖js
import { postLogin } from "@/api/login";

submitForm(formName) {

this.$refs[formName].validate(valid => {

if (valid) {

let that = this;

// console.log('username',this.loginForm.username)

// 通过校验规则后进入校验用户名密码是否正确

postLogin(this.loginForm.username, this.loginForm.password)

.then(res => {

console.log(res);



that.$store.commit("set_token", res.data.token);

that.$store.commit("setUserInfo", res.data.account);


this.$notify({

title: "登录成功",

type: "success",

showClose: false,

duration: 1000

});

setTimeout(() => {

// 此时要判断/login后面的参数,若无参数,进入主页;

this.$router.push("/index");

// 若有参数则参数为未有权限的那个路由,跳转到那个路由

// this.$router.push(***); -- 具体要自己在这实现

}, 1000);

})

.catch(error => {

// 错误分为 status-请求错误 和 code-账号密码错误

this.$message.error(error);

console.log(error);

});

} else {

// 不符合前端校验

this.$message.error('format error:'+error);

console.log('format error:',error);

return false;

}

});

}

import { postLogin } from "@/api/login";

submitForm(formName) {

this.$refs[formName].validate(valid => {

if (valid) {

let that = this;

// console.log('username',this.loginForm.username)

// 通过校验规则后进入校验用户名密码是否正确

postLogin(this.loginForm.username, this.loginForm.password)

.then(res => {

console.log(res);



that.$store.commit("set_token", res.data.token);

that.$store.commit("setUserInfo", res.data.account);


this.$notify({

title: "登录成功",

type: "success",

showClose: false,

duration: 1000

});

setTimeout(() => {

// 此时要判断/login后面的参数,若无参数,进入主页;

this.$router.push("/index");

// 若有参数则参数为未有权限的那个路由,跳转到那个路由

// this.$router.push(***); -- 具体要自己在这实现

}, 1000);

})

.catch(error => {

// 错误分为 status-请求错误 和 code-账号密码错误

this.$message.error(error);

console.log(error);

});

} else {

// 不符合前端校验

this.$message.error('format error:'+error);

console.log('format error:',error);

return false;

}

});

}
上面依赖的@/api/login:
import request from '@/utils/request.js'

export function postLogin(account,password) {

console.log(account,password)

return request({

url: '/login',

method: 'post',

params:{

// 具体传参(键)要看后台要求

account:account,

password:password

}

})
}

import request from '@/utils/request.js'

export function postLogin(account,password) {

console.log(account,password)

return request({

url: '/login',

method: 'post',

params:{

// 具体传参(键)要看后台要求

account:account,

password:password

}

})
}
以上这篇解决vue刷新页面以后丢失store的数据问题就是小编分享给大家的全部内容了,希望能给大家一个参考。