国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

單頁(yè)面路由切換原理/簡(jiǎn)單實(shí)現(xiàn)

yangrd / 3484人閱讀

摘要:新增一條記錄替換當(dāng)前的記錄實(shí)現(xiàn)核心路由綁定標(biāo)簽綁定事件并阻止默認(rèn)事件總結(jié)本文只是簡(jiǎn)述了,路由變化原理,并未去結(jié)合去完成實(shí)現(xiàn)一個(gè)框架路由。

前言

最近學(xué)習(xí)react時(shí),在使用react-router-dom的時(shí)候,對(duì)history原理與路由切換實(shí)現(xiàn)并不了解,經(jīng)過(guò)學(xué)習(xí)后總結(jié)一下吧!

如果你只是使用react 自帶history 那下面這些原理,你可能并不會(huì)用到。但當(dāng)需要使用自己的history 或 使用第三方history 的時(shí)候你就需要了解其原理

在react 中,你要在非組件內(nèi)可以靈活的切換路由,那么你就要使用自定義的history。

// app.jsx
import React from "react"
import "./App.scss"
import { BrowserRouter } from "react-router-dom"
import history from "./history"
import XtContent from "./layout/content"
import Login from "./components/loginModal"
function App() {
  return (
    
) } export default App // history.js // 這里使用第三方創(chuàng)建history import { createBrowserHistory } from "history" export default createBrowserHistory() // 在封裝的fetch中使用 import axios from "axios" import history from "@/history"; // 設(shè)置axios 通用 const service = axios.create({ timeout: 5000, headers: { "Content-Type": "application/json;charset=UTF-8" }, withCredentials: true }) // 響應(yīng)攔截 service.interceptors.response.use( response => { //服務(wù)端定義的響應(yīng)code碼為0時(shí)請(qǐng)求成功 if (response.data.code === 200) { //使用Promise.resolve 正常響應(yīng) return Promise.resolve(response.data) } else if (response.data.code === 1002) { //服務(wù)端定義的響應(yīng)code碼為1401時(shí)為未登錄 message.error("登陸失效,請(qǐng)從新登陸!") /////////// 登陸失敗切換登陸頁(yè)面 **history.push("/Login")** ////////// window.localStorage.removeItem("userInfo") return Promise.reject(response.data) //使用Promise.reject 拋出錯(cuò)誤和異常 } else { message.error(response.data.message) return Promise.reject(response.data) } }, error => { if (error && error.response) { let res = {} res.code = error.response.status res.msg = throwErr(error.response.status, error.response) //throwErr 捕捉服務(wù)端的http狀態(tài)碼 定義在utils工具類的方法 message.error(res.msg) return Promise.reject(res) } return Promise.reject(error) } )

模式

在React/Vue的路由時(shí),會(huì)有兩種模式 hash 和 history ,事實(shí)上他們是針對(duì)游覽器的路由模式設(shè)置的。其基本原理實(shí)際就是通關(guān)游覽器提供的監(jiān)聽這兩種模式的變化,從而映射的對(duì)應(yīng)路由的組件render.

基與以上理論簡(jiǎn)單實(shí)現(xiàn)一下路由切換 hash

hash 其兼容性好,但一般不采用只是在不支持H5 history 的情況下回退到hash。其在游覽器上的路由形式 http://localhost#/test 與正常路由相比略顯怪異且不美觀(不推薦使用)

核心:監(jiān)聽hash變化觸發(fā)callback // window.addEventListener("hashchange", callback)

