主頁 > 前端設計 > 50、路由vue-router

50、路由vue-router

2021-06-12 08:31:27 前端設計

參考:https://blog.csdn.net/qq_31967569/article/details/91546294

目錄

1、對路由的理解?

2、路由的實作程序

3、前端路由的兩種實作方式:基于hash 和基于history

3.1 hash模式

3.2 history模式

3.3 兩種模式對比

4、Vue-Router 的懶加載如何實作

4.1 方案一(常用):使用箭頭函式+import動態加載

4.2 方案二:使用箭頭函式+require動態加載

4.3 方案三:使用webpack的require.ensure技術,也可以實作按需加載,

5、 如何定義動態路由?如何獲取傳過來的動態引數?

5.1 param方式

5.2 query方式

5.3 params和query的區別?

6、Vue-router 導航守衛

6.1 全域的守衛

6.2 路由獨享的守衛

6.3 組件內的守衛

7、對前端路由的理解

8、Vue-router跳轉和location.href有什么區別


1、對路由的理解?

路由,其實就是指向的意思,當我點擊頁面上的home按鈕時,頁面中就要顯示home的內容,如果點擊頁面上的about 按鈕,頁面中就要顯示about 的內容,Home按鈕 => home 內容, about按鈕 => about 內容,也可以說是一種映射. 所以在頁面上有兩個部分,一個是點擊部分,一個是點擊之后,顯示內容的部分,

點擊之后,怎么做到正確的對應,比如,我點擊home 按鈕,頁面中怎么就正好能顯示home的內容,這就要在js 檔案中配置路由

路由中有三個基本的概念 route, routes, router:

  1. route(路由資訊物件):它是一條路由,由這個英文單詞可看出 它是單數,Home按鈕 => home內容, 這是一條route, about按鈕 => about 內容,這是另一條路由,route物件 {path:’/home’, component: home},包括 path,params,hash,query,fullPath,matched,name 等路由資訊引數;
  2. routes:是一組路由把上面的每一條路由組合起來,形成一個陣列,[{home 按鈕 =>home內容 }, { about按鈕 => about 內容}];
  3. router(路由實體物件): 是一個機制,相當于一個管理者,它來管理路由,因為routes 只是定義了一組路由,它放在哪里是靜止的,當真正來了請求,怎么辦? 就是當用戶點擊home 按鈕的時候,怎么辦?這時router 就起作用了,它到routes 中去查找,去找到對應的 home 內容,所以頁面中就顯示了 home 內容,包括了路由的跳轉方法,鉤子函式等,
  4. 客戶端中的路由:實際上就是dom 元素的顯示和隱藏直接找到與地址匹配的一個組件或物件并將其渲染出來,改變瀏覽器地址而不向服務器發出請求當頁面中顯示home 內容的時候,about 中的內容全部隱藏,反之也是一樣,客戶端路由有兩種實作方式基于hash 和基于history

2、路由的實作程序

在vue中實作路由還是相對簡單的,因為頁面中所有內容都是組件化的,我們只要把路徑和組件對應起來就可以了,然后在頁面中把組件渲染出來

  1. <router-link>:對應點擊部分,to屬性表示定義點擊之后,要到哪里去,例 點擊Home后,跳轉到/home :<router-link to="/home">Home</router-link>
  2. <router-view>:對應顯示部分,其實它就是一個占位符,它在什么地方,匹配路徑的組件就顯示在什么地方,<router-view></router-view>
<template>
  <div id="app">
    <header>
    <!-- router-link 定義點擊后導航到哪個路徑下 -->
      <router-link to="/home">Home</router-link>
      <router-link to="/about">About</router-link>
    </header>
    <!-- 對應的組件內容渲染到router-view中 -->
    <router-view></router-view>   
  </div>
</template>

(1)在js中配置路由,

首先要定義route物件, 一條路由的實作,由兩個部分組成: 路徑path和對應的組件component. 如:route物件 {path:’/home’, component: home},兩條路由,組成一個routes:

const routes = [
  { path: '/home', component: Home },  //訪問路徑/home時,顯示Home組件
  { path: '/about', component: About } //訪問路徑/about時,顯示About組件
]

