vue列表页进入详情页,返回列表项不刷新

功能

  • 像搜索功能,在点击某项进入详情页,再回到搜索界面,如果不做特殊处理,初始化到原来的状态,在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,因此 不是我 们想要的。

还原滚动条的滑动距离

绑定onscroll 事件

  • 在生命周期 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})
        }
    })
}

效果二

posted @ 2020-02-29 16:42  车神我也  阅读(3692)  评论(0编辑  收藏  举报

目录列表

顶部