1. 程式人生 > 其它 >【紫書總結】第四章 ---函式和遞迴

【紫書總結】第四章 ---函式和遞迴

技術標籤:vue-routervue

vue-router

在研究vue的路由前,先說說什麼是路由

路由是指 當地址欄的改變時頁面做出改變

路由分為前端路由 和 後端路由

  • 後端路由就是指訪問和相應了,位址列是百度,當前的路由就是百度,如果跳轉到淘寶,路由就是淘寶,後端路由會帶來頁面重新整理
  • 前端路由是自己通過API改變位址列的內容,再判斷位址列的值修改頁面的內容,最重要的是前端路由是可以被瀏覽器的history記錄,history記錄的意思就是點選返回是返回上一個路由,到了最後一個路由關閉頁面,完美的模擬後端路由的效果

為什麼要用前端路由,前端路由帶來了什麼

  • 漂亮的路由地址,去看看網易雲音樂的網頁版地址和嗶哩嗶哩的網站地址
  • 減少頁面請求,只需要ajax修改資料,只需要第一次進入請求一次頁面資料就行,稱為單頁面應用,簡稱SPA

起步
如果沒有安裝vue-router
自己去看開發文件

  1. 先npm下載
  2. 然後在建立配置檔案和基礎配置檔案的模板
  3. 最後在main.js引入

vue的路由是用什麼APIhistoryhash

window.history
// 方法有
history.pushState
history.replaceState

window.hash
// 方法有
window.hashchange = function(){ ... }

這兩個路由對應的就是vue-router的配置的引數mode,預設是hash

new Router({
  mode: 'history', // history 和 hash
  routes: [{
    path: '/',
    component: () => import('page/home'),
    children: [{
      path: 'list',
      component: () => import('page/list'),
    }]
  },{
    path: '/404',
    component: () => import('page/error')
  }]
})

mode的引數有什麼區別
history模式,這是個新API,所以相容性不好,位址列沒有【#】,嗶哩嗶哩就是沒帶【#】號的,更好看,而且在微信的分享等地方是禁止用【#】的
hash模式,位址列帶有【#】,網易雲音樂就是帶【#】號的,我不喜歡這個模式

routes引數是一個數組,這個陣列需要學的有子路由的配置和引數路由的配置
在配置之前瞭解一下vue怎麼把路由進行顯示出來的,看路由的component引數,這個是指當有人訪問這個路由,我就給他看哪個頁面的傳參,引數是一個頁面的地址,首先找到這個路徑下的地址,是.vue字尾檔案,開啟後是這樣的

<template>
   <div>
     <div>HOME</div>
     <div>{{ msg }}</div>
   </div>
</template>
<script>
export default {
  // 這個name是無意義的,只是為了好看,是程式碼規範,但不是程式碼規定
  name: 'HOME',
  data(){
     return {
       msg:"helloword"
     }
  }
}
</script>
<style scoped>
// 這是寫樣式的
// scoped屬性的意思是這裡的樣式只服務這個vue檔案
</style>

那這個檔案被顯示到哪裡了呢

vue格式檔案顯示在<router-view />標籤裡,這也是子路由的配置理解,比如上面的路由配置,當路由是【/】時,頁面顯示的是home.vue這個檔案,如果路由是【/404】就顯示的是error.vue檔案,home和error是展示在同一個<router-view />裡的,因為他們屬於同一級,把這個<router-view />理解成div的innerHTML也行,所以當我們要給路由【/】新增子路由時,就需要在home.vue檔案裡放置一個<router-view />標籤,如下

<div>我是HOME.vue</div>
<router-view />

當路由是【/】時,我們會看到我是HOME.vue,看不到<router-view />,當我們訪問【/list】時,<router-view />會繪製上list.vue檔案的程式碼,就能看到頁面顯示,我是HOME.vue,我是List.vue,應該很好理解吧

那麼問題來了,一級配置,也就是上面的【/】和【/404】是顯示在哪個<router-view />裡的,在檔案列表有個APP.vue檔案,這個才是一級路由顯示的地方,這個檔案又顯示在哪呢,顯示在public資料夾的index.html,開啟index.html,會看見一個id為app的div,跟srcipt引入外掛的方式一樣,vue腳手架最後也只是把vue給new一下,顯示到#app裡而已,檢視main.js