(2)創建router 對路由進行管理,它由建構式 new vueRouter() 創建,接受routes 引數

const router = new VueRouter({
      routes // routes: routes 的簡寫
})

(3)配置完成后把router 實體注入到 vue 根實體中,就可以使用路由了

const app = new Vue({
  router
}).$mount('#app')

執行程序:

  1. 當用戶點擊 router-link 標簽時,會去尋找它的 to 屬性;
  2. 它的 to 屬性和 js 中配置的路徑 { path: '/home', component: Home} 對應,從而找到了匹配的組件;
  3. 最后把組件渲染到 <router-view> 標簽所在的地方,

3、前端路由的兩種實作方式基于hash 和基于history

3.1 hash模式

(1)簡介:開發中默認的模式,它的URL帶著一個#,例如:www.abc.com/#/vue,它的hash值就是#/vue“www.baidu.com/#/hashhash,它的hash值就是 “#/hashhash” ,(此 hash 不是密碼學里的散列運算)

(2)特點hash值會出現在URL里面,但是不會出現在HTTP請求中對后端完全沒有影響,所以改變hash值,不會重新加載頁面,這種模式的瀏覽器支持度很好,低版本的IE瀏覽器也支持這種模式,hash路由被稱為是前端路由,已經成為SPA(單頁面應用)的標配,

(3)原理: hash模式的主要原理就是onhashchange()事件,使用hash模式時,我們可以考慮對每個路由注冊一個映射函式,頁面加載時,在window注冊onhashchange事件的監聽函式每次切換url,就呼叫對應的映射函式

window.onhashchange = function(event){
	console.log(event.oldURL, event.newURL);
	let hash = location.hash.slice(1);
}

觸發hash變化的方式主要有兩種

  1. 通過a標簽,并為a設定href屬性,當用戶點擊這個標簽后,URL就會發生改變,觸發onhashchange 事件,達到切換路由的目的;
  2. 直接使用JavaScript來對loaction.hash進行賦值,從而改變URL,觸發onhashchange事件,

使用onhashchange()事件的好處就是

  1. 頁面的hash值發生變化時,無需向后端發起請求,window就可以監聽事件的改變,并按規則加載相應的代碼;
  2. hash值變化對應的URL都會被瀏覽器記錄下來,這樣瀏覽器就能實作頁面的前進和后退,雖然是沒有請求后端服務器,但是頁面的hash值和對應的URL關聯起來了,

(4)如何獲取頁面的hash變化

1)通過watch 監聽$route的變化

// 監聽,當路由發生變化的時候執行
watch: {
  $route: {
    handler: function(val, oldVal){
      console.log(val);
    },
    // 深度觀察監聽
    deep: true
  }
},

2)window.location.hash讀取#值 ,window.location.hash 的值可讀可寫,讀取來判斷狀態是否改變,寫入時可以在不多載網頁的前提下,添加一條歷史訪問記錄 ,

3.2 history模式

(1)簡介:history模式的URL中沒有#,它使用的是傳統的路由分發模式,即用戶在輸入一個URL時,服務器會接收這個請求,并決議這個URL,然后做出相應的邏輯處理

(2)特點:當使用history模式時,URL就像這樣:abc.com/user/id相比hash模式更加好看,但是,history模式需要后臺配置支持,如果后臺沒有正確配置,訪問時會回傳404,所以,需要在服務端增加一個覆寫所有情況的候選資源:如果 URL 匹配不到任何靜態資源,則應該回傳單頁應用的 html 檔案,

(3)History主要的API分為兩大部分,切換歷史狀態修改歷史狀態

  • 修改歷史狀態:包括了 HTML5 History Interface 中新增的 pushState() replaceState() 方法,這兩個方法應用于瀏覽器的歷史記錄堆疊,提供了對歷史記錄進行修改的功能,只是當他們修改了url時,但瀏覽器不會立即向后端發送請求(即不進行重繪),如果要做到改變url但又不重繪頁面的效果,就需要前端用上這兩個API,
  1. pushState() : 新增一個歷史記錄
  2. replaceState(): 直接替換當前的歷史記錄

這兩個api都接受三個引數:

