设置滚动条切换页面回归原来位置

345 阅读2分钟

切换页面滚动条回到原来位置

切换页面,还原滚动条位置,一般是使用在新闻,列表之类的地方,在项目中,一般以两种形式为主;一种是动态组件切换的页面,一种是路由的页面。

动态组件:

<component :is='currcompont'></component>  
import interactive from "../../components/ranking/interactive.vue"
import { ref} from 'vue'
components:{
    interactive
}
setup(){
    const currcompont = ref(interactive)
    return{
        currcompont
    }
}

在页面退出页面之前获取滚动条离头部的距离(scrollTop),然后将获取的距离以对象形式(obj)存在本地或者vuex中(routeList),在进入页面的时候获取存储的值(scrollTop),然后进行过滤判断是否存在,存在就将值取出来赋值给scrollTop。

本地localStorage:

setup(){
    const path = ref('a页面')
    const createPage = () =>{
        const routeList =  JSON.parse(localStorage.getItem('routeList')) 
        const wrapper = document.querySelector('#app')
        // path 是我本地存储的一个路径
        routeList.find((v) => {
          return v.path === path.value
        })?.scrollTop
        // 赋值距离
        wrapper.scrollTop = top
    }
    beforeUnmount(()=>{
        const wrapper = document.querySelector('#app')
        const scrollTop = wrapper ? wrapper.scrollTop : 0
        const obj = {
          scrollTop: scrollTop,
          path: path.value,
        }
        // 以下可以写成一个公共方法,进行调用
        const routeList =  JSON.parse(localStorage.getItem('routeList')) 
        const idx = routeList?.findIndex((v) => v.path === path.value 
        let list = []
        // 判断是否存在,
        if (idx !== -1 && idx) {
            list = routeList.map((v) => {
              const route = v
              if (route.path === obj.path) {
                route.scrollTop = obj.scrollTop
              }
              return route
            })
        } else {
             list =  JSON.parse(JSON.stringify(routeList))
             list.push(obj)
        }
         localStorage.setItem(JSON.stringify(list))
    })
    return{
        path,
        createPage
    }
}

vuex 同上,逻辑差不多

路由

在路由切换之前获取滚动条离头部的距离(scrollTop),然后将获取的距离以对象形式(obj)存在vuex中(routeList),在路由进入页面之前的时候获取存储的值(scrollTop),然后进行过滤判断是否存在,存在就将值取出来赋值给scrollTop。

使用keepAlive进行有条件的筛选,不需要做会原来位置的就可以加上keepAlive

router.beforeEach((to, from, next) => {
  const wrapper = document.querySelector('#app')
  if (from.meta.keepAlive) {
    const scrollTop = wrapper ? wrapper.scrollTop : 0
    const obj = {
      scrollTop: scrollTop,
      path: from.path,
      query: from.query
    }
    store.commit('cancelAxios/setRouterPush', obj)
  }

  if (to.meta.keepAlive) {
      setTimeout(() => {
        const top = store.state.cancelAxios.routeList.find((v) => {
          return v.path === to.path && JSON.stringify(v.query) === JSON.stringify(to.query)
        })?.scrollTop
        wrapper.scrollTop = top
      }, 200)
  }

  next()
})
setRouterPush (state, obj) {
      const idx = state.routeList.findIndex((v) => v.path === obj.path && JSON.stringify(v.query) === JSON.stringify(obj.query))
      if (idx !== -1) {
        state.routeList = state.routeList.map((v) => {
          const route = v
          if (route.path === obj.path && JSON.stringify(route.query) === JSON.stringify(obj.query)) {
            route.scrollTop = obj.scrollTop
          }
          return route
        })
      } else {
        state.routeList.push(obj)
      }
    }