Vue3:返回组件(运用keepAlive保留滚动位置)

this.$router.go(-1) ( VUE3写法 :proxy.$router.go(-1) )返回上一页最简单实用,现通过路由传参及keepAlive,实现返回保留滚动条位置

router.js

注:需要保留滚动条的页设置keepAlive: true

import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [
  {
    path: '/',
    name: 'index',
    component: () => import('@/views/index.vue'),
  }, {
    path: '/rule',
    name: 'rule',
    component: () => import('@/views/rule.vue'),
  },{
    path: '/list',
    name: 'list',
    component: () => import('@/views/list.vue'),
    meta: {
      keepAlive: true // 需要缓存
    }
  }, {
    path: '/about/:orderid',
    name: 'about',
    component: () => import('@/views/about.vue')
  }, {
    path: '/rank',
    name: 'rank',
    component: () => import('@/views/rank.vue'),
    meta: {
      keepAlive: true // 需要缓存
    }
  }
]

//history模式对应createWebHistory()方法
//hash模式对应createWebHashHistory()方法
const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

App.vue

<template>
<div id="app">


<router-view v-slot="{ Component, route }">
<keep-alive>
<component :is="Component" :key="route.name" v-if="route.meta.keepAlive"/>
</keep-alive>
<component :is="Component" :key="route.name" v-if="!route.meta.keepAlive"/>
</router-view>


</div>
</template>
<script setup>
import {defineComponent,getCurrentInstance,ref,reactive,computed,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted,onErrorCaptured,onRenderTracked,onRenderTriggered,onActivated,onDeactivated,onServerPrefetch} from 'vue';
//生命周期
onBeforeMount(()=>{
  console.log('注册一个钩子,在组件被挂载之前被调用。onBeforeMount')
})
onMounted(()=>{
  console.log('注册一个回调函数,在组件挂载完成后执行。onMounted')
})
onBeforeUpdate(()=>{
  console.log('注册一个钩子,在组件即将因为响应式状态变更而更新其 DOM 树之前调用。onBeforeUpdate')
})
onUpdated(()=>{
  console.log('注册一个回调函数,在组件因为响应式状态变更而更新其 DOM 树之后调用。onUpdated')
})
onBeforeUnmount(()=>{
  console.log('注册一个钩子,在组件实例被卸载之前调用。onBeforeUnmount')
})
onUnmounted(()=>{
  console.log('注册一个回调函数,在组件实例被卸载之后调用。onUnmounted')
})
onErrorCaptured(() => {
  console.log('注册一个钩子,在捕获了后代组件传递的错误时调用。onErrorCaptured')
})
onRenderTracked(() => {
  console.log('注册一个调试钩子,当组件渲染过程中追踪到响应式依赖时调用。onRenderTracked')
})
onRenderTriggered(() => {
  console.log('注册一个调试钩子,当响应式依赖的变更触发了组件渲染时调用。onRenderTriggered')
})
onActivated(() => {
  console.log('注册一个回调函数,若组件实例是 <KeepAlive> 缓存树的一部分,当组件被插入到 DOM 中时调用。onActivated')
})
onDeactivated(() => {
  console.log('注册一个回调函数,若组件实例是 <KeepAlive> 缓存树的一部分,当组件从 DOM 中被移除时调用。onDeactivated')
})
onServerPrefetch(() => {
  console.log('注册一个异步函数,在组件实例在服务器上被渲染之前调用。onServerPrefetch')
})
</script>
<style scoped>
</style>

需保存滚动条位置页.vue

注意这两个onActivatedonDeactivated 这两个生命周期钩子函数,

需要import {onActivated,onDeactivated} from 'vue'

<template>
<div id="millia">

<!--其他HTML代码-->

<!--侧边导航非组件-->
<ul>
<li @click="goTop">TOP</li>
<li @click="goOtherPage">去其他页</li>
</ul>


<!--引用返回组件用于返回上一层-->
<go-back :goBackData="goBackData"></go-back>

<!--其他HTML代码-->

</div>
</template>
<script setup>
import {defineComponent,getCurrentInstance,ref,reactive,computed,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted,onErrorCaptured,onRenderTracked,onRenderTriggered,onActivated,onDeactivated,onServerPrefetch} from 'vue';

import GoBack from '@/components/GoBack.vue'

//使用vue的getCurrentInstance 方法获取当前组件实例
const { proxy } = getCurrentInstance()


