1. 程式人生 > 其它 >【Vue2】Router 路由

【Vue2】Router 路由

1.什麼是單頁面應用程式

單頁面應用程式(英文名: Single Page Application)簡稱SPA,

顧名思義,指的是一個Web網站中只有唯一-的一-個HTML頁面,

所有的功能與互動都在這唯--的一個頁面內完成。

結論:在SPA專案中,不同功能之間的切換,要依賴於前端路由來完成!

4.什麼是前端路由

通俗易懂的概念: Hash地址與元件之間的對應關係。

5.前端路由的工作方式

① 使用者點選了頁面.上的路由連結
② 導致了URL位址列中的Hash值發生了變化
③ 前端路由監聽了到Hash地址的變化
④ 前端路由把當前Hash地址對應的元件渲染都瀏覽器中

6、手寫路由案例:

<template>
  <div id="app">
    <a href="#/index">首頁</a> | 
    <a href="#/movie">電影</a> | 
    <a href="#/about">關於</a> 
    <component :is="routerName"></component>
  </div>
</template>

<script>
import Home from '@/components/Home.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'

export default {
  name: 'App',
  components: {
    Home,
    Movie,
    About
  },
  data() {
    return {
      routerName: ''
    }
  },
  created() {
    window.onhashchange = () => {
      const hash = location.hash
      switch (hash) {
        case '#/home':
          this.routerName = 'Home'
          break
        case '#/Movie':
          this.routerName = 'Movie'
          break
        case '#/About':
          this.routerName = 'About'
          break
      }
    }
  },
}
</script>

<style lang="less">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

1.什麼是vue-router

vue-router是vue.js官方給出的路由解決方案。

它只能結合vue專案進行使用,能夠輕鬆的管理SPA專案中元件的切換。

vue-router的官方文件地址: https://router.vuejs.org/zh/

2.使用Vue-Router步驟

① 安裝vue-router包

npm i [email protected] -S

② 建立路由模組

router/index.js

// 匯入資源配置
import Vue from 'vue' import Router from 'vue-router' // 安裝Router外掛 Vue.use(Router)
// 建立路由例項 const router = new Router() // 匯出Router例項 export default router

③ 匯入並掛載路由模組

main.js檔案中,Vue例項,入參路由例項

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

// ES6 模組匯入 如果提供的是一個目錄地址,預設匯入裡面index名稱檔案
// import router from '@/router/index.js'
import router from '@/router/index.js'

new Vue({
  render: h => h(App),
  router
}).$mount('#app')

④ 宣告路由連結和佔位符

配置路由和地址的對應關係:

import Vue from 'vue'
import Router from 'vue-router'

// 把路由對應的元件和Hash對映起來
import Home from '@/components/Index.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'

Vue.use(Router)

// 配置路由列表 path不需要寫#號 const routes = [ { path: '/home', component: Home }, { path: '/movie', component: Movie }, { path: '/about', component: About } ]
// 註冊到路由例項中 const router = new Router({ routes }) export default router

更改原來的手寫路由分配,App.vue:

改用 router-view佔位符標籤實現路由分配

<template>
  <div id="app">
    <a href="#/index">首頁</a> | 
    <a href="#/movie">電影</a> | 
    <a href="#/about">關於</a> 
  
    <router-view></router-view>
  </div>
</template>
<script> export default { name: 'App' } </script> <style lang="less"> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>

可以使用router-link代替a標籤,router-link本身還是使用a標籤做的

      使用Router-link替換a標籤
      <router-link to="/index">首頁</router-link> | 
      <router-link to="/movie">電影</router-link> | 
      <router-link to="/about">關於</router-link>

2.1、懶載入路由

https://www.cnblogs.com/mindzone/p/13909668.html

3、路由重定向問題

新的問題是,進入頁面後沒有預設頁,需要使用者自己手動點選,才會跳轉

所以需要把首頁在進入頁面時就路由進來,這個功能可以使用路由重定向來解決:

// 配置路由列表 path不需要寫#號
const routes = [
  { path: '/', redirect: '/home' },
  { path: '/home', component: Home },
  { path: '/movie', component: Movie },
  { path: '/about', component: About }
]

  

 4、子路由和子路由佔位符

路由配置:

import Vue from 'vue'
import Router from 'vue-router'

// 把路由對應的元件和Hash對映起來
import Home from '@/components/Index.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'

// 引入子元件
import SubPage1 from '@/components/about/SubPage1.vue'
import SubPage2 from '@/components/about/SubPage2.vue'

// 安裝Router外掛
Vue.use(Router)

// 設定路由的配置項
const routes = [
  { path: '/', redirect: '/index'},
  { path: '/index', component: Home },
  { 
    path: '/about', 
    component: About, 
    children: [
      // 子元件不能寫斜槓開頭, router會預設視為第一層級的規則來分配
      { path: 'tab1', component: SubPage1 },
      { path: 'tab2', component: SubPage2 }
    ]
  }
]

const router = new Router({
  routes
})

export default router

在About元件中編寫對應的佔位符:

<template>
  <div>
    <h3>關於 元件</h3>
    <p> 
      <router-link to="/about/tab1" >子頁面1</router-link>
      <router-link to="/about/tab2" >子頁面2</router-link>
    </p>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'About'
}
</script>

  

5、預設子路由或者重定向

import Vue from 'vue'
import Router from 'vue-router'

// 把路由對應的元件和Hash對映起來
import Home from '@/components/Index.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'

// 引入子元件
import SubPage1 from '@/components/about/SubPage1.vue'
import SubPage2 from '@/components/about/SubPage2.vue'

// 安裝Router外掛
Vue.use(Router)

// 設定路由的配置項
const routes = [
  { path: '/', redirect: '/index'},
  { path: '/index', component: Home },
  { 
    path: '/about', 
    component: About, 
    // 方式一:使用重定向配置
    redirect: '/about/tab1',
    children: [
      // 方式二:使用預設子路由,省略路徑實現
      // { path: '', component: SubPage1 },
      { path: 'tab1', component: SubPage1 },
      { path: 'tab2', component: SubPage2 }
    ]
  }
]

const router = new Router({
  routes
})

export default router

 

6、動態路由實現

類似Rest風格,根據引數動態渲染頁面的內容,提高頁面的複用性

<template>
  <div id="app">
      <router-link to="/movie/1">電影1</router-link> | 
      <router-link to="/movie/2">電影2</router-link> | 
      <router-link to="/movie/3>電影3</router-link>
    <hr>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App',
}
</script>

<style lang="less">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

路由配置時,宣告一個動態路徑引數標記:

在vue-router中使用英文的冒號(:) 來定義路由的引數項。

import Vue from 'vue'
import Router from 'vue-router'

// 把路由對應的元件和Hash對映起來
import Movie from '@/components/Movie.vue'

// 安裝Router外掛
Vue.use(Router)

// 設定路由的配置項
const routes = [
  /**
   * 動態引數配置
   * 
   * props: true 開啟props屬性傳參
   */
  { path: '/movie/:id', component: Movie },
]

const router = new Router({
  routes
})

export default router

元件會把路由的路徑引數封裝成物件獲取,通過下面這段程式碼獲取

this.$route.params.id

可以開啟Props屬性來接收引數

<template>
  <div>
    <!-- this.$route.params 可以獲取路由的引數 -->
    <h3>電影 元件 </h3>
    <p> 路由Rest引數 {{ $route.params.id }} -> {{ id }}</p>
  </div>
</template>

<script>
export default {
  name: 'Movie',
  props: {
    id: {
      type: String,
      default: ''
    }
  }
}
</script>

7、路徑引數和查詢引數

<template>
  <div>
    <h3>電影 元件 </h3>
    <p> 路由Rest引數 {{ $route.params.id }} -> {{ id }}</p>
    <p> 路由Query查詢引數 {{ $route.query }}</p>
  </div>
</template>

<script>
export default {
  name: 'Movie',
  props: {
    id: {
      type: String,
      default: ''
    }
  }
}
</script>

在使用路由時,附加查詢引數:

<template>
  <div id="app">
      <router-link to="/movie/1">電影1</router-link> | 
      <router-link to="/movie/2">電影2</router-link> | 
      <router-link to="/movie/3?aaa=100&bbb=true">電影3</router-link>
    <hr>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style lang="less">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

  

8、編碼式路由的跳轉

<template>
  <div>
    <!-- this.$route.params 可以獲取路由的引數 -->
    <h3>電影 元件 </h3>
    <p> 路由Rest引數 {{ $route.params.id }} -> {{ id }}</p>
    <p> 路由Query查詢引數 {{ $route.query }}</p>
    <!-- 
      宣告式導航,向上面這種直接寫標籤和路徑的實現元件跳轉被稱為宣告式導航
        普通網頁中點選<a>連結、vue專案中點選<router-link>都屬於宣告式導航

      程式設計式導航, 利用瀏覽器API實現導航的方式
        普通網頁中呼叫location.href跳轉到新頁面的方式,屬於程式設計式導航
        5.1 vue-router中的程式設計式導航API
        vue-router提供了許多程式設計式導航的API,其中最常用的導航API分別是:
        ①this.$router.push('hash 地址') 跳轉指定Hash地址,並增加一條歷史記錄
        ②this.$router.replace('hash 地址') 跳轉指定Hash地址,並替換當前的歷史記錄
        ③this.$router.go(數值 n), 
          在歷史記錄中進行前進和後退
          0 表示當前頁
          -1 後退一頁
          如果後退的頁數超過了歷史記錄的上限,則原地不動
          1 前進一頁
        在實際開發中,一般只會前進和後退一層頁面。因此vue-router提供瞭如下兩個便捷方法:
          ①$router.back()
          ②$router .forward()

        導航守衛:
          控制路由能否跳轉
        
        全域性前置首位
    -->
    <button @click="toMovie1"> 跳轉到 電影1</button> <br>
    <button @click="toAbout"> 跳轉到 關於</button>
  </div>
</template>

<script>
export default {
  name: 'Movie',
  props: {
    id: {
      type: String,
      default: ''
    }
  },
  methods: {
    toMovie1 () {
      // 直接在 <router-view> 標籤中跳轉
      this.$router.push('/movie/1')
    },
    toAbout () {
      this.$router.push('/about')
    }
  },
}
</script>

  

9、路由跳轉守衛:

import Vue from 'vue'
import Router from 'vue-router'

// 把路由對應的元件和Hash對映起來
import Home from '@/components/Index.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'

// 引入子元件
import SubPage1 from '@/components/about/SubPage1.vue'
import SubPage2 from '@/components/about/SubPage2.vue'

// 安裝Router外掛
Vue.use(Router)

// 設定路由的配置項
const routes = [
  { path: '/', redirect: '/index'},
  { path: '/index', component: Home },
  { path: '/movie/:id', component: Movie, props: true  },
  { 
    path: '/about', 
    component: About, 
    redirect: '/about/tab1',
    children: [
      { path: 'tab1', component: SubPage1 },
      { path: 'tab2', component: SubPage2 }
    ]
  }
]

const router = new Router({
  routes
})

/**
 * 全域性前置守衛
 * //呼叫路由例項物件的beforeEach 方法,即可宣告“全域性前置守衛”
 * //每次發生路由導航跳轉的時候,都會自動觸發fn這個“回撥函式"
 */
router.beforeEach(function(to, from, next) {
  // to是將要訪問的路由的資訊物件
  
  // from是將要離開的路由的資訊物件
  
  // next 是一個函式,呼叫next() 表示放行,允許這次路由導航
  
  // console.log(`to -> ${JSON.stringify(to)}`)
  // console.log(`from -> ${JSON.stringify(from)}`)

  /**
   * 當前使用者擁有後臺主頁的訪問許可權,直接放行: next()
   * 當前使用者沒有後臺主頁的訪問許可權,強制其跳轉到登入頁面: next('/login')
   * 當前使用者沒有後臺主頁的訪問許可權,不允許跳轉到後臺主頁: next(false)
   */
  next()
})

export default router

9.1、區域性元件路由配置:

https://www.cnblogs.com/mindzone/p/13910845.html