window.history.pushState(state,title, "http://www.163.com");
  1. state:合法的 Javascript 物件,可以用在 popstate 事件中;
  2. title:現在大多瀏覽器忽略這個引數,可以直接用 null 代替;
  3. url:任意有效的 URL,用于更新瀏覽器的地址欄,
  • 切換歷史狀態: 包括forward()back()go()三個方法,對應瀏覽器的前進,后退,跳轉操作,

(4)對于單頁應用的 history 模式而言,url 的改變有三種方式:

  1. 點擊瀏覽器的前進或后退按鈕
  2. 點擊 a 標簽
  3. JS 中主動觸發 history.pushState 和replaceState函式

方式1,3都能觸發popstate ,所以我們只需要對a標簽處理,通過對取消a標簽的默認行為,然后呼叫pushState來觸發路徑變化,

(5)雖然history模式丟棄了丑陋的#,但是,它也有自己的缺點,就是在重繪頁面的時候,如果沒有相應的路由或資源,就會刷出404來,

如果想要切換到history模式,就要進行以下配置(后端也要進行配置):

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

3.3 兩種模式對比

呼叫 history.pushState() 相比于直接修改 hash,存在以下優勢:

  1. pushState() 設定的新 URL 可以是與當前 URL 同源的任意 URL而 hash 只可修改 # 后面的部分,因此只能設定與當前 URL 同檔案的 URL
  2. pushState() 設定的新 URL 可以與當前 URL 一模一樣,這樣也會把記錄添加到堆疊中;而 hash 設定的新值必須與原來不一樣才會觸發動作將記錄添加到堆疊中;
  3. pushState() 通過 stateObject 引數可以添加任意型別的資料到記錄中;而 hash 只可添加短字串
  4. pushState() 可額外設定 title 屬性供后續使用,
  5. hash模式下僅hash符號之前的url會被包含在請求中,后端如果沒有做到對路由的全覆寫,也不會回傳404錯誤history模式下,前端的url必須和實際向后端發起請求的url一致如果沒有對用的路由處理,將回傳404錯誤

hash模式和history模式都有各自的優勢和缺陷,還是要根據實際情況選擇性的使用,

4、Vue-Router 的懶加載如何實作

Vue 是單頁面應用,可能會有很多的路由引入 ,這樣使用 webpcak 打包后的檔案很大,當進入首頁時,加載的資源過多,頁面會出現白屏的情況,不利于用戶體驗,而運用懶加載則可以將頁面進行劃分,需要的時候加載頁面,可以有效的分擔首頁所承擔的加載壓力,這樣就更加高效了,這樣會大大提高首屏顯示的速度,但是可能其他的頁面的速度就會降下來

4.1 方案一(常用):使用箭頭函式+import動態加載

import通過這種特殊注釋語法,將幾個路由放到一個組中 :

// 這三個組件分為一組:login_home_welcome
const Login = () => import(/* webpackChunkName: "login_home_welcome" */ '@/components/Login.vue')
const Home = () => import(/* webpackChunkName: "login_home_welcome" */ '@/components/Home.vue')
const Welcome = () => import(/* webpackChunkName: "login_home_welcome" */ '@/components/Welcome.vue')


