vue--vue-router 元件對映到路由

丶Serendipity丶發表於2022-02-28

前言

  位址列路由的發展經歷了後端路由配置階段、前後端分離階段、直至單頁面富應用階段。本文來總結一下 vue-router 的相關知識點和用法。

正文

  1、什麼是 vue-router 路由

   路由就是SPA(單頁應用)的路徑管理器,vue-router就是WebApp的連結路徑管理系統。

  vue-router是Vue.js官方的路由外掛,它和vue.js是深度整合的,適合用於構建單頁面應用。vue的單頁面應用是基於路由和元件的,路由用於設定訪問路徑,並將路徑和元件對映起來。傳統的頁面應用,是用一些超連結來實現頁面切換和跳轉的。在vue-router單頁面應用中,則是路徑之間的切換,也就是元件的切換。路由模組的本質 就是建立起url和頁面之間的對映關係,將元件 (components) 對映到路由 (routes),然後告訴 Vue Router 在哪裡渲染它們。總之,在vue中頁面路徑的改變就是元件的切換。

  2、通過router-link訪問路由例項

  router-link 宣告式訪問路由例項,相當於a標籤來改變地址來路徑,並渲染對應的元件。

  (1)普通路由的使用,分如下三步:

    a、註冊路由元件並定義路由表

    b、建立路由例項並掛載到根例項

    c、通過 router-link 元件來導航路由,通過router-view來渲染對應的元件,同時導航欄地址跳轉。

  具體程式碼如下:

     <body>
            <div id="app">
                <p>
                    <!-- 使用 router-link 元件來導航. -->
                    <!-- 通過傳入 `to` 屬性指定連結. -->
                    <!-- <router-link> 預設會被渲染成一個 `<a>` 標籤 -->
                    <router-link to="/foo">Go to Foo</router-link>
                    <router-link :to="{name:'bar',params: { bar: 123 }}">Go to Bar</router-link>
                    <router-link :to="{name:'car',query: { car: 234 }}">Go to Car</router-link>
                </p>
                <!-- 路由出口:路由匹配到的元件將渲染在這裡 -->
                <router-view></router-view>
            </div>
     </body>
    <script>
        // 定義 (路由) 元件。
        // 可以從其他檔案 import 進來
        const Foo = { template: '<div>foo</div>' }
        const Bar = { template: '<div>bar</div>' }
        const Car = { template: '<div>Car</div>' }

        //定義路由表
        // 每個路由應該對映一個元件。 其中"component" 可以是
        // 通過 Vue.extend() 建立的元件構造器,
        // 或者,只是一個元件配置物件。
        // 我們晚點再討論巢狀路由。
        const routes = [
            { path: '/foo', name: 'foo',component: Foo },
            { path: '/bar', name: 'bar',component: Bar },
            { path: '/car', name: 'car',component: Car }
        ]
        // 建立 router 例項,然後傳 `routes` 配置
        // 你還可以傳別的配置引數, 不過先這麼簡單著吧。
        const router = new VueRouter({
            routes // (縮寫) 相當於 routes: routes
        })
        // 建立和掛載根例項。
        // 記得要通過 router 配置引數注入路由,
        // 從而讓整個應用都有路由功能
        const app = new Vue({
            router
        }).$mount('#app')
        </script>
