vue单页面从详情页面返回列表页面,记录滚动条位置。

这个需求是很常见的。

方法一:

1、先定义路由时添加关键字

{
    path: "/",
    component: Layout,
    redirect: "/home",
    children: [
      {
        path: "home",
        name: "Home",
        meta: {
          keepAlive: true
        },
        component: () => import("@/views/Home.vue")
      },
      {
        path: "about",
        name: "About",
        component: () => import("@/views/About.vue")
      }
    ]
  },

需要缓存的设置keepAlive: true

2、在路由切换容器设置

<keep-alive>
        <router-view v-if="$route.meta.keepAlive" :key="key"></router-view>
      </keep-alive>
      <router-view v-if="!$route.meta.keepAlive" :key="key"></router-view>

3、在详情页面通过this.$router.back()来实现返回。不能push。

方法二:

1、定义路由时添加meta scrollToTop: false/true来表示需不需要缓存

  {
    path: "/",
    component: Layout,
    redirect: "/home",
    children: [
      {
        path: "home",
        name: "Home",
        meta: {
          scrollToTop: false
        },
        component: () => import("@/views/Home.vue")
      },
      {
        path: "about",
        name: "About",
        component: () => import("@/views/About.vue")
      }
    ]
  },
    {
    path: "/article-edit",
    component: Layout,
    redirect: "/article-edit/index",
    children: [
      {
        path: "index",
        name: "ArticleEdit",
        meta: {
          scrollToTop: true
        },
        component: () => import("@/views/ArticleEdit.vue")
      }
    ]
  },

2、路由切换容器设置keep-alive

<transition name="fade-transform" mode="out-in">
        <keep-alive>
          <router-view :key="key"></router-view>
        </keep-alive>
      </transition>

3、在vuex中记录滚动条位置

const state = {
  scrollTop: 0
};

const mutations = {
  RECORD_SCROLL_TOP: (state, n) => {
    state.scrollTop = n;
  }
};

const actions = {
  changeScrollTop({ commit }, num) {
    commit("RECORD_SCROLL_TOP", num);
  }
};

export default {
  namespaced: true,
  state,
  mutations,
  actions
};

4、在路由导航卫士做判断

import router from "./router";
import store from "./store";
import { getToken } from "@/utils/auth"; // 从cookie中拿去token
router.beforeEach((to, from, next) => {
  // 要离开页面如果设置为不滚回到顶部,则本页是要记住上滚动高度到vuex中,以便下次进来恢复高度
  if (from.meta.scrollToTop == false) {
    store.dispatch("app/changeScrollTop", document.documentElement.scrollTop);
  }
  const hasToken = getToken();
  if (hasToken) {
    /* 有token */
    if (to.path === "/login/index") {
      // 有token,请求的是登录页面,直接返回首页
      next({ path: "/home" });
    } else {
      next();
    }
  } else {
    /* 无token */
    if (to.meta.requireAuth) {
      // 该路由需要登录权限
      if (store.state.user.token) {
        // vuex state中获取到当前的token是否存在
        next();
      } else {
        next({
          path: "/login"
          // query: { redirect: to.fullPath } // 将跳转的路由path作为参数,登录成功后跳转到该路由
        });
      }
    } else {
      // 该路由不需要登录权限
      next();
    }
  }
});
router.afterEach(to => {
  // 如果进入后的页面是要滚动到顶部,则设置scrollTop = 0
  //否则从vuex中读取上次离开本页面记住的高度,恢复它
  if (to.meta.scrollToTop == true) {
    setTimeout(() => {
      document.documentElement.scrollTop = 0;
    }, 10);
  } else {
    setTimeout(() => {
      document.documentElement.scrollTop = store.state.app.scrollTop;
    }, 50);
  }
});

参考连接:
https://www.cnblogs.com/vbyzc/p/9952550.html

https://blog.csdn.net/zjl516088421/article/details/77937440

方法三、在2的思路上调整修改。

方法2还是有点问题。感觉不是很好操作。特麻烦,并且,有时候,反正测试,还是有点问题。
不需要在路由内定义,也不需要在路由导航中进行判断。
1、在vuex中定义保存scrollTop的值和触发方法。
2、在list页面中,点击详情跳转时,触发记录scrollTop的方法,然后跳转到详情页面去了。

 handleRead(v) {
      // console.log(document.body.scrollTop);
      // console.log(document.documentElement.scrollTop);
      this.$store.dispatch(
        "app/changeScrollTop",
        document.documentElement.scrollTop
      );
      this.$router.push({
        path: "/article-detail/index",
        query: { id: v._id }
      });
    },

3、在list页面,activated()钩子函数内,设置应该距离顶部导航的值

  mounted() {},
  activated() {
    // console.log(this.$route);
    // 需要刷新,keepalive不应该生效
    if (this.$route.query.reload && this.$route.query.reload === true) {
      this.fetchList();
    }
    // console.log(this.$store.state.app.scrollTop);
    document.documentElement.scrollTop = this.$store.state.app.scrollTop;
  },
  methods: {}

4、如果在编辑页面跳转回来列表页面,需要页面刷新,就给路由传参,然后在activated中监听参数,看需不需要重新加载数据

articleAdd(para)
        .then(() => {
          this.$router.push({
            path: "/home",
            query: {
              reload: true
            }
          });
        })

注意,获取scollTop值的元素,有些元素的值,始终是0;监听获取的适合,需要注意一下。

原创文章 103 获赞 128 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_42991509/article/details/103896161