// 模擬實(shí)現(xiàn)
  class Router {
      constructor() {
        // 儲(chǔ)存 hash 與 callBack 的映射
        this.routes = {};
        // 當(dāng)前 路由
        this.currentUrl = "";
        // 存儲(chǔ)歷史記錄
        this.history = [];
        // 作為指針,默認(rèn)指向 this.history 的末尾,根據(jù)后退前進(jìn)指向 history 中不同的 hash
        this.currentIndex = this.history.length - 1;
        this.backIndex = this.history.length - 1
        this.refresh = this.refresh.bind(this);
        this.backOff = this.backOff.bind(this);
        // 默認(rèn)不是后退操作
        this.isBack = false;
    
        // 監(jiān)聽load后加載路由
        window.addEventListener("load", this.refresh, false);
    
        // 監(jiān)聽hash 變化
        //window.addEventListener("hashchange", this.refresh, false);
      }
    
      //路由實(shí)例 加添路由映射
      route(path, callback) {
        this.routes[path] = callback || function() {};
      }
    
      // 根據(jù)由render
      refresh() {
        console.log("refresh")
        this.currentUrl = location.hash.slice(1) || "/";
        this.history.push(this.currentUrl);
        this.currentIndex++;
        if (!this.isBack) {
          this.backIndex = this.currentIndex
        }
        this.routes[this.currentUrl]();
        console.log("指針:", this.currentIndex, "history:", this.history);
        this.isBack = false;
      }
      // 后退功能
      backOff() {
        // 后退操作設(shè)置為true
        console.log(this.currentIndex)
        console.log(this.backIndex)
        this.isBack = true;
        this.backIndex <= 0 ?
          (this.backIndex = 0) :
          (this.backIndex = this.backIndex - 1);
        location.hash = `#${this.history[this.backIndex]}`;
      }
    }
    
    // 調(diào)用
    
    window.router = new Router()

    router.route("/", function () {
      console.log("")
      changeContent("")
    })
    router.route("/Home1", function () {
      console.log("Home1")
      changeContent("Home1")
    })
    router.route("/Home2", function () {
      console.log("Home2")
      changeContent("Home2")
    })
    router.route("/Home3", function () {
      console.log("Home3")
      changeContent("Home3")
    })
history history API (pushState replaceState)

將游覽器地址上路由切換

修改歷史記錄

不會(huì)刷新頁(yè)面

其路由形式為游覽器標(biāo)準(zhǔn),所以當(dāng)切換到某一路由localhost/test 后再刷新游覽器(F5),游覽器會(huì)向服務(wù)器請(qǐng)求/test下對(duì)應(yīng)的資源,然鵝路由是在前端實(shí)現(xiàn)的服務(wù)器會(huì)找不到資源,在這種模式需要將服務(wù)器接收到的get(contentType = text/html)請(qǐng)求統(tǒng)一返回index.html。下面已node-koa為例

  
  const Koa = require("koa")
  // 一個(gè)處理前端路由hisrtory模式的node插件
  const history = require("koa2-connect-history-api-fallback")
  const app = new Koa()
  // 將contentType 為 text/html, application/xhtml+xml 統(tǒng)一返回靜態(tài)資源文件下的index.html
  app.use(history({
    htmlAcceptHeaders: ["text/html", "application/xhtml+xml"]
  }))
  
  * koa2-connect-history-api-fallback 見 https://github.com/davezuko/koa-connect-history-api-fallback

/**
* state :歷史記錄相關(guān)聯(lián)的狀態(tài)對(duì)象,當(dāng)popstate事件觸發(fā)時(shí),會(huì)把該對(duì)象傳入回調(diào)函數(shù)。不用可傳null。
* title: 新頁(yè)面的標(biāo)題不用可傳null。
* url: 要切換到的路徑,必須保持與當(dāng)前URL同一個(gè)域。
**/

// 新增一條記錄
history.pushState(state, title, url)

// 替換當(dāng)前的記錄
history.replaceState(state, title, url)

#### 實(shí)現(xiàn) #####

* 核心  window.addEventListener("popstate",callBack)

class Routers {
  constructor() {
    this.routes = {};
    this._bindPopState();
  }
  init(path) {
    history.replaceState({path: path}, null, path);
    this.routes[path] && this.routes[path]();
  }

  route(path, callback) {
    this.routes[path] = callback || function() {};
  }

  go(path) {
    history.pushState({path: path}, null, path);
    this.routes[path] && this.routes[path]();
  }
  _bindPopState() {
    window.addEventListener("popstate", e => {
      const path = e.state && e.state.path;
      this.routes[path] && this.routes[path]();
    });
  }
}

window.Router = new Routers();
Router.init(location.pathname);

// 路由綁定
Router.route("/", function() {
  console.log("/")
});
Router.route("/blue", function() {
  console("blue");
});
Router.route("/green", function() {
  console("green");
});