import App from './App'
import store from './store'
import router from './router'

new Vue({
  // 這個就是路由
  router,
  // 這個是vuex
  store,
  // render渲染,$mount是代表index.html的id
  // 即我把App.vue渲染到id為app的div裡
  render: h => h(App)
}).$mount('#app')

現在應該知道怎麼配子路由了吧,接下來引數路由【/:】

new Router({
  mode: 'history', // history 和 hash
  routes: [{
        path: '/:type/:id',
        component: () => import('page/type'),
    },{
        path: '/home/test',
        component: () => import('page/ceshi'),
    }]
})

上面的路由是要幹什麼呢,是想實現根據型別和id去返回頁面的功能,比如【/book/0001】,是指找一個編號是0001的書,【/movie/123】是找一部編號123的電影,所以我才說前段路由是那麼的好看,如果是後端路由應該是【xxx.com/index.html?type=movie&id=123】

在上面有個【/home/test】的配置,如果有人訪問這個,會跳轉到上面去嗎,這是不會的,引數路由是最後被判斷的,這個外掛是非常智慧的,先把固定的判斷完,沒合適的再去找引數路由

問題來了,我怎麼去知道當前的type是什麼,id是什麼,去到type.vue這個檔案裡

mounted(){
   // 把當前頁面的路由打印出來
   console.log(this.$route)
   // 裡面有個params屬性,是個物件
   // 把這個物件取值判斷就行
   console.log(this.$route.params)
}

除了params物件,路由還有一個query物件,就是正常的問號傳參,試一下在位址列上路由的最後面加上【?name=name&age=age】,就會在路由裡看到query物件,很好理解,不寫栗子了

總結下路由的配置
路由的配置就是複製黏貼,沒什麼可玩性,按照文件設定好就行

路由的監控
如果我想根據路由的整體的變化做一些判斷呢,如果我想控制一些許可權呢
在路由的配置頁面加上這個方法

new Router({
  mode: 'history', // history 和 hash
  routes: [{
        path: '/:type/:id',
        // 先配置一個title屬性,你想寫什麼屬性都行
        title: "我是title",
        component: () => import('page/type'),
    }]
})

下面這個監聽的程式碼可以寫在router.js裡,最好還是單獨拆一個檔案出來

router.beforeEach((to, from, next) => {
  // 這個to就是當前頁面的路由的物件,也就是this.$route
  console.log(to)
  if(to.title){ document.title = to.title } 
  else{ document.title = "pdt-1997" }
  if(user=="pdt"){
     console.log("沒資格訪問")
     // 重定向到主頁
     next({path:'/'})
  }else{
     // next一定要有,不然路由不執行
     next()
  }
})

router.afterEach(() => {
  
})

怎麼跳轉
上面的測試都是手動去改路由,再重新整理頁面
首先就是用標籤去跳轉,理解為a標籤,一般不用標籤跳轉

<router-link to="/">去到主頁</router-link>
<router-link :to="{path:'/index',query:{id:'xxx',name:'xxx'}}">

push和replace
push是把當前路由A存起來,然後跳轉B,如果點選返回會到A
replace是跳轉B,然後把B替換A,如果點選返回A之前的路由或者關閉頁面

this.$router.push({ path:"/it/"+data.id ,query:{ page:this.pageNo }})
this.$router.replace({ path:"/it/"+data.id ,query:{ page:this.pageNo }})

應該注意的點

vue檔案的template標籤的子標籤只能有一個

<template>
   <div>
     <div>HOME</div>
     <div>{{ msg }}</div>
   </div>
   <div> 如果再加上這個會報錯 </div>	
</template>

hash的實現原理

<a href="#/home">首頁</a>
<a href="#/about">關於</a>
<div id="html"></div>

<script>
    window.addEventListener('load',()=>{
        html.innerHTML = location.hash.slice(1);
    });
    window.addEventListener('hashchange',()=>{
        html.innerHTML = location.hash.slice(1)
    })
</script>

history的實現原理

<a onclick="go(/home)">首頁</a>
<a onclick="go(/about)">關於</a>
<div id="html"></div>

<script >
    function go(pathname) {
        history.pushState({},null,pathname)
        html.innerHTML = pathname;
    }
    window.addEventListener('popstate',()=>{
        go(location.pathname);
    })
</script>