若依面包屑导航保存表单数据

本文最后更新于 2024年6月14日 晚上

若依面包屑导航保存表单数据

解决的问题

bff5d33e-b4aa-4bb5-85aa-b378c5367f28

面包屑并不是类似操作系统的多窗口, 仅仅是把页面的路由数据存起来, 作为一个标签展示在页面上, 直接切换的话还是会重新进入对应的页面, 这就会导致本来在页面上输入的数据切换标签页后会被清空

解决方案

利用Vuex将页面上的数据进行存储,只要浏览器标签页不被关闭或刷新,Vuex的数据就会一直存在,所以:

1. 从标签页1跳转到标签页2之前(组件路由守卫`beforeRouteLeave`),将标签页1中的数据存放到`Vuex`
1. 标签页2(或其他标签页)跳转到标签页1时(组件路由守卫`beforeRouteEnter`),从`Vuex`中读取存放的数据,如果有就赋值给`data`中对应的数据

默认都是使用了若依的Vue-Router, 封装好了导航守卫

代码实现

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<!-- Tag Page 1 -->
<template>...</template>
<script>
export default {
data() {
return {
...,
// queryParams是用户输入的一些信息
queryParams: {
type: '',
...
}
}
},
/**
* 路由跳转到这一页之前会触发下面的方法
*
* @param to 当前页的route对象
* @param from 上一页的route对象
* @param next
*/
beforeRouteEnter(to, from, next) {
// 这里的vm指当前页的(也就是to所指向的页面)Vue实例(this)
// 因为触发此路由守卫时该页面还未被创建,所以需要由next中的方法去触发
// 具体参考 完整的导航解析流程
next(vm => {
// 这里的params对应下面beforeRouteLeave中的params,根据需求自定义格式
let params = vm.$store.state.tagsView.viewsParams[to.fullPath];
if (params && params.queryParams) vm.queryParams = params.queryParams
})
},
/**
* 此页面路由跳转到其他页面之前会触发下面的方法
*
* @param to 下一页的route对象
* @param from 当前页的route对象
* @param next
*/
beforeRouteLeave(to, from, next) {
// 将数据存到Vuex中
// params可以根据自己的需求更改内容,只要和beforeRouteEnter中赋值的方法对应上即可
this.$store.dispatch("tagsView/addViewParams", {
view: from,
params: {
queryParams: this.queryParams
}
});
// 触发跳转
next()
}
}
</script>
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// /src/store/modules/tagsView.js

const state = {
visitedViews: [],
cachedViews: [],
//用来保存页面的一些数据,方便面包屑切换时保留数据
viewsParams: {}
}

const mutations = {
ADD_VISITED_VIEW: (state, view) => {...},
ADD_CACHED_VIEW: (state, view) => {...},
// 使用页面route对象的fullPath作为索引,防止重复
ADD_VIEWS_PARAMS: (state, {view, params}) => {
state.viewsParams[view.fullPath] = params
},

DEL_VISITED_VIEW: (state, view) => {...},
DEL_CACHED_VIEW: (state, view) => {...},
DEL_VIEWS_PARAMS: (state, view) => {
delete state.viewsParams[view.fullPath]
},

DEL_OTHERS_VISITED_VIEWS: (state, view) => {...},
DEL_OTHERS_CACHED_VIEWS: (state, view) => {...},
DEL_OTHERS_VIEWS_PARAMS: (state, view) => {
let tempParams = state.viewsParams[view.fullPath]

state.viewsParams = {}

state.viewsParams[view.fullPath] = tempParams
},

DEL_ALL_VISITED_VIEWS: state => {...},
DEL_ALL_CACHED_VIEWS: state => {...},
DEL_ALL_VIEWS_PARAMS: state => {
state.viewsParams = {}
},

UPDATE_VISITED_VIEW: (state, view) => {...},

DEL_RIGHT_VIEWS: (state, view) => {
...
if (i > -1) {
state.cachedViews.splice(i, 1)
delete state.viewsParams[item.fullPath]
}
...
},

DEL_LEFT_VIEWS: (state, view) => {
...
if (i > -1) {
state.cachedViews.splice(i, 1)
delete state.viewsParams[item.fullPath]
}
...
}

const actions = {
addView({dispatch}, view) {...},
addVisitedView({commit}, view) {...},
addCachedView({commit}, view) {...},
addViewParams({commit}, data) {
commit("ADD_VIEWS_PARAMS", data)
},

delView({dispatch, state}, view) {
return new Promise(resolve => {
dispatch('delVisitedView', view)
dispatch('delCachedView', view)
dispatch('delViewParams', view)
// dispatch('delView')
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews],
viewsParams: {...state.viewsParams}
})
})
},
delVisitedView({commit, state}, view) {...},
delCachedView({commit, state}, view) {...},
delViewParams({commit, state}, view) {
return new Promise(resolve => {
commit('DEL_VIEWS_PARAMS',view)
resolve({...state.viewsParams})
})
},

delOthersViews({dispatch, state}, view) {
return new Promise(resolve => {
dispatch('delOthersVisitedViews', view)
dispatch('delOthersCachedViews', view)
dispatch('delOthersViewsParams', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews],
viewsParams: {...state.viewsParams}
})
})
},
delOthersVisitedViews({commit, state}, view) {...},
delOthersCachedViews({commit, state}, view) {...},
delOthersViewsParams({commit, state}, view) {
return new Promise(resolve => {
commit('DEL_OTHERS_VIEWS_PARAMS', view)
resolve({...state.viewsParams})
})
},

delAllViews({dispatch, state}, view) {
return new Promise(resolve => {
dispatch('delAllVisitedViews', view)
dispatch('delAllCachedViews', view)
dispatch('delAllViewsParams')
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews],
viewsParams: {...state.visitedViews}
})
})
},
delAllVisitedViews({commit, state}) {...},
delAllCachedViews({commit, state}) {...},
delAllViewsParams({commit, state}) {
return new Promise(resolve => {
commit('DEL_ALL_VIEWS_PARAMS')
resolve({...state.viewsParams})
})
},

updateVisitedView({commit}, view) {...},

delRightTags({commit}, view) {...},

delLeftTags({commit}, view) {...}
}

export default {
...
}

修改好tagView,js后,就可以将需要存放的数据放到viewsParams

使用时的viewsParams

这样只需要在对应的页面中加入beforeRouterEnterbeforeRouterLeave方法即可

其他问题

下拉框显示错误

image-20220623143139118

原因: 主要是因为下拉框的绑定的数组也是从后台请求到的数据, 路由跳转后赋值只会使下拉框绑定的值有值,而下拉选项的数组还是空的

解决: 可以在给参数赋值之前调用methods中对应的方法请求下拉选项对应的数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
beforeRouteEnter(to, from, next) {
next(vm => {
let params = vm.$store.state.tagsView.viewsParams[to.fullPath];
if (params && params.queryParams) {
// 如果保存的数据中存在省的数据,就调用methods中的getCityListByProvinceid获取市下拉列表的数据
if (params.queryParams.province) vm.getCityListByProvinceid(params.queryParams.province)
// 如果保存的数据中存在市的数据,就调用methods中的getTownListByCityid获取县下拉列表的数据
if (params.queryParams.city) vm.getTownListByCityid(params.queryParams.city)
vm.queryParams = params.queryParams
}
})
},
...

参考

  1. 完整的导航解析流程

若依面包屑导航保存表单数据
https://tippye.github.io/2022/06/23/若依面包屑导航保存表单数据/
作者
Tippy
发布于
2022年6月23日
许可协议