// a標(biāo)簽綁定事件、并阻止默認(rèn)事件
a.addEventListener("click", e => {
  if (e.target.tagName === "A") {
    e.preventDefault();
    Router.go(e.target.getAttribute("href"));
  }
});


總結(jié)

本文只是簡(jiǎn)述了,路由變化原理,并未去React/Vue結(jié)合 去完成實(shí)現(xiàn)一個(gè)框架路由。后續(xù)學(xué)習(xí)后會(huì)補(bǔ)上!

參考

Hash路由

history路由

作者:易企秀——D_Q_

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/106516.html

相關(guān)文章

  • 頁(yè)面路由切換原理/簡(jiǎn)實(shí)現(xiàn)

    摘要:新增一條記錄替換當(dāng)前的記錄實(shí)現(xiàn)核心路由綁定標(biāo)簽綁定事件并阻止默認(rèn)事件總結(jié)本文只是簡(jiǎn)述了,路由變化原理,并未去結(jié)合去完成實(shí)現(xiàn)一個(gè)框架路由。 前言 最近學(xué)習(xí)react時(shí),在使用react-router-dom的時(shí)候,對(duì)history原理與路由切換實(shí)現(xiàn)并不了解,經(jīng)過(guò)學(xué)習(xí)后總結(jié)一下吧! 如果你只是使用react 自帶history 那下面這些原理,你可能并不會(huì)用到。但當(dāng)需要使用自己的hist...

    DandJ 評(píng)論0 收藏0
  • vue-router實(shí)現(xiàn)原理

    摘要:我們知道是的核心插件,而當(dāng)前項(xiàng)目一般都是單頁(yè)面應(yīng)用,也就是說(shuō)是應(yīng)用在單頁(yè)面應(yīng)用中的。原理是傳統(tǒng)的頁(yè)面應(yīng)用,是用一些超鏈接來(lái)實(shí)現(xiàn)頁(yè)面切換和跳轉(zhuǎn)的其實(shí)剛才單頁(yè)面應(yīng)用跳轉(zhuǎn)原理即實(shí)現(xiàn)原理實(shí)現(xiàn)原理原理核心就是更新視圖但不重新請(qǐng)求頁(yè)面。 近期面試,遇到關(guān)于vue-router實(shí)現(xiàn)原理的問(wèn)題,在查閱了相關(guān)資料后,根據(jù)自己理解,來(lái)記錄下。我們知道vue-router是vue的核心插件,而當(dāng)前vue項(xiàng)目...

    vibiu 評(píng)論0 收藏0
  • 你需要知道的頁(yè)面路由實(shí)現(xiàn)原理

    摘要:顯示為顯示為顯示為單頁(yè)面應(yīng)用用戶訪問(wèn)軌跡埋點(diǎn)開發(fā)過(guò)單頁(yè)面應(yīng)用的同學(xué),一定比較清楚,單頁(yè)面應(yīng)用的路由切換是無(wú)感知的,不會(huì)重新進(jìn)行請(qǐng)求去獲取頁(yè)面,而是通過(guò)改變頁(yè)面渲染視圖來(lái)實(shí)現(xiàn)。 前言 最近開發(fā)的埋點(diǎn)項(xiàng)目,需要記錄用戶行為軌跡即用戶頁(yè)面訪問(wèn)順序。需要在頁(yè)面跳轉(zhuǎn)的時(shí)候,記錄用戶訪問(wèn)的信息(比如 url ,請(qǐng)求頭部等),非單頁(yè)面應(yīng)用可以給 window 對(duì)象加上一個(gè) beforeunload ...

    light 評(píng)論0 收藏0
  • 【Vue.js 牛刀小試】:第十二章 - 使用 Vue Router 實(shí)現(xiàn) Vue 中的前端路由控制

    摘要:而路由則是使用了中新增的事件和事件。總結(jié)這一章主要是介紹了如何使用在中構(gòu)建我們的前端路由。 系列目錄地址 一、基礎(chǔ)知識(shí)概覽 第一章 - 一些基礎(chǔ)概念(posted at 2018-10-31) 第二章 - 常見的指令的使用(posted at 2018-11-01) 第三章 - 事件修飾符的使用(posted at 2018-11-02) 第四章 - 頁(yè)面元素樣式的設(shè)定(posted a...

    cpupro 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<