1. 程式人生 > >Vue.js路由管理器 Vue Router

Vue.js路由管理器 Vue Router

起步

  • HTML

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<div id="app">
  <h1>Hello App!</h1>
  <p>
    <!-- 使用 router-link 元件來導航. -->
    <!-- 通過傳入 `to` 屬性指定連結. -->
    <!-- <router-link> 預設會被渲染成一個 `<a>` 標籤 -->
    <router-link to="/foo">Go to Foo</router-link>
    <router-link to="/bar">Go to Bar</router-link>
  </p>
  <!-- 路由出口 -->
  <!-- 路由匹配到的元件將渲染在這裡 n內建元件-->
  <router-view></router-view>
</div>
  • JavaScript

// 0. 如果使用模組化機制程式設計,匯入Vue和VueRouter,要呼叫 Vue.use(VueRouter)

// 1. 定義 (路由) 元件。
// 可以從其他檔案 import 進來
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

// 2. 定義路由
// 每個路由應該對映一個元件。 其中"component" 可以是
// 通過 Vue.extend() 建立的元件構造器,
// 或者,只是一個元件配置物件。
// 我們晚點再討論巢狀路由。
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]

// 3. 建立 router 例項,然後傳 `routes` 配置
// 你還可以傳別的配置引數, 不過先這麼簡單著吧。
const router = new VueRouter({
  routes // (縮寫) 相當於 routes: routes
})

// 4. 建立和掛載根例項。
// 記得要通過 router 配置引數注入路由,
// 從而讓整個應用都有路由功能
const app = new Vue({
  router
}).$mount('#app')

// 現在,應用已經啟動了!

通過注入路由器,我們可以在任何元件內通過 this.$router 訪問路由器,也可以通過 this.$route 訪問當前路由:


export default {
  computed: {
    username () {
      // 我們很快就會看到 `params` 是什麼
      return this.$route.params.username
    }
  },
  methods: {
    goBack () {
      window.history.length > 1
        ? this.$router.go(-1)
        : this.$router.push('/')
    }
  }
}

routes 選項 (Array)

redirect(重定向 )


//此時訪問/a會跳轉到/b
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' }
  ]
})
//重定向的目標也可以是一個命名的路由:
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: { name: 'foo' }}
  ]
})
//甚至是一個方法,動態返回重定向目標:
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: to => {
      // 方法接收 目標路由 作為引數
      // return 重定向的 字串路徑/路徑物件
    }}
  ]
})

命名路由


export default [
    {
        path:'/',
        redirect:'/app' //預設跳轉路由
    },
    {
        path: '/app',
        //路由命名,可用於跳轉
        name: 'app',
    }
]

//可用於跳轉
<router-link :to="{name:'app'}">app</router-link>

路由元資訊

定義路由的時候可以配置 meta 欄位:


export default [
    {
        path:'/',
        redirect:'/app' //預設跳轉路由
    },
    {
        path: '/app',
        //**相當於HTML的meta標籤**
        meta: {
            title: 'this is app',
            description: 'asdasd'
        },
    }
]

巢狀路由


export default [
    {
        path:'/',
        redirect:'/app' //預設跳轉路由
    },
    {
        path: '/app',
        //子路由 匹配 /app/test
         children: [
           {
             path: 'test',
             component: Login
           }
         ]
    }
]

路由元件傳參


export default [
    {
        path:'/',
        redirect:'/app' //預設跳轉路由
    },
    {
        path: '/app/:id', // /app/xxx ,元件內部可以通過$route.params.id拿到這個值
        // 會把:後面的引數通過props傳遞給元件Todozhong 中
        //布林模式
        props: true,
        //物件模式
        props:{id:456}
        //函式模式
        props: (route) => ({ id: route.query.b }),
        component: Todo,

    }
]

mode選項(string)

vue-router 預設 hash 模式 —— 使用 URL 的 hash 來模擬一個完整的 URL,於是當 URL 改變時,頁面不會重新載入。

如果不想要很醜的 hash,我們可以用路由的 history 模式,這種模式充分利用 history.pushState API 來完成 URL 跳轉而無須重新載入頁面。


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

這種模式要玩好,還需要後臺配置支援。

base(string)

應用的基路徑。例如,如果整個單頁應用服務在 /app/ 下,然後 base 就應該設為 "/app/"


return new Router({
    routes,
    mode: 'history',//預設使用hash#
    base: '/base/', //在path前面都會加上/base/,基路徑
  })

linkActiveClass(string)

預設值: "router-link-active"

全域性配置 <router-link> 的預設“啟用 class 類名”。