const router = new Router({
  routes: [
    { path: '/login', component: Login },
    { path: '/home',  component: Home  },
    { path: '/welcome', component: Welcome }
  ]

(1)安裝開發依賴@babel/plugin-syntax-dynamic-import

(2)在組態檔babel.config.js中宣告該插件

(3)將路由改為按需加載的形式

其中 import(/*分組名:劃分大同一分組的多個組件*/ 路由組件)

4.2 方案二:使用箭頭函式+require動態加載

const router = new Router({
  routes: [
   {
     path: '/list',
     component: resolve => require(['@/components/list'], resolve)
   }
  ]
})

4.3 方案三:使用webpack的require.ensure技術,也可以實作按需加載,

這種情況下,多個路由指定相同的chunkName,會合并打包成一個js檔案

//require.ensure(當前需要進來的模塊的一些依賴, 回呼函式 動態引入其他模塊, 打包的組塊名稱)
const Foo = resolve => require.ensure([], () => resolve(require('./Foo.vue')), 'group-foo')
const Bar = resolve => require.ensure([], () => resolve(require('./Bar.vue')), 'group-foo')
const Baz = resolve => require.ensure([], () => resolve(require('./Baz.vue')), 'group-foo')
require.ensure(
  dependencies:String [],
  callback:function(require),
  errorCallback:function(error),
  chunkName:String
)

require.ensure()接受四個引數:

  • 第一個引數:表依賴關系,是一個陣列,代表了當前需要進來的模塊的一些依賴;
  • 第二個引數: 是一個回呼函式,這個有一個引數要求,通過回呼函式的require可以動態引入組件,雖然require是回呼函式的引數,但是其名稱實際上是不能換的,否則WebPack就無法靜態分析的時候處理它;
  • 第三個引數:errorCallback比較好理解,就是處理錯誤的回呼;
  • 第四個引數:chunkName則是指定打包的組塊名稱,

5、 如何定義動態路由?如何獲取傳過來的動態引數?

5.1 param方式

  • 配置路由格式:使用冒號:系結動態引數, /user/:userid
const routes = [{ //配置路由的index.js檔案
    path: '/user/:userid',
    name: 'users',
    component: User
}]
  • 傳遞的方式:在path后面跟上對應的值 '/user/'+id
<router-link :to="'/user/'+id" >用戶</router-link>
  • 傳遞后形成的路徑:/router/123

(1)路由定義

const routes = [{ //配置路由的index.js檔案
    path: '/user/:userid',
    name: 'users',
    component: User
}]

(2)路由跳轉

1)方法一 使用router-link實作路由跳轉:使用字串,在路徑后面直接跟上對應的值

屬性名userId使用自己的id,不必與路由配置的路徑中一致

<router-link :to="'/user/'+userId" replace>用戶</router-link> 

2)方法二 使用router-link實作路由跳轉:使用物件的方式,

name: 'users' 的屬性名和屬性值 必須跟配置路由中的一致
params中的屬性名userid 必須與配置路由path中的'/user/:userid'一致

<router-link :to="{ name: 'users', params: { userid: userId}}">用戶</router-link>

配置路由的index.js檔案中,需定義name屬性,才可使用方法二

3)方法三:使用$router的方式進行路由的跳轉

this.$router.push('/user/' + this.userId)

// 或
this.$router.push({
   name: 'users', //屬性名和屬性值 必須與路由一致
   params: { // id屬性名 必須與路由一致
     userid: this.userId
   }
})

配置路由的index.js檔案中,需定義name屬性,才可使用方法三

(3)引數獲取

1)方式一:通過 $route.params.userid 獲取傳遞的值(userid 表要查詢的引數),

2)方式二:組件中也可以用props來接受引數,前提是需要在路由配置中設定props為true

const routes = [{ //配置路由的index.js檔案
    path: '/user/:userid',
    name: 'users',
    component: User,
   //ture,代表將path后面的引數作為值,傳遞到組件中,組件中通過props屬性接受這個值
    props:true
}]

在組件中通過props接收引數

<script>   // 組件中
export default {
	 props:{
		 name:{
			 type:String,
			 default:'lily' //默認情況
		 },
		 id:{
			 type:Number,
			 default:'0' //默認情況
		 }
	 }
}
</script>

3)$router 和 $route的區別

  • $router : 是路由操作物件,只寫物件
  • $route : 路由資訊物件,只讀物件

5.2 query方式

  • 配置路由格式:/router,也就是普通配置
const routes = [{ //配置路由的index.js檔案
    path: '/user/:userid',
    name: 'users',
    component: User
}]
  • 傳遞的方式:物件中使用query的key作為傳遞方式,

注意:query傳參的方式只可以通過物件,不可以使用字串,

里面的屬性名(如本例中的id)可以隨便起名,不像params方式傳參時受限

<router-link :to="{path:'/user',query:{id:18, name:'sh'}">用戶</router-link>
  • 傳遞后形成的路徑:/route?id=18 & name=sh,引數之間用&符號連接
localhost:8080/user?id=18 & name=sh

(1)路由定義(普通的路由配置)

const routes = [{ //配置路由的index.js檔案
    path: '/user/:userid',
    name: 'users',
    component: User
}]

(2)路由跳轉

1)方法一 使用router-link方式實作路由跳轉:使用name

