iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >vue/react单页应用后退不刷新方案
  • 892
分享到

vue/react单页应用后退不刷新方案

2024-04-02 19:04:59 892人浏览 安东尼
摘要

目录引言 为什么麻烦 有坑的社区方案(以Vue为例) 目前不错的方案 上效果图vue中的实现 React中的实现 题外 该方案的优点缺点 引言 前进刷新,后退不刷新,是一个类似ap

引言

前进刷新,后退不刷新,是一个类似app页面的特点,要在单页WEB应用中做后退不刷新,却并非一件易事。

为什么麻烦

spa的渲染原理(以vue为例):url的更改触发onHashChange/pushState/popState/replaceState,通过url中的pathName去匹配路由中定义的组件,加载进来并实例化渲染在项目的出口router-view中。

换言之,一个实例的解析渲染意味着另外一个实例的销毁,因为渲染出口只有一个。

keep-alive为什么不行?因为keep-alive的原理是将实例化后的组件存储起来,当下次url匹配到了改组件时,优先从存储里面取。

但是vue只提供了入存储的方式,没提供删存储的方式,所以没法实现“前进刷新”。

有一种方案是手动根据to和from去做前进后退判断,这种判断不能应对复杂的跳转逻辑,可维护性也很差。

有坑的社区方案(以vue为例)

vue-page-stackvue-navigation
这两个方案都有明显缺点:前者不支持嵌套路由,在一些场景下会出现url变化,页面完全无反应的情况,后者存在类似的bug。并且这两种方案侵入性都很强,因为他们都是基于vue-router的魔改。并且会在url中增加无意义的多余字段(stackID)

目前不错的方案

现在有一个可行且简单的方案:嵌套子路由 + 叠页面。
叠页面的灵感:原生应用中的webview in webview,多页应用中的window in window。
要在spa中实现后退不刷新,本质是要实现多实例共存。
这个方案的核心在于:通过嵌套子路由实现多实例共存,通过CSS的absolute实现视觉上的页面堆叠。

上效果图

vue中的实现

在routes配置文件中:


import Home from "../views/Home.vue";

const routes = [
  {
    path: "/home",
    name: "Home",
    component: Home,
    children: [
      {
        path: "sub",
        component: () =>
          import( "../views/Sub.vue"),
      },
    ],
  },
];

export default routes;

主页:


<template>
  <div class="home">
    <input v-model="inputValue" />
    <h3>{{ inputValue }}</h3>
    <button @click="handleToSub">to sub</button>
    <router-view @reload="handleReload" />
  </div>
</template>

<script>
export default {
  name: "Home",
  data() {
    return {
      inputValue: "",
    };
  },
  methods: {
    handleToSub() {
      // 注意路由格式,是基于上一个路由/home下面的sub,不是独立的/sub
      this.$router.push("/home/sub");
    },

    handleReload(val) {
      // 这里可以做一些重新获取数据的操作,比如在详情页修改数据,返回后重新拉取列表
      console.log("reload", val);
    },
  },
  mounted() {
    // 子页面返回,不会重新跑生命周期
    console.log("mounted");
  },
};
</script>

<style scoped>
.home {
  position: relative;
}
</style>

子页面:


<template>
  <div class="sub">
    <h1>This is Sub page</h1>
  </div>
</template>

<script>
export default {
  beforeDestroy() {
    // 可以传自定义参数,如果没需要,也可以不做
    this.$emit("reload", 123);
  },
};
</script>

<style scoped>
.sub {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: #fff;
}
</style>

react中的实现

在routes中:


import { Route } from "react-router-dom";

const Routes = () => {
  return (
    <>
      {}
      <Route path="/home" component={lazy(() => import("../views/Home"))} />
    </>
  );
};

export default Routes;

主页:


import React, { useEffect, useState } from "react";
import { Route, useHistory } from "react-router-dom";
import styled from "styled-components";
import Sub from "./Sub";

