开发两问题
vue项目开发的两个问题的答案
1.解决 vuex 中的数据在页面刷新之后就丢失的问题
在vue的项目中我们一般都会使用到vuex,在vuex中我们会保存一个需要全局使用的变量或者状态,这样方便我们使用。但是vuex的store中的数据有一个特性,那就是在页面刷新时,页面会重新加载vue实例,store里面的数据就会被重新赋值,这样就会出现页面刷新vuex中的数据丢失的问题。
第一种解决办法:
将状态同步保存到localStorage中,下面的例子列出了两种格式的数据保存,分别是字符串格式和对象格式
state中存储数据:
state: {
tabActiveName: localStorage.getItem('tabActiveName') || '',
user: JSON.parse(localStorage.getItem('user')) || {}
}
mutation中保存提交的数据
setTabActiveName (state, payload) {
localStorage.setItem('tabActiveName', payload)
state.tabActiveName = payload
},
login (state, payload) {
localStorage.setItem('user', JSON.stringify({...payload}))
state.user = {...payload}
}
这样当每次程序commit mutation更新状态时,同步到localStorage中,当F5刷新后,state中的状态会从localStorage中读取
也可以直接在App.vue的js 部分的 created 中写上这几行代码,
//在页面加载时读取sessionStorage里的状态信息
if (sessionStorage.getItem("store") ) {
this.$store.replaceState(Object.assign({},this.$store.state,JSON.parse(sessionStorage.getItem("store"))))
}
//在页面刷新时将vuex里的信息保存到sessionStorage里
window.addEventListener("beforeunload",()=>{
sessionStorage.setItem("store",JSON.stringify(this.$store.state))
})
这样就能在页面刷新时把store的数据存到sessionStorage中,并且在页面加载时及时获取到数据。
这里之所以使用sessionStorage,是因为sessionStorage的存在时间是当页面打开时存在,页面一关闭就会自动清除,能保证下次一进来页面使用的仍是新数据,不是上次存储的数据。store插件介绍
第二种:利用插件
第一个插件:store
这里我们用了一个名叫store的插件,当然不用也是可以的,不过都得自己来写set、get略微麻烦一写。 store的插件就是把Storage的set、get等封装,使用起来更方便。
自2.x以来,功能也是越来越强大
// === store(key, data); store.set(key, data[, overwrite]);
// === store({key: data, key2: data}); store.setAll(data[, overwrite]);
// === store(key); store.get(key[, alt]);
// === store(); store.getAll([fillObj]);
// === store(key, fn[, alt]); store.transact(key, fn[, alt]);
// === store(false); store.clear();
// returns true or false store.has(key);
// removes key and its data, then returns the data store.remove(key);
// fn receives key and data (or fill), return false to exit early store.each(fn[, fill]);
// concats, merges, or adds new value into existing one store.add(key, data);
// returns array of keys store.keys([fillList]);
// number of keys, not length of data store.size();
// clears *ALL* areas (but still namespace sensitive) store.clearAll();
下面来看看具体使用示例
storage文件示例
Vuex+localStorage数据状态持久化
新建一个storage.js文件
import storage from 'store';
// 缓存数据的key const WEB_NAME = 'WEB_NAME';
export const storage = {
set setLocalStorageName(val) {
if (!val) {
storage.remove(WEB_NAME);
} else {
storage.set(WEB_NAME, val);
}
},
get getLocalStorageName() {
return storage.get(WEB_NAME);
}
}
store文件示例
新建一个store.js文件,同时引入上面的storage.js文件
import Vue from 'vue'
import Vuex from 'vuex'
import { storage } from './storage';
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
// 默认读取storage里面的数据
name: storage.setLocalStorageName || ''
},
mutations: {
setData (state, data) {
// 拿到数据有,向state和storage里面都放入数据
state.name = data storage.setLocalStorageName = data;
}
},
actions: {
getData ({ commit, state }, params) {
let name = 'web秀 Vuex+localStorage数据状态持久化';
commit('name', name)
}
}
})
export default store
这样在使用Vuex state的时候,强制刷新页面等操作都不会清除name值,只有手动清除火车set 空值进去才可以清除name了。
第二个插件 vuex-persistedstate
首先安装插件,
npm install vuex-persistedstate --save
然后在store的index.js中写上下面这些代码
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState({
storage: window.sessionStorage
})]
})
我们就把vuex中的数据存储起来了,同样我们在页面加载时再次把sessionStorage中的数据存到vuex中,就可以了。
其实这2种方法的本质是一样,而且第一种方法的代码少,还不用下载插件,个人推荐使用这样
注意:
上面说的不用store的插件也是可以的,怎么解决了?只需要将store.js文件里面用到storage的地方换成对应的get、set即可。
小提示:localStorage.setItem(key, String), set的值必须是字符串,如果你的数据是对象都需要先行转换(JSON.stringify(xxx)),取出时localStorage.getItem(key),如果不是字符串,取出后可以通过JSON.parse(xxx)转回对象。
2. this.router和 this.route的区别
1. 跳转
-
this.$route 是当前路由跳转对象,包含当前路由的name、path、query、params等属性
-
this.$router 是路由导航对象,使用它跳转到其他不同url地址
2. 获取值
- this.$router(获取全局的路由对象),项目中通过router路由参数注入路由之后,在任何一个页面都可以通过此方法获取到路由器对象,并调用其push(), go()等方法
- this.$route(当前的路由对象),可以调用其name、path、query、params等方法
3. 注入的属性
通过在 Vue 根实例的 router
配置传入 router 实例,下面这些属性成员会被注入到每个子组件。
-
this.$router
router 实例。
-
this.$route
当前激活的路由信息对象。这个属性是只读的,里面的属性是 immutable (不可变) 的,不过你可以 watch (监测变化) 它。
4.语法
this.$router
路由的操作阶段, 路由跳转
语法:
两种传参数形式, params 和 query
this.$router.push({path: ‘路径’, name: ‘路由名称’, params: ‘对象,传递的参数’, query: ‘对象,传递的参数’})
this.$router.go() // 数值或对象,即前进或后退.负数后退,整数前进,赋值操作一目了然
this.$route
路由的获取阶段, 单个路由
语法:
两种传参数形式, params 和 query
this.$route.[path | name | params | query]
eg: this.$route.path ⇒ ‘路径’