Vue框架中如何实现单页面后退不刷新的效果
Admin 2022-06-24 群英技术资讯 1158 次浏览
关于“Vue框架中如何实现单页面后退不刷新的效果”的知识有一些人不是很理解,对此小编给大家总结了相关内容,具有一定的参考借鉴价值,而且易于学习与理解,希望能对大家有所帮助,有这个方面学习需要的朋友就继续往下看吧。spa的渲染原理(以vue为例):url的更改触发onHashChange/pushState/popState/replaceState,通过url中的pathName去匹配路由中定义的组件,加载进来并实例化渲染在项目的出口router-view中。
换言之,一个实例的解析渲染意味着另外一个实例的销毁,因为渲染出口只有一个。
keep-alive为什么不行?因为keep-alive的原理是将实例化后的组件存储起来,当下次url匹配到了改组件时,优先从存储里面取。
但是vue只提供了入存储的方式,没提供删存储的方式,所以没法实现“前进刷新”。
有一种方案是手动根据to和from去做前进后退判断,这种判断不能应对复杂的跳转逻辑,可维护性也很差。
vue-page-stack,vue-navigation。
这两个方案都有明显缺点:前者不支持嵌套路由,在一些场景下会出现url变化,页面完全无反应的情况,后者存在类似的bug。并且这两种方案侵入性都很强,因为他们都是基于vue-router的魔改。并且会在url中增加无意义的多余字段(stackID)
现在有一个可行且简单的方案:嵌套子路由 + 叠页面。
叠页面的灵感:原生应用中的webview in webview,多页应用中的window in window。
要在spa中实现后退不刷新,本质是要实现多实例共存。
这个方案的核心在于:通过嵌套子路由实现多实例共存,通过css的absolute实现视觉上的页面堆叠。

在routes配置文件中:
import Home from "../views/Home.vue";
const routes = [
{
path: "/home",
name: "Home",
component: Home,
children: [
{
path: "sub",
component: () =>
import(/* webpackChunkName: "sub" */ "../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>
在routes中:
import { Route } from "react-router-dom";
const Routes = () => {
return (
<>
{/* 这里不能加exact,因为要先匹配父页面再匹配子页面 */}
<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方案,由于逻辑简单,得到了不少同事的认可和使用。比如常见的:列表页存在搜索条件,进入详情页再返回。 大家可以试用一下,会有惊喜的。
路由格式需要做改造,必须做成嵌套关系,对url有一定要求。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章给大家分享的是jQuery改变td背景色的方法,在jQuery中,可以利用css()方法来改变td单元格的背景颜色,文中的示例介绍得很详细,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。
本文主要介绍了Element-UI 10个奇淫技巧小结,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
React中useRef的用法有什么?如果有使用过React的朋友,应该对ref会比较熟悉的点,ref可以用来获取组件实例对象或者是DOM对象,而useRef这个hooks函数,除了传统的用法之外,它还可以“跨渲染周期”保存数据。那么具体怎样用呢?下面我们就一起来了解看看。
不少朋友应该都有玩过俄罗斯方块小游戏吧,俄罗斯方块是个很经典的小游戏,下面我们就来尝试一下用JS实现实现俄罗斯方块游戏,下文有实现思路和代码,感兴趣的朋友可以参考学习。
这篇文章主要为大家详细介绍了原生JavaScript实现简单五子棋游戏,文中示例代码注释的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
成为群英会员,开启智能安全云计算之旅
立即注册关注或联系群英网络
7x24小时售前:400-678-4567
7x24小时售后:0668-2555666
24小时QQ客服
群英微信公众号
CNNIC域名投诉举报处理平台
服务电话:010-58813000
服务邮箱:service@cnnic.cn
投诉与建议:0668-2555555
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008