const HomeContainer = styled.div`
  position: relative;


const Home: React.FC = () => {
  const [inputValue, setInputValue] = useState("");
  const history = useHistory();

  const handleToSub = () => {
    history.push("/home/sub");
  };

  const handleReload = (val: number) => {
    console.log("reload", val);
  };

  useEffect(() => {
    console.log("mounted");
  }, []);

  return (
    <HomeContainer>
      <input
        value={inputValue}
        onChange={(e) => setInputValue(e.target.value)}
      />
      <h3>{inputValue}</h3>
      <button onClick={handleToSub}>to sub</button>
      <Route
        path="/home/sub"
        component={() => <Sub handleReload={handleReload} />}
      />
    </HomeContainer>
  );
};

export default Home;

子页面:


import React from "react";
import styled from "styled-components";

const SubContainer = styled.div`
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: #fff;


type SubProps = {
  handleReload: (val: number) => void;
};

const Sub: React.FC<SubProps> = ({ handleReload }) => {
  useEffect(() => {
   return () => handleReload(123);
  }, []);
  
  return (
    <SubContainer>
      <h1>This is Sub page</h1>
    </SubContainer>
  );
};

export default Sub;

题外

在前司的核心项目“平安好车主”中,我就在部分h5新项目用了该方案,在线上经受住了170w+访问量的考验。目前在Shopee也在推行这种h5方案,由于逻辑简单,得到了不少同事的认可和使用。比如常见的:列表页存在搜索条件,进入详情页再返回。 大家可以试用一下,会有惊喜的。

该方案的优点

  • 实现简单,无侵入式修改,几乎0逻辑;
  • 子页面可以单独提供出去,供三方接入;
  • 完全的多实例共存,后退不刷新;
  • 可以像父子组件一样通信,监听子页面离开;

缺点

路由格式需要做改造,必须做成嵌套关系,对url有一定要求。
GitHub地址
https://github.com/zhangnan24/no-refresh-back-vue

到此这篇关于vue/react单页应用后退不刷新方案的文章就介绍到这了,更多相关vue/react后退不刷新内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: vue/react单页应用后退不刷新方案

