cloud_music项目模拟浏览器前进后退功能
模拟浏览器前进后退功能
写网易云前进后退的时候遇到了这个问题, 所以用router和vuex做了一个管理history的功能
一、问题发现
1.1. 仅仅为前进后退绑定事件
- history.go()
- history.forward()
- history.back()
1.2 发现的问题
- 无法在没有的前进/后退的时候动态的显示可以点击的按钮
- 正常状态下
二、开始的解决方法
2.1 设立Vue.prototype.$http = []来存放, 在每次路由变换的时候添加地址
- 但是存放在$http里面的不能为前进/后退动态绑定按钮
2.2 存放在vuex中
- 但是在router中无法调出vuex
三、最终解决方法
3.1 绑定好router与vuex
let that = null
router.beforeEach((to, from, next) => {
// 把实例化的VUE保存在that中
if (!that) that = router.app
// types.ADD_HISTORY为vuex中mutations的一个方法
// 使用router.app.$options.store可以调出vuex
// 与把sroter文件暴露出来的store给import进来也一样
that.$options.store.commit(types.ADD_HISTORY, urlJointQuery(to.path, to.query))
next()
})
function urlJointQuery (url, query) {
const queryArr = []
// 如果query是一个空对象则直接返回url
if (!Object.keys(query).length) return url
// 不是空对象则拼接到url后面
for (const key in query) {
queryArr.push(`${key}=${query[key]}`)
}
return `${url}?${queryArr.join('')}`
}
- 其中urlJointQuery为拼接url和query的方法
3.2 配置vuex的state与mutations
- mutations
[types.ADD_HISTORY] (state, path) {
const history = state.history
// 如果没有存放history则执行下面的
if (!history.pathArr) {
return history.pathArr.push(path)
}
// 有history执行这里
// 当要跳转的path为当前历史pathArr中的下一个的path
if (path === handlePath(history, 1)) {
history.prevPath = handlePath(history)
history.currentIndex++
if (history.pathArr.length > history.currentIndex) {
history.nextPath = handlePath(history, 1)
} else {
history.nextPath = null
}
// 当要跳转的path为当前历史pathArr中的上一个的path
} else if (path === handlePath(history, -1)) {
history.nextPath = handlePath(history)
history.currentIndex--
if (history.currentIndex > 0) {
history.prevPath = handlePath(history, -1)
} else {
history.prevPath = null
}
} else {
// 当要跳转的path为不同于任意currentIndex的path的时候
history.prevPath = handlePath(history)
history.nextPath = null
// 删掉之前那些要被新path代替的旧path
history.pathArr.splice(history.currentIndex + 1, history.pathArr.length - history.currentIndex)
history.pathArr.push(path)
history.currentIndex = history.pathArr.length - 1
}
}
- state
history: {
nextPath: null,
prevPath: null,
currentIndex: 0,
pathArr: []
}