功能
- 像搜索功能,在点击某项进入详情页,再回到搜索界面,如果不做特殊处理,初始化到原来的状态,在vue中可以使用keep-alive缓存搜索界面,达到数据不刷新的结果。
思路
- 在搜索路由对象的meta添加一个keepAlive属性,值为true,表示在路由切换的时候,会被缓存。这样一来搜索界面的数据不会被初始化。
缓存界面
- keepAlive如果为true,就会使用keep-alive缓存起来,否则就不会被缓存
router
{
path: '/search',
name: 'Search',
meta:{
keepAlive: true
},
component: Search
}
App.js
<template>
<div id="app">
<keep-alive>
<router-view v-if="$route.meta.keepAlive" />
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" />
</div>
</template>
初始化数据
- 但是有时候只需要 搜索界面 进入 详情页 才需要缓存,当搜索界面进入 非详情页 时,再回到 搜索界面,希望 清除界面的 数据,可通过 vm.$data 初始化 data 数据,但此时 不能直接 赋值,vue的 data 是一个函数,因此可以 通过调用 vm.$options.data() 返回一份 原始的 data,再使用 Object.assign() 合并 vm.$data、原始data。
// 当前往首页时,初始化 data
backHome(){
// 初始化数据
Object.assign(this.$data, this.$options.data())
this.$router.replace('/home')
}
效果一
- 此时可以实现 进入详情页,返回搜索界面 数据不刷新,进入首页,返回 搜索界面 数据初始化 的效果,但 搜索界面 滚动条的 滑动距离 会置为0,因此 不是我 们想要的。
还原滚动条的滑动距离
- 在生命周期 mounted 为DOM元素绑定 onscroll 事件,实时 保存 滑动的距离
mounted(){
// 为了使this指向组件实例, 需要使用箭头函数
this.$refs.searchList.addEventListener('scroll', () =>{
// 实时 滑动的距离 会保存在 vuex中,也可以保存在 session storage中
this.$store.commit('setState', {searchTop: this.$refs.searchList.scrollTop})
})
}
还原滑动距离
- 使用 组件的 路由守卫钩子 beforeRouteEnter,当详情页 进入搜索页,取出滑动的 距离 scrollTop 并赋值,否则设置 滚动条的 距离为 0,因为 beforeRouteEnter 钩子函数 访问不了this,因此需要 通过 next的回调函数 访问 this(vm)。
beforeRouteEnter (to, from, next) {
next(vm =>{
// 详情页进入搜索页 初始化滚动条
if(from.name === 'Detail'){
vm.$refs.searchList.scrollTop = vm.$store.state.searchTop
}else{
// 非详情页进入搜索页 设置滚动条为初始值 0
vm.$store.commit('setState', {searchTop: 0})
}
})
}
效果二