//goBack组件数据 传空值用于返回上一页 proxy.$router.go(-1)
let goBackData = reactive({
  goBackParam:"",
  isScroll:"",
})


//当前滚动条位置
let scroll = ref()
const handleScroll = () =>  {
  scroll.value = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
  //console.log(scroll.value)
}


//窗口绑定监听方法
window.addEventListener('scroll',handleScroll)


//返回顶部
const goTop = () => {
  document.getElementById('app').scrollIntoView({
    behavior: "smooth",
    block: "start",
    inline: "nearest"
  });
}


//去其他页同时传递页面滚动条位置
const goOtherPage = (event) => {
  proxy.$router.push({
    name:"其他页名字",
    params:{
      goBackParam: "当前需要保存滚动条页名字 如 list",
      isScroll: scroll.value
    }
  })
}


//判断路由参数isScroll决定滚动条位置
const isGoScroll = () => {
  if (proxy.$route.params.isScroll) {
   //console.log(proxy.$route.params.isScroll)
    document.documentElement.scrollTop = proxy.$route.params.isScroll
    document.body.scrollTop = proxy.$route.params.isScroll
  }
}


//若 <KeepAlive>,当组件被插入到 DOM 中时调用。onActivated'
onActivated(() => {
  window.addEventListener('scroll',handleScroll);
  isGoScroll();
})


//若 <KeepAlive>,当组件从 DOM 中被移除时调用。onDeactivated'
onDeactivated(() => {
  window.removeEventListener('scroll', handleScroll);
})
</script>

返回组件使用页.vue

<template>
<div id="millia">

<!--其他HTML代码-->

<go-top></go-top>
<go-back :goBackData="goBackData"></go-back>

<!--其他HTML代码-->

</div>
</template>
<script setup>
import { defineComponent, getCurrentInstance, ref, reactive, computed, onMounted } from 'vue';
import GoBack from '@/components/GoBack.vue';  //回顶部组件
import GoTop from '@/components/GoTop.vue'; //返回组件

//使用vue的getCurrentInstance 方法获取当前组件实例
const { proxy } = getCurrentInstance()


//goBack组件数据
let goBackData = reactive({
  goBackParam:"",
  isScroll:"",
})


//获取路由参数
const getRouter = () => {
  if(proxy.$route.params.goBackParam && proxy.$route.params.isScroll){
    goBackData.goBackParam = proxy.$route.params.goBackParam
    goBackData.isScroll = proxy.$route.params.isScroll
  }
}


onMounted(() => {
  getRouter();
})
</script>
<style scoped>
</style>

GoBack返回组件

<template>
<div class="goBack" @click="goBack">
返回
</div>
</template>
<script setup>
import {getCurrentInstance,defineProps,defineEmits,defineExpose,ref,reactive} from 'vue';
defineProps({
  goBackData: Object,
  //goBackParam及isScroll
  //goBackParam 返回路径名
  //isScroll 滚动量
})
//使用vue的getCurrentInstance 方法获取当前组件实例
const { proxy } = getCurrentInstance();
console.log(proxy.goBackData.goBackParam)
//根据参数判断返回
const goBack = () => {
  //console.log(proxy.goBackData.goBackParam)
  if(proxy.goBackData.goBackParam == '' || proxy.goBackData == undefined){
    proxy.$router.go(-1)
  }else{
    proxy.$router.push({
      name:proxy.goBackData.goBackParam,
      params:{
        isScroll:proxy.goBackData.isScroll
      }
    })
  }
}
</script>
<style scoped>
.goBack{position:fixed;right:0;bottom:0;display:flex;justify-content:center;align-items:center;z-index:8;background:#3398fb;color:#fff;font-size:1.4rem;padding:1rem 0;border-radius:0.5rem 0 0 0.5rem;writing-mode:vertical-rl;width:3rem;}
.goBack .icon{height:3rem;width:3rem;}
</style>

GoTop回顶部组件

<template>
<div class="goTop" @click="goTop">
TOP
</div>

</template>
<script setup>
const goTop = () => {
  document.getElementById('app').scrollIntoView({
    behavior: "smooth",
    block: "start",
    inline: "nearest"
  });
}
</script>
<style scoped>
.goTop{position:fixed;right:0;bottom:5.5rem;display:flex;justify-content:center;align-items:center;z-index:8;background:#ff58d9;color:#fff;font-size:1.4rem;padding:1rem 0;border-radius:0.5rem 0 0 0.5rem;writing-mode:vertical-rl;width:3rem;}
.goTop .icon{width:3rem;}
</style>

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值