屬性名name 和 其屬性值 需與路由配置中的 name: 'users' 一致

<router-link :to="{ name: 'users', query: { uname: james }}">按鈕</router-link>

2)方法二 使用router-link方式實作路由跳轉:使用path

<router-link :to="{ path: '/user', query: { uname:james }}">按鈕</router-link>

3)方法三 使用$router的方式進行路由的跳轉

// 方式1 使用name
this.$router.push({ name: 'users', query:{ uname:james }}) 

// 方式2 使用路徑
this.$router.push({ path: '/user', query:{ uname:james }})

// 方式3 直接將傳的參添加到路徑后
this.$router.push('/user?uname=' + jsmes)

(3)引數獲取

1)方式一:通過 $route.query.userid 獲取傳遞的值(userid 表要查詢的引數),

2)方式二:組件中也可以用props來接受引數,前提是需要在路由配置中設定props為true

與params中的方式二一樣,

5.3 params和query的區別?

  1. params方式路由的引入只能用name;query方式路由的引入可以用name和path,
  2. params的引數是URL不可或缺的一部分,一定要加路由后面添加引數path: '/user/:userid',不添加重繪頁面資料會丟失;而query是拼接在url后面的引數,路由后面不添加也沒關系,
  3. params 在瀏覽器地址欄中不顯示引數;query則顯示,params相當于post請求,引數不會在地址欄中顯示;query相當于get請求,頁面跳轉的時候,可以在地址欄看到請求引數,

6、Vue-router 導航守衛

  1. 全域的守衛:beforeEach(全域前置)、beforeResolve(全域決議)、afterEach(全域后置);寫在router.js 檔案中;
  2. 路由獨享的守衛:beforeEnter;寫在router單個路由中
  3. 組件內的守衛:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave;寫在組件中,

優先級:①>②>③,組件內的守衛優先級是最低的

6.1 全域的守衛

(1)beforeEach(全域前置守衛)

對用于訪問網頁的情況進行相應的跳轉,例如初次登入,不能訪問除登錄頁面外的頁面,已登錄會自動跳轉自首頁等等

const router = new VueRouter({...})
 
//使用router.beforeEach注冊一個全域前置守衛
router.beforeEach((to,from,next) =>{
    //...
})
  1. to: 將要訪問的路徑;
  2. from:當前導航正要離開的路由;
  3. next 是一個函式,表示放行, next() 放行、next('/login') 強制跳轉到到該路徑, 確保要呼叫next方法,否則鉤子就不會被resolved ,

(2)beforeResolve(全域決議)

這和router.beforeEach類似,區別是在導航被確認之前,同時在所有組件內守衛和異步路由組件被決議之后,決議守衛就被呼叫

(3)afterEach(全域后置)

不同的是,后置守衛不會接收next函式,也不會改變導航本身

router.afterEach((to,from)=>{
   //...
})

6.2 路由獨享的守衛

單個路由獨享的守衛,可以在單個路由中直接定義(方法、引數等都和全域前置守衛beforeEach一樣)

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }]})

6.3 組件內的守衛

都有三個引數:to, from, next

  1. beforeRouteEnter:路由進入之前呼叫,不能獲取組件實體 `this` ,因為當守衛執行前,組件實體還沒被創建,
  2. beforeRouteUpdate:路由更新呼叫,在當前路由改變,但是該組件被復用時呼叫,
  3. beforeRouteLeave:導航離開該組件的對應路由時呼叫,用來禁止用戶在還未保存修改前突然離開,