頁面效果如下:

 

  上面的程式碼中,通過router-link訪問路由例項,第一個標籤中to屬性值匹配路由表中path屬性,後面兩個通過name值去匹配路由表中的name屬性,並且分別傳遞了引數,注意觀察對應的位址列變化。

  (2)巢狀路由

    <body>
        <div id="app">
        <p>
            <router-link to="/foo">Go to Foo</router-link>
            <router-link to="/bar">Go to Bar</router-link>
        </p>
        <router-view></router-view>
        </div>
    </body>
     <script>
        const Foo = { template: '<div>foo</div>' }
        const Bar = {
            template: `<div>
                            <router-link to="/bar/car">to Car</router-link>
                            <router-link :to="{name:'dar',query:{dar:123}}">to Dar</router-link>
                            <router-view></router-view>
                        </div>` }
        const Car = { template: '<div>Car</div>' }
        const Dar = { template: '<div>Dar</div>' }
        const routes = [
            { path: '/foo', component: Foo },
            {
                path: '/bar', component: Bar,
                children: [
                    { path: 'car',name:"car", component: Car },// 這裡需要注意子路由path的用法,若前面加了"/" 表示該路由為根路徑,router-link中to 需要對應根路徑,不推薦在子路由前加"/"
                    { path: 'dar', name:"dar",component: Dar }
                ]
            }
        ]
        const router = new VueRouter({
            routes
        })
        const app = new Vue({
            router
        }).$mount('#app')
    </script>

  執行效果如下:

 

  上面的程式碼中在根路由中巢狀了子路由,同樣通過router-link的方式來訪問,也支援name屬性匹配路由表和傳遞值等操作,需要注意子路由推薦使用path屬性值不帶"/"

  3、通過  $router 的例項方法訪問路由例項

  通過注入路由器,我們可以在任何元件內通過 this.$router 訪問路由器,也可以通過 this.$route 訪問當前路由,在 Vue 例項內部,你可以通過 $router 訪問路由例項。因此你可以呼叫 this.$router物件完成。該方法等同於前面的宣告式訪問路由例項。

  this.$router.push()該方法的引數可以是一個字串路徑,或者一個描述地址的物件,該方法會向 history 棧新增一個新的記錄,所以,當使用者點選瀏覽器後退按鈕時,則回到之前的 URL。

    <body>
        <div id="app">
            <p>
                <button @click="handleFoo">to Foo </button>
                <button @click="handleBar">to Bar</button>
            </p>
            <router-view></router-view>
        </div>
    </body>
    <script>
        const Foo = { template: '<div>foo{{this.$route.params.foo}}</div>' }
        const Bar = { template: '<div>bar{{this.$route.query.bar}}</div>' }
        const routes = [
            { path: '/foo', name: 'foo',component: Foo },
            { path: '/bar', name: 'bar',component: Bar },
        ]
        const router = new VueRouter({
            routes 
        })
        const app = new Vue({
            router,
            methods:{
                handleFoo(){
                    this.$router.push({name:"foo",params:{foo:123}})
                },
                handleBar(){
                    this.$router.push({path:"/bar",query:{bar:234}})
                }
            }
        }).$mount('#app')
    </script>
  執行結果如下:

 

  但是在重複點選按鈕,路由重複時,控制檯出現報錯,如下:

  上面的報錯是因為push方法導致路由重複在當前路由,這裡需要在原型上修改push方法,程式碼如下:

    //獲取原型物件上的push函式
    const originalPush = VueRouter.prototype.push;
    //修改原型物件中的push方法
    VueRouter.prototype.push = function push(location) {
      return originalPush.call(this, location).catch((err) => err);
    };

  除了this.$router.push()之外還有別的訪問路由例項方法,如:this.$router.replace()不會向 history 新增新記錄,而是跟它的方法名一樣 —— 替換掉當前的 history 記錄。

this.$router.go(n) 在history 記錄中向前或者後退多少步,類似 window.history.go(n)。

  4、this.$router 和 this.$route 的區別及使用

  this.$router:是全域性路由器 router 的例項,可以在任何元件內進行訪問,路由例項裡面有很多屬性和方法,比如push方法。

  this.$route:是當前啟用的頁面的路由資訊物件,包含了當前 URL 解析得到的資訊,還有 URL 匹配到的路由記錄 (route records),也有一些屬性,這個屬性是隻讀的,裡面的屬性是 immutable (不可變) 的,不過你可以 watch (監測變化) 它。

        總之,可以在任何元件內通過 this.$router 訪問路由器,也可以通過 this.$route 訪問當前路由。

  5、動態路由

  某些情況下,一個頁面的path路徑可能是不確定的,比如我們進入使用者介面時,希望是如下的路徑: /user/aaaa或/user/bbbb。除了有前面的/user之外,後面還跟上了使用者的ID 這種path和Component的匹配關係,我們稱之為動態路由(也是路由傳遞資料的一種方式)。程式碼如下:

    <div id="app">
        <p>
            <router-link to="/foo">Go to Foo</router-link>
            <router-link to="/bar/123">Go to Bar</router-link>
        </p>
        <router-view></router-view>
    </div>
    <script>
        const routes = [
          { path: "/foo", component: Foo },
          { path: "/bar/:id", component: Bar },
        ];
        const router = new VueRouter({
          routes,
        });
        const app = new Vue({
          router,
        }).$mount("#app");
    </script>

  執行結果如下:

寫在最後

  以上就是本文的全部內容,希望給讀者帶來些許的幫助和進步,方便的話點個關注,小白的成長之路會持續更新一些工作中常見的問題和技術點。

 

 

相關文章