本文链接: https://www.lsjlt.com/news/154659.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • vue/react单页应用后退不刷新方案
    目录引言 为什么麻烦 有坑的社区方案(以vue为例) 目前不错的方案 上效果图vue中的实现 react中的实现 题外 该方案的优点缺点 引言 前进刷新,后退不刷新,是一个类似ap...
    99+
    2024-04-02
  • react 跳转后路由变了页面没刷新的解决方案
    目录问题解决方案问题 这样的问题貌似原因还挺多的,我的问题是带参数的url不能刷新,router 5.0版本 ,使用withRouter关联组件进行页面跳转 如下所示 路由代码...
    99+
    2024-04-02
  • 应用provide与inject刷新Vue页面方法
    目录方法1:直接调用函数方法2:采用provide / inject(静刷新)优势比较方法1:直接调用函数 将整个页面重载, 以下两种都可以 1.window.location.r...
    99+
    2024-04-02
  • Vue路由this.route.push跳转页面不刷新的解决方案
    Vue路由this.route.push跳转页面不刷新 一、背景 介绍:在vue项目开发中,使用路由进行页面跳转时,路由所跳转的页面不进行刷新。 也就是vue生命周期函数没有执行(c...
    99+
    2024-04-02
  • vue返回上一页面时不刷新问题及解决方案
    目录返回上一页面时不刷新前景思路说明页面回退后,不刷新问题问题描述问题解决返回上一页面时不刷新 前景 在日常使用的时候,我们经常需要返回上一级页面的时候,不刷新页面,保持页面不变,这...
    99+
    2024-04-02
  • vue列表数据删除后主动刷新页面及刷新方法详解
    问题描述: 前端删除一条数据或者新增数据后,后端操作成功,但前端不会自动刷新,需要重新刷新当前页面 (用vue-router重新路由到当前页面,页面是不进行刷新的 ,采用windo...
    99+
    2024-04-02
  • Vue应用程序中怎么刷新页面
    Vue是一款流行的JavaScript框架,它是一个用于构建交互式Web应用程序的开发工具。Vue提供了许多有用的功能和工具,其中包括Vue Router。Vue Router是一个内置的路由管理器,它可以帮助开发者更好地管理Vue应用程序...
    99+
    2023-05-14
  • Vue使用三种方法刷新页面
    我们在写项目的时候,经常会遇到,用户执行完某个动作,改变了某些状态,需要重新刷新页面,以此来重新渲染页面。如:用户登录成功、增加、删除、更新等。 原始方法: loca...
    99+
    2024-04-02
  • apache和nginx下vue页面刷新404的解决方案
    目录问题描述原因伪静态配置apache伪静态配置nginx伪静态配置总结问题描述 记录一个新手很容易遇见的问题,vue的项目,在打包前本地cli模式运行没有任何问题,但是打包完在ap...
    99+
    2022-12-09
    apache nginx vue页面刷新404 nginx vue页面刷新
  • Vue/React 项目部署到服务器后,刷新页面出现404报错
    问题描述:在本地启动项目一切正常,部署到服务器上线后出现BUG,项目刷新页面出现404。 起初以为是自己路由守卫或是token丢失问题,找了一圈终于解决了 产生原因:我们打开vue/react打包后生成的dist文件夹,可以看到只有...
    99+
    2023-09-15
    vue.js 前端 javascript
  • vue如何实现刷新之后嵌套路由不变并重新渲染页面
    这篇文章给大家分享的是有关vue如何实现刷新之后嵌套路由不变并重新渲染页面的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。解决嵌套路由刷新时,路由没有变化,正常情况下页面是不会重新...
    99+
    2024-04-02
  • vue项目刷新后导航菜单高亮显示的位置不对怎么办
    这篇文章主要介绍vue项目刷新后导航菜单高亮显示的位置不对怎么办,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1本人在学vue项目时遇到一个坑、在写vue项目头部导航时,比如点击第三...
    99+
    2024-04-02
  • Nuxt.js的Vue化身:单页面应用的革新之作
    ...
    99+
    2024-04-02
  • VUE单页面应用SEO的方法是什么
    这篇文章主要介绍了VUE单页面应用SEO的方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇VUE单页面应用SEO的方法是什么文章都会有所收获,下面我们一起来看看吧。vue-meta-info ...
    99+
    2023-06-27
  • Vue实现父子组件页面刷新的几种常用方法
    目录1、原地页面重新加载(不推荐)2、空白页面作为过渡3、使用Provide / Inject组合控制显示4、v-on:param父组件监听子组件事件参考文档:很多时候我们在操作过页...
    99+
    2024-04-02
  • ASP.NET Core应用JWT进行用户认证及Token的刷新方案
    目录一、什么是JWT?为什么要使用JWT?二、JWT的组成:HeaderPayloadSignature三、认证流程四、应用实例认证服务User相关:TokenHelper:应用服务...
    99+
    2024-04-02
  • vue中如何实现前进刷新、后退缓存用户浏览数据和浏览位置
    这篇文章主要介绍了vue中如何实现前进刷新、后退缓存用户浏览数据和浏览位置,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。vue中,我们所要实...
    99+
    2024-04-02
  • 如何实现一个简单的Ajax页面无刷新进行用户验证案例
    这篇文章给大家分享的是有关如何实现一个简单的Ajax页面无刷新进行用户验证案例的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。效果如下图:实现主要过程:在UsersAction类中...
    99+
    2024-04-02
  • Vue单页面应用做预渲染的方法实例
    目录前言vue-cli2.0版本vue-cli3.0版本总结前言 使用vue-cli打包项目一般为spa项目,众所周知单页面应用不利于SEO,有ssr(服务端渲染)和预渲染两种解决方...
    99+
    2024-04-02
  • vue中swiper开启loop后,点击事件不响应的解决方案
    目录swiper开启loop后,点击事件不响应问题代码如下swiper设置loop:true时点击事件失效解决swiper开启loop后,点击事件不响应 接手离职同事的项目,然后发现...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作