欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue/react單頁應(yīng)用后退不刷新方案

 更新時間:2021年10月18日 09:13:20   作者:陌上兮月  
本文主要介紹了vue/react單頁應(yīng)用后退不刷新方案,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

引言

前進刷新,后退不刷新,是一個類似app頁面的特點,要在單頁web應(yīng)用中做后退不刷新,卻并非一件易事。

為什么麻煩

spa的渲染原理(以vue為例):url的更改觸發(fā)onHashChange/pushState/popState/replaceState,通過url中的pathName去匹配路由中定義的組件,加載進來并實例化渲染在項目的出口router-view中。

換言之,一個實例的解析渲染意味著另外一個實例的銷毀,因為渲染出口只有一個。

keep-alive為什么不行?因為keep-alive的原理是將實例化后的組件存儲起來,當(dāng)下次url匹配到了改組件時,優(yōu)先從存儲里面取。

但是vue只提供了入存儲的方式,沒提供刪存儲的方式,所以沒法實現(xiàn)“前進刷新”。

有一種方案是手動根據(jù)to和from去做前進后退判斷,這種判斷不能應(yīng)對復(fù)雜的跳轉(zhuǎn)邏輯,可維護性也很差。

有坑的社區(qū)方案(以vue為例)

vue-page-stack,vue-navigation。
這兩個方案都有明顯缺點:前者不支持嵌套路由,在一些場景下會出現(xiàn)url變化,頁面完全無反應(yīng)的情況,后者存在類似的bug。并且這兩種方案侵入性都很強,因為他們都是基于vue-router的魔改。并且會在url中增加無意義的多余字段(stackID)

目前不錯的方案

現(xiàn)在有一個可行且簡單的方案:嵌套子路由 + 疊頁面。
疊頁面的靈感:原生應(yīng)用中的webview in webview,多頁應(yīng)用中的window in window。
要在spa中實現(xiàn)后退不刷新,本質(zhì)是要實現(xiàn)多實例共存。
這個方案的核心在于:通過嵌套子路由實現(xiàn)多實例共存,通過css的absolute實現(xiàn)視覺上的頁面堆疊。

上效果圖

vue中的實現(xiàn)

在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) {
      // 這里可以做一些重新獲取數(shù)據(jù)的操作,比如在詳情頁修改數(shù)據(jù),返回后重新拉取列表
      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() {
    // 可以傳自定義參數(shù),如果沒需要,也可以不做
    this.$emit("reload", 123);
  },
};
</script>

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

react中的實現(xiàn)

在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新項目用了該方案,在線上經(jīng)受住了170w+訪問量的考驗。目前在Shopee也在推行這種h5方案,由于邏輯簡單,得到了不少同事的認可和使用。比如常見的:列表頁存在搜索條件,進入詳情頁再返回。 大家可以試用一下,會有驚喜的。

該方案的優(yōu)點

  • 實現(xiàn)簡單,無侵入式修改,幾乎0邏輯;
  • 子頁面可以單獨提供出去,供三方接入;
  • 完全的多實例共存,后退不刷新;
  • 可以像父子組件一樣通信,監(jiān)聽子頁面離開;

缺點

路由格式需要做改造,必須做成嵌套關(guān)系,對url有一定要求。
github地址
https://github.com/zhangnan24/no-refresh-back-vue

到此這篇關(guān)于vue/react單頁應(yīng)用后退不刷新方案的文章就介紹到這了,更多相關(guān)vue/react后退不刷新內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 讓你30分鐘快速掌握vue3教程

    讓你30分鐘快速掌握vue3教程

    這篇文章主要介紹了讓你30分鐘快速掌握vue3,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Vue.js路由vue-router使用方法詳解

    Vue.js路由vue-router使用方法詳解

    這篇文章主要為大家詳細介紹了Vue.js路由vue-router使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • 一步一步實現(xiàn)Vue的響應(yīng)式(對象觀測)

    一步一步實現(xiàn)Vue的響應(yīng)式(對象觀測)

    這篇文章主要介紹了一步一步實現(xiàn)Vue的響應(yīng)式(對象觀測),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Vue.js 2.0 和 React、Augular等其他前端框架大比拼

    Vue.js 2.0 和 React、Augular等其他前端框架大比拼

    這篇文章主要介紹了Vue.js 2.0 和 React、Augular等其他前端框架大比拼的相關(guān)資料,React 和 Vue 有許多相似之處,本文給大家提到,需要的朋友可以參考下
    2016-10-10
  • vue使用路由router-view的詳細代碼

    vue使用路由router-view的詳細代碼

    這篇文章主要介紹了vue使用路由router-view的相關(guān)知識,其原理就是采用?SPA(single-page-application)?模式,就是只有一個?Web?頁面的應(yīng)用,通過?router?來控制頁面的刷新和迭代,感興趣的朋友一起看看吧
    2023-12-12
  • vue element 中的table動態(tài)渲染實現(xiàn)(動態(tài)表頭)

    vue element 中的table動態(tài)渲染實現(xiàn)(動態(tài)表頭)

    這篇文章主要介紹了vue element 中的table動態(tài)渲染實現(xiàn)(動態(tài)表頭),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Vue路由模塊化配置的完整步驟

    Vue路由模塊化配置的完整步驟

    這篇文章主要給大家介紹了關(guān)于Vue路由模塊化配置的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用Vue具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • vue中設(shè)置echarts寬度自適應(yīng)的代碼步驟

    vue中設(shè)置echarts寬度自適應(yīng)的代碼步驟

    這篇文章主要介紹了vue中設(shè)置echarts寬度自適應(yīng)的問題及解決方案,常常需要做到echarts圖表的自適應(yīng),一般是根據(jù)頁面的寬度做對應(yīng)的適應(yīng),本文記錄一下設(shè)置echarts圖表的自適應(yīng)的步驟,需要的朋友可以參考下
    2022-09-09
  • Vue+EleMentUI實現(xiàn)el-table-colum表格select下拉框可編輯功能實例

    Vue+EleMentUI實現(xiàn)el-table-colum表格select下拉框可編輯功能實例

    這篇文章主要給大家介紹了關(guān)于Vue+EleMentUI實現(xiàn)el-table-colum表格select下拉框可編輯功能的相關(guān)資料,element-UI表格的使用相信大家都不陌生,文中給出了詳細的代碼示例,需要的朋友可以參考下
    2023-07-07
  • Vue項目中ESLint配置超全指南(VScode)

    Vue項目中ESLint配置超全指南(VScode)

    ESLint是一個代碼檢查工具,用來檢查你的代碼是否符合指定的規(guī)范,下面這篇文章主要給大家介紹了關(guān)于Vue項目中ESLint配置(VScode)的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-04-04

最新評論