watch: {
    $route(to, from) {
      //當使用路由引數時,例如從 /user/foo 導航到 /user/bar,原來的組件實體會被復用,因為兩個路由都渲染同個組件,比起銷毀再創建,復用則顯得更加高效,不過,這也意味著組件的生命周期鉤子不會再被呼叫,復用組件時,想對路由引數的變化作出回應的話,你可以簡單地 watch (監測變化) $route 物件
      // 對路由變化作出回應...
      console.log(" // 對路由變化作出回應...");
    }
}, //監聽
beforeRouteEnter(to, from, next) {
    //路由進入之前呼叫
    // 在渲染該組件的對應路由被 confirm 前呼叫
    // 不!能!獲取組件實體 `this`
    // 因為當守衛執行前,組件實體還沒被創建
    //console.log(from);//上一個激活的路由
    //console.log(to);//當前路由
    next(vm => {
      // 通過 `vm` 訪問組件實體
      console.log(vm)//當前激活的路由對應的組件物件
    });
    // next();
  },
  beforeRouteUpdate(to, from, next) {
    //路由更新呼叫
    // 在當前路由改變,但是該組件被復用時呼叫
    // 舉例來說,對于一個帶有動態引數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
    // 由于會渲染同樣的 Foo 組件,因此組件實體會被復用,而這個鉤子就會在這個情況下被呼叫,
    // 可以訪問組件實體 `this`
    // console.log(to);
    next();
  },
  beforeRouteLeave(to, from, next) {
    //這個離開守衛通常用來禁止用戶在還未保存修改前突然離開,該導航可以通過 next(false) 來取消
    // 導航離開該組件的對應路由時呼叫
    // 可以訪問組件實體 `this`
    //to是將要去的路由
    //from是將要離開的路由(也就是當前的路由)
    const answer = window.confirm(
      "Do you really want to leave? you have unsaved changes!"
    );
    if (answer) {
      next();
    } else {
      next(false);
    }
  },

補充:鉤子函式

  • 是個函式,在系統訊息觸發時被系統呼叫 ,在系統級對所有訊息、事件進行過濾;
  • 不是用戶自己觸發的

7、對前端路由的理解

在前端技術早期,一個 url 對應一個頁面,如果要從 A 頁面切換到 B 頁面,那么必然伴隨著頁面的重繪,這個體驗并不好,不過在最初也是無奈之舉——用戶只有在重繪頁面的情況下,才可以重新去請求資料,

后來,改變發生了——Ajax 出現了,它允許人們在不重繪頁面的情況下發起請求;與之共生的,還有“不重繪頁面即可更新頁面內容”這種需求,在這樣的背景下,出現了 SPA(單頁面應用),

SPA極大地提升了用戶體驗,它允許頁面在不重繪的情況下更新頁面內容,使內容的切換更加流暢,但是在 SPA 誕生之初,人們并沒有考慮到“定位”這個問題——在內容切換前后,頁面的 URL 都是一樣的,這就帶來了兩個問題:

  • SPA 其實并不知道當前的頁面“進展到了哪一步”,可能在一個站點下經過了反復的“前進”才終于喚出了某一塊內容,但是此時只要重繪一下頁面,一切就會被清零,必須重復之前的操作、才可以重新對內容進行定位——SPA 并不會“記住”你的操作,
  • 由于有且僅有一個 URL 給頁面做映射,這對 SEO 也不夠友好,搜索引擎無法收集全面的資訊

為了解決這個問題,前端路由出現了,

前端路由可以幫助我們在僅有一個頁面的情況下,“記住”用戶當前走到了哪一步——為 SPA 中的各個視圖匹配一個唯一標識,這意味著用戶前進、后退觸發的新內容,都會映射到不同的 URL 上去,此時即便他重繪頁面,因為當前的 URL 可以標識出他所處的位置,因此內容也不會丟失

那么如何實作這個目的呢?首先要解決兩個問題:

  • 當用戶重繪頁面時,瀏覽器會默認根據當前 URL 對資源進行重新定位(發送請求),這個動作對 SPA 是不必要的,因為我們的 SPA 作為單頁面,無論如何也只會有一個資源與之對應,此時若走正常的請求-重繪流程,反而會使用戶的前進后退操作無法被記錄,
  • 單頁面應用對服務端來說,就是一個URL、一套資源,那么如何做到用“不同的URL”來映射不同的視圖內容呢?

從這兩個問題來看,服務端已經完全救不了這個場景了,所以要靠咱們前端自力更生,不然怎么叫“前端路由”呢?作為前端,可以提供這樣的解決思路:

  • 攔截用戶的重繪操作,避免服務端盲目回應、回傳不符合預期的資源內容,把重繪這個動作完全放到前端邏輯里消化掉,
  • 感知 URL 的變化,這里不是說要改造 URL、憑空制造出 N 個 URL 來,而是說 URL 還是那個 URL,只不過我們可以給它做一些微小的處理——這些處理并不會影響 URL 本身的性質,不會影響服務器對它的識別,只有我們前端感知的到,一旦我們感知到了,我們就根據這些變化、用 JS 去給它生成不同的內容,

