Vue页面刷新路由传参与vuex数据丢失

image-20220928175435071

Vuex 刷新页面数据丢失

为什么刷新页面 Vuex 的数据会丢失

刷新页面 Vuex 的数据会丢失属于正常现象,因为 JS 的数据都是保存在浏览器的堆栈内存里面的,刷新浏览器页面,以前堆栈申请的内存被释放,这就是浏览器的运行机制,那么堆栈里的数据自然就清空了。

实现方式

  • Storage
  • 第三方 npm 包

Storage

推荐 sessionStorage,也可以用 localStorage,但是它没有期限;所以常用的还是 sessionStorage,当浏览器关闭时会话结束。将需要的数据存入 vuex 的 store 里,也将该数据存入 sessionStorage 里。

注意:vuex 中的变量是响应式的,而 sessionStorage 不是,当你改变 vuex 中的状态,组件会检测到改变,而 sessionStorage 就不会了,页面要重新刷新才可以看到改变,所以应让 vuex 中的状态从 sessionStorage 中得到,这样组件就可以响应式的变化。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const state = {
authInfo: JSON.parse(sessionStorage.getItem('COMPANY_AUTH_INFO')) || {}
}

const getters = {
authInfo: (state) => state.authInfo
}
const mutations = {
SET_COMPANY_AUTH_INFO(state, data) {
state.authInfo = data
sessionStorage.setItem('COMPANY_AUTH_INFO', JSON.stringify(data))
}
}

//actions 模块里无需使用 sessionStorage

export default {
namespaced: true,
state,
getters,
mutations
//actions,
}

第三方 npm 包

1、vuex-along

2、vuex-persistedstate

3、vuex-persist

Vue 路由传参页面刷新参数丢失

常见场景:点击列表的详情,跳转到详情页,在该页根据传递的参数获取详情数据。

这里的路由当然是 Vue Router 了。

不修改路由配置

使用 sessionStorage 来马上缓存(通常在 created 钩子函数中)获得的路由参数,这种方法要自己把握好什么时候 set,什么时候 get,什么时候 remove。

配置路由参数

单个参数优先考虑使用

1
2
3
4
5
{
path: '/detail/:id', //若id后面加?代表这个参数是可选的
name: 'detail',
component: Detail
}

通过 $router.push 中 path 携带参数的方式

1
2
3
4
5
6
7
8
9
// 列表中的传参
goDetail(row) {
this.$router.push({
path: `/detail/${row.id}`
})
}

// 详情页获取参数
this.$route.params.id

通过 $router.push 的 params 传参

1
2
3
4
5
6
7
8
9
10
11
12
// 列表页传参
goDetail(row) {
this.$router.push({
name: 'detail',
params: {
id: row.id
}
})
}

// 详情页获取
this.$route.params.id

使用 query

适用多个参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 路由配置
{
path: '/detail',
name: 'detail',
component: Detail
}

// 列表页
goDetail(row) {
this.$router.push({
path: '/detail',
query: {
id: row.id
}
})
}

// 详情页
this.$route.query.id

注意:在所有的子组件中获取路由参数是 $route 不是 $router

params 与 query 区别

当使用 params 方法传参的时候,要在路由后面加参数名,成为路由的一部分,并且传参的时候,参数名要跟路由后面设置的参数名对应。使用 query 方法,就没有这种限制,直接在跳转里面用就可以,另外 query 是拼接在 url 后面的参数,没有也没关系。

使用 props 配合组件路由解耦

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 路由配置
{
path: '/detail/:id',
name: 'detail',
component: Detail,
props: true // 如果props设置为true,$route.params将被设置为组件属性
}

// 列表页
goDetail(row) {
this.$router.push({
path: '/detail',
query: {
id: row.id
}
})
}

// 详情页
export default {
props: {
// 将路由中传递的参数id解耦到组件的props属性上
id: String
},
mounted: {
console.log(this.id)
}
}

相关链接

[1] 编程式导航