return new Router({
    routes,
    mode: 'history',//預設使用hash#
    base: '/base/', //在path前面都會加上/base/,基路徑
    // 點選calss名字
    linkActiveClass: 'active-link', //匹配到其中一個子集
    linkExactActiveClass: 'exact-active-link',//完全匹配
  })

linkExactActiveClass(string)

預設值: "router-link-exact-active"

全域性配置 <router-link> 精確啟用的預設的 class。

scrollBehavior(Function)

路由跳轉後是否滾動


export default () =&gt; {
  return new Router({
    routes,
    mode: 'history',//預設使用hash#
    base: '/base/', //在path前面都會加上/base/,基路徑
    //頁面跳轉是否需要滾動
    /*
        to:去向路由,完整路由物件
        from:來源路由
        savedPosition:儲存的滾動位置
    */
    scrollBehavior (to, from, savedPosition) {
      if (savedPosition) {
        return savedPosition
      } else {
        return { x: 0, y: 0 }
      }
    },
  })
}

parseQuery / stringifyQuery (Function)


/每次import都會建立一個router,避免每次都是同一個router
export default () =&gt; {
  return new Router({
    routes,
    mode: 'history',//預設使用hash#
    base: '/base/', //在path前面都會加上/base/,基路徑
    // 路由後面的引數?a=2&amp;b=3,string-&gt;object
     parseQuery (query) {

     },
      //object-&gt;string
    stringifyQuery (obj) {

     }
  })
}

fallback(boolean)

當瀏覽器不支援 history.pushState 控制路由是否應該回退到 hash 模式。預設值為 true。
如果設定為false,則跳轉後重新整理頁面,相當於多頁應用

<router-link>

過渡動效

<router-view> 是基本的動態元件,所以我們可以用 <transition> 元件給它新增一些過渡效果:


&lt;transition&gt;
  &lt;router-view&gt;&lt;/router-view&gt;
&lt;/transition&gt;

高階用法

命名檢視


&lt;router-view class="view one"&gt;&lt;/router-view&gt;
&lt;router-view class="view two" name="a"&gt;&lt;/router-view&gt;
&lt;router-view class="view three" name="b"&gt;&lt;/router-view&gt;

const router = new VueRouter({
  routes: [
    {
      path: '/',
      components: {
      //預設元件
        default: Foo,
        //命名元件
        a: Bar,
        b: Baz
      }
    }
  ]
})

導航守衛

  • 全域性守衛

import Vue from 'vue'
import VueRouter from 'vue-router'

import App from './app.vue'

import './assets/styles/global.styl'
// const root = document.createElement('div')
// document.body.appendChild(root)
import createRouter from './config/router'
Vue.use(VueRouter)

const router = createRouter()

// 全域性導航守衛(鉤子)

// 驗證一些使用者是否登入
router.beforeEach((to, from, next) =&gt; {
    console.log('before each invoked')
    next()
//   if (to.fullPath === '/app') {
//     next({ path: '/login' })
//     console.log('to.fullPath :'+to.fullPath )

//   } else {
//     next()
//   }
})

router.beforeResolve((to, from, next) =&gt; {
    console.log('before resolve invoked')
    next()
})

// 每次跳轉後觸發
router.afterEach((to, from) =&gt; {
    console.log('after each invoked')
})

new Vue({
    router,
    render: (h) =&gt; h(App)
}).$mount("#root")
  • 路由獨享的守衛

可以在路由配置上直接定義 beforeEnter 守衛:


export default [
    {
        path:'/',
        redirect:'/app' //預設跳轉路由
    },
    {
  
        path: '/app',
        // 路由獨享的守衛鉤子
        beforeEnter(to, from, next) {
            console.log('app route before enter')
            next()
        }
        component: Todo,
    }
]
  • 元件內的守衛

export default {
  //進來之前
  beforeRouteEnter(to, from, next) {
    // 不!能!獲取元件例項 `this`
    // 因為當守衛執行前,元件例項還沒被建立
    console.log("todo before enter", this); //todo before enter undefined
    //可以通過傳一個回撥給 next來訪問元件例項。在導航被確認的時候執行回撥,並且把元件例項作為回撥方法的引數。
    next(vm =&gt; {
        // 通過 `vm` 訪問元件例項
      console.log("after enter vm.id is ", vm.id);
    });
  },
  //更新的時候
  beforeRouteUpdate(to, from, next) {
    console.log("todo update enter");
    next();
  },
  // 路由離開
  beforeRouteLeave(to, from, next) {
    console.log("todo leave enter");
    const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
      if (answer) {
        next()
      } else {
        //以通過 next(false) 來取消。
        next(false)
      }
  },
  props:['id'],
  components: {
    Item,
    Tabs
  },
  mounted() {
    console.log(this.id)
  },
};

路由懶載入

參考:路由懶載入

來源:https://segmentfault.com/a/1190000015976735