8、Vue-router跳轉和location.href有什么區別

  • 使用 location.href= /url 來跳轉,簡單方便,但是重繪了頁面;
  • 使用 history.pushState( /url ) ,無重繪頁面,靜態跳轉;
  • 引進 router ,然后使用 router.push( /url ) 來跳轉,使用了 diff 演算法,實作了按需加載,減少了 dom 的消耗,其實使用 router 跳轉和使用 history.pushState() 沒什么差別的,因為vue-router就是用了 history.pushState() ,尤其是在history模式下,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/286781.html

標籤:其他

上一篇:一文帶你使用Vue完成移動端(apk)專案

下一篇:前端進階全堆疊入門級教程nodeJs博客開發(一)搭建環境與路由

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • vue移動端上拉加載

    可能做得過于簡單或者比較low,請各位大佬留情,一起探討技術 ......

    uj5u.com 2020-09-10 04:38:07 more
  • 優美網站首頁,頂部多層導航

    一個個人用的瀏覽器首頁,可以把一下常用的網站放在這里,平常打開會比較方便。 第一步,HTML代碼 <script src=https://www.cnblogs.com/szharf/p/"js/jquery-3.4.1.min.js"></script> <div id="navigate"> <ul> <li class="labels labels_1"> ......

    uj5u.com 2020-09-10 04:38:47 more
  • 頁面為要加<!DOCTYPE html>

    最近因為寫一個js函式,需要用到$(window).height(); 由于手寫demo的時候,過于自信,其實對前端方面的認識也不夠體系,用文本檔案直接敲出來的html代碼,第一行沒有加上<!DOCTYPE html> 導致了$(window).height();的結果直接是整個document的高 ......

    uj5u.com 2020-09-10 04:38:52 more
  • WordPress網站程式手動升級要做好資料備份

    WordPress博客網站程式在進行升級前,必須要做好網站資料的備份,這個問題良家佐言是遇見過的;在剛開始接觸WordPress博客程式的時候,因為升級問題和博客網站的修改的一些嘗試,良家佐言是吃盡了苦頭。因為購買的是西部數碼的空間和域名,每當佐言把自己的WordPress博客網站搞到一塌糊涂的時候 ......

    uj5u.com 2020-09-10 04:39:30 more
  • WordPress程式不能升級為5.4.2版本的原因

    WordPress是一款個人博客系統,受到英文博客愛好者和中文博客愛好者的追捧,并逐步演化成一款內容管理系統軟體;它是使用PHP語言和MySQL資料庫開發的,用戶可以在支持PHP和MySQL資料庫的服務器上使用自己的博客。每一次WordPress程式的更新,就會牽動無數WordPress愛好者的心, ......

    uj5u.com 2020-09-10 04:39:49 more
  • 使用CSS3的偽元素進行首字母下沉和首行改變樣式

    網頁中常見的一種效果,首字改變樣式或者首行改變樣式,效果如下圖。 代碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, ......

    uj5u.com 2020-09-10 04:40:09 more
  • 關于a標簽的講解

    什么是a標簽? <a> 標簽定義超鏈接,用于從一個頁面鏈接到另一個頁面。 <a> 元素最重要的屬性是 href 屬性,它指定鏈接的目標。 a標簽的語法格式:<a href=https://www.cnblogs.com/summerxbc/p/"指定要跳轉的目標界面的鏈接">需要展示給用戶看見的內容</a> a標簽 在所有瀏覽器中,鏈接的默認外觀如下: 未被訪問的鏈接帶 ......

    uj5u.com 2020-09-10 04:40:11 more
  • 前端輪播圖

    在需要輪播的頁面是引入swiper.min.js和swiper.min.css swiper.min.js地址: 鏈接:https://pan.baidu.com/s/15Uh516YHa4CV3X-RyjEIWw 提取碼:4aks swiper.min.css地址 鏈接:https://pan.b ......

    uj5u.com 2020-09-10 04:40:13 more
  • 如何設定html中的背景圖片(全屏顯示,且不拉伸)

    1 <style>2 body{background-image:url(https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture); 3 background-size:cover;background ......

    uj5u.com 2020-09-10 04:40:16 more
  • Java學習——HTML詳解(上)

    HTML詳解 初識HTML Hyper Text Markup Language(超文本標記語言) 1 <!--DOCTYPE:告訴瀏覽器我們要使用什么規范--> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <!--meta 描述性的標簽,描述一些 ......

    uj5u.com 2020-09-10 04:40:33 more
最新发布
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 07:59:23 more
  • 生產事故-走近科學之消失的JWT

    入職多年,面對生產環境,盡管都是小心翼翼,慎之又慎,還是難免捅出簍子。輕則滿頭大汗,面紅耳赤。重則系統停擺,損失資金。每一個生產事故的背后,都是寶貴的經驗和教訓,都是專案成員的血淚史。為了更好地防范和遏制今后的各類事故,特開此專題,長期更新和記錄大大小小的各類事故。有些是親身經歷,有些是經人耳傳口授 ......

    uj5u.com 2023-04-18 07:55:04 more
  • 記錄--Canvas實作打飛字游戲

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 打開游戲界面,看到一個畫面簡潔、卻又富有挑戰性的游戲。螢屏上,有一個白色的矩形框,里面不斷下落著各種單詞,而我需要迅速地輸入這些單詞。如果我輸入的單詞與螢屏上的單詞匹配,那么我就可以獲得得分;如果我輸入的單詞錯誤或者時間過長,那么我就會輸 ......

    uj5u.com 2023-04-04 08:35:30 more
  • 了解 HTTP 看這一篇就夠

    在學習網路之前,了解它的歷史能夠幫助我們明白為何它會發展為如今這個樣子,引發探究網路的興趣。下面的這張圖片就展示了“互聯網”誕生至今的發展歷程。 ......

    uj5u.com 2023-03-16 11:00:15 more
  • 藍牙-低功耗中心設備

    //11.開啟藍牙配接器 openBluetoothAdapter //21.開始搜索藍牙設備 startBluetoothDevicesDiscovery //31.開啟監聽搜索藍牙設備 onBluetoothDeviceFound //30.停止監聽搜索藍牙設備 offBluetoothDevi ......

    uj5u.com 2023-03-15 09:06:45 more
  • canvas畫板(滑鼠和觸摸)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>canves</title> <style> #canvas { cursor:url(../images/pen.png),crosshair; } #canvasdiv{ bo ......

    uj5u.com 2023-02-15 08:56:31 more
  • 手機端H5 實作自定義拍照界面

    手機端 H5 實作自定義拍照界面也可以使用 MediaDevices API 和 <video> 標簽來實作,和在桌面端做法基本一致。 首先,使用 MediaDevices.getUserMedia() 方法獲取攝像頭媒體流,并將其傳遞給 <video> 標簽進行渲染。 接著,使用 HTML 的 < ......

    uj5u.com 2023-01-12 07:58:22 more
  • 記錄--短視頻滑動播放在 H5 下的實作

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 短視頻已經無數不在了,但是主體還是使用 app 來承載的。本文講述 H5 如何實作 app 的視頻滑動體驗。 無聲勝有聲,一圖頂百辯,且看下圖: 網址鏈接(需在微信或者手Q中瀏覽) 從上圖可以看到,我們主要實作的功能也是本文要講解的有: ......

    uj5u.com 2023-01-04 07:29:05 more
  • 一文讀懂 HTTP/1 HTTP/2 HTTP/3

    從 1989 年萬維網(www)誕生,HTTP(HyperText Transfer Protocol)經歷了眾多版本迭代,WebSocket 也在期間萌芽。1991 年 HTTP0.9 被發明。1996 年出現了 HTTP1.0。2015 年 HTTP2 正式發布。2020 年 HTTP3 或能正... ......

    uj5u.com 2022-12-24 06:56:02 more
  • 【HTML基礎篇002】HTML之form表單超詳解

    ??一、form表單是什么

    ??二、form表單的屬性

    ??三、input中的各種Type屬性值

    ??四、標簽 ......

    uj5u.com 2022-12-18 07:17:06 more