(一)Vue-路由

路由使用

  1. 靜態路由
// 路由規則
const routes = [
  {
    path: '/',
    name: 'Index',
    component: Index
  },
  {
    path: '/blog',
    name: 'Blog',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "blog" */ '../views/Blog.vue')
  }
]
  1. 動態路由
    通過當前路由規則獲取 或者 通過開啟 props 獲取, 建議通過props來解耦
// 路由規則
const routes = [
  {
    path: '/',
    name: 'Index',
    component: Index
  },
  {
    path: '/detail/:id',
    name: 'Detail',
    // 開啟 props,會把 URL 中的參數傳遞給組件
    // 在組件中通過 props 來接收 URL 參數
    //  <!-- 方式2:路由規則中開啟 props 傳參 -->
    props: true,
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "detail" */ '../views/Detail.vue')
  }
]

// 頁面
<template>
  <div>
    <!-- 方式1: 通過當前路由規則,獲取數據 -->
    通過當前路由規則獲取:{{ $route.params.id }}

    <br>
    <!-- 方式2:路由規則中開啟 props 傳參 -->
    通過開啟 props 獲取:{{ id }}
  </div>
</template>

<script>
export default {
  name: 'Detail',
  //  <!-- 方式2:路由規則中開啟 props 傳參 -->
  props: ['id']
}
</script>
<style>
</style>

3.嵌套路由

const routes = [
  {
    name: 'login',
    path: '/login',
    component: Login
  },
  // 嵌套路由
  {
    path: '/',
    component: Layout,
    children: [
      {
        name: 'index',
        // 外面的path 和 這里path拼接起來
        // 可以加/,也可以不加
        path: '',
        // 外面的Layout 和 這里Index拼接起來
        component: Index
      },
      {
        name: 'detail',
        path: 'detail/:id',
        props: true,
        component: () => import('@/views/Detail.vue')
      }
    ]
  }
]
  1. 路由跳轉replace、push、go
<script>
export default {
  name: 'Index',
  methods: {
    replace () {
      // replace沒有歷史記錄
      this.$router.replace('/login')
    },
    goDetail () {
      // 支持路由和name跳轉
      // this.$router.push({ path: '/detail/1' })
      this.$router.push({ name: 'Detail', params: { id: 1 } })
    },
    go () {
      // 返回上面二層頁面, 正數代表next, 負數代表previous
      this.$router.go(-2)
    }
  }
}
</script>

  1. hash VS History
  • hash 模式
    Vue Router 默認使用的是 hash 模式,使用 hash 來模擬一個完整的 URL,通過onhashchange 監聽路徑的變化。 有一個#號。
  • History 模式
    基于 History API ,沒有#
// 改變地址欄,同時記錄,但是不會跳轉指定路徑, IE10后支持
// 可以實現客戶端路由
history.pushState() 
// 會發起服務端請求
history.replaceState() 
history.go()

需要開啟 History 模式

const router = new VueRouter({ 
  // mode: 'hash', 
  mode: 'history', routes
})

History 需要服務器的支持
單頁應用中,服務端不存在 http://www.testurl.com/login 這樣的地址會返回找不到該頁面
在服務端應該除了靜態資源外都返回單頁應用的 index.html

服務端開啟history,刷新的時候。 其實是先給前端返回index頁面,然后再跳轉到對應login頁面

路由基礎實現

let _Vue = null
class JerryVueRouter {
    // 接收一個參數,也就是Vue類
    // Vue.use(你的插件)自動調用
    static install(Vue){
        console.log('Srs==>', Vue)
        //1 判斷當前插件是否被安裝
        if(JerryVueRouter.install.installed){
            return;
        }
        JerryVueRouter.install.installed = true
        //2 把Vue的構造函數記錄在全局
        _Vue = Vue
        //3 把創建Vue的實例傳入的router對象注入到Vue實例
        // _Vue.prototype.$router = this.$options.router
        _Vue.mixin({
            beforeCreate(){
                // 實例化為Vue 類時,會將 VueRouter 的實例傳入,這個變量放在this.$options.router中
                // 判斷是Vue實例才設置
                if(this.$options.router){
                    _Vue.prototype.$router = this.$options.router
                    
                }
            }
        })
    }
    constructor(options){
        // 包含路由規則
        this.options = options
        // 路由規則對下
        this.routeMap = {}
        // observable
        this.data = _Vue.observable({
            current:"/"
        })
        this.init()
    }
    init(){
        this.createRouteMap()
        this.initComponent(_Vue)
        this.initEvent()
    }
    createRouteMap(){
        //遍歷所有的路由規則 吧路由規則解析成鍵值對的形式存儲到routeMap中
        this.options.routes.forEach(route => {
            this.routeMap[route.path] = route.component
        });
    }
    initComponent(Vue){
        Vue.component("router-link",{
            props:{
                to:String
            },
            render(h){
                return h("a",{
                    attrs:{
                        href: this.to
                    },
                    on:{
                        click:this.clickhander
                    }
                }, [this.$slots.default])
            },
            methods:{
                // 重置點擊事件, 默認會請求后臺數據
                clickhander(e){
                    history.pushState({}, "", this.to)
                    // 響應事件,會重復view刷新
                    this.$router.data.current = this.to
                    e.preventDefault()
                }
            },
            // slot是插槽
            // 使用template需要完整版編譯
            // 需要配置vue.config.js里面的runtimeCompiler
                // module.exports = {
                //     // 完整版view,默認是false。完整版帶編譯器,多10K
                //     runtimeCompiler: true
                // } 
            // template: "<a :href='to'><slot></slot><>"
        })
        const self = this
        Vue.component("router-view",{
            render(h){
                // self.data.current
                const cm = self.routeMap[self.data.current]
                return h(cm)
            }
        })
        
    }
    initEvent(){
        // 處理瀏覽器上返回 前進按鈕
        window.addEventListener("popstate",()=>{
            this.data.current = window.location.pathname
        })
    }
}

export default JerryVueRouter
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 什么是路由 對于普通的網站,所有的超鏈接都是URL地址,所有的URL地址都對應服務器上對應的資源; 對于單頁面應用...
    wanminglei閱讀 260評論 0 0
  • 路由 用 Vue.js + Vue Router 創建單頁應用,是非常簡單的。使用 Vue.js ,我們已經可以通...
    王蕾_fd49閱讀 259評論 0 1
  • 路由可以分為前端路由和后端路由 后端路由: 概念:根據不同的用戶url請求,返回不同的內容 本質:URL請求地址和...
    zhchhhemmm閱讀 426評論 0 0
  • VUE能夠利用理由進行單頁面應用的開發我想是很多開發者選擇它的一大原因。這都歸功于vue-router的設計,讓我...
    9d0edee7bcb0閱讀 283評論 0 2
  • 后端路由:對于普通網站,所有的超鏈接都是URL地址,所有的URL地址都對應服務器上對應的資源;前端路由:對于單頁面...
    哎呦呦胖子斌閱讀 844評論 1 2