vue-06-路由

SPA 單頁(yè)面應(yīng)用開發(fā)(重點(diǎn))

SPA 的優(yōu)勢(shì):因?yàn)槭前秧?yè)面都合并到一起,所以路由切換時(shí),實(shí)際上是在當(dāng)前頁(yè)面切換顯示,所以不會(huì)因網(wǎng)絡(luò)問題造成頁(yè)面卡頓、白屏。

SPA 的不足:合并后的文件體積特別的大,所以第一次打開頁(yè)面時(shí),比較慢。(解決方法是用按需加載)

router 路由(重點(diǎn))

vue-router 配置基于 vue 的單頁(yè)面應(yīng)用(SPA)

// npm install vue-router -S    
import VueRouter from 'vue-router';

// 將vue-router注冊(cè)到全局,這樣每一個(gè)組件都可以使用router-link和router-view組件了
Vue.use(VueRouter);

// 定義路由規(guī)則
var routes = [
    { path: '/', component: ind },  
    { path: '/msg', component: msg },   
    { path: '/hi', component: hi }
]

// 創(chuàng)建路由實(shí)例
var router = new VueRouter({ routes, mode:'history' });

// 將路由實(shí)例注入到vue實(shí)例中
new Vue({
    el:"#app",
    router,
    render: h => h(App)
});
  • router-link 組件:渲染后為a標(biāo)簽,點(diǎn)擊這個(gè)標(biāo)簽后,瀏覽器地址欄會(huì)發(fā)生變化。
  • router-view 組件:瀏覽器地址欄每次發(fā)生變化時(shí),會(huì)根據(jù)路由規(guī)則,把匹配到的組件顯示到router-view標(biāo)簽上。
<template>
    <div>
        <router-link to="/">ind</router-link>
        <router-link to="/msg">msg</router-link>
        <router-link to="/hi">hi</router-link>

        <router-view></router-view>
    </div>
</template>

router-link組件識(shí)別路由后會(huì)自動(dòng)添加style樣式

.router-link-exact-active{
    color: green !important;
}

也可以自己定義樣式

<router-link to="/hi" active-class="xyz" exact-active-class="abc">hi</router-link>

通過tag屬性,可以將a標(biāo)簽解析成其他標(biāo)簽。

<router-link to="/hi" tag="li">hi</router-link>

路由模式:mode

  • history
  • hash(默認(rèn)值。哈希、網(wǎng)址含#)
  • abstract(抽象、網(wǎng)址不變)
var router = new VueRouter({ routes, mode:'history' });

用的較多的是history,每次頁(yè)面切換的時(shí)候,瀏覽器地址欄看起來就像是傳統(tǒng)的網(wǎng)站頁(yè)面一樣。

慎用 abstract,首次打開頁(yè)面時(shí) router-view 無法匹配 path='/',
所以可以在 app.vue 的 mounted 中執(zhí)行 this.$router.push('/')

動(dòng)態(tài)路由匹配

在瀏覽器中訪問一個(gè)網(wǎng)址時(shí),通常這個(gè)網(wǎng)址是有語(yǔ)義的,比如訪問:

http://www.abc.com/news/102/

  • news 表示新聞
  • 102 表示新聞id

那么怎么配置這種路由呢?

路由規(guī)則頁(yè)面

const routes = [
    {
        path : '/news/:id',
        component: {
            // 可以直接創(chuàng)建組件,使用render渲染,不能使用template渲染。
            render(createElement){
                return createElement('div', 'abc')
            },
            created(){
                // 在js中接收瀏覽器地址欄中id對(duì)應(yīng)的數(shù)據(jù)
                console.log(this.$route.params)
            }
        }
    }
]

某組件的html頁(yè)面,由這個(gè)頁(yè)跳轉(zhuǎn)到NewsComponent頁(yè)面

<router-link to="/news/102">點(diǎn)我跳轉(zhuǎn)頁(yè)面</router-link>

路由參數(shù)

路由中傳遞數(shù)據(jù)除了剛才的params外,還可以使用query數(shù)據(jù)。

路由規(guī)則頁(yè)面

const routes = [
    {
        path : '/news',
        component : NewsComponent
    }
]

某組件的html頁(yè)面,由這個(gè)頁(yè)跳轉(zhuǎn)到NewsComponent頁(yè)面

<router-link to="/news?id=102">點(diǎn)我跳轉(zhuǎn)頁(yè)面</router-link>

NewsComponent組件的js部分

// 在js中接收瀏覽器地址欄中id對(duì)應(yīng)的數(shù)據(jù)
this.$route.query.id

嵌套路由規(guī)則

移動(dòng)端項(xiàng)目不建議使用嵌套的路由規(guī)則,如果必須要用到嵌套路由,通常也不會(huì)超過2層。

比如項(xiàng)目中,一級(jí)導(dǎo)航有首頁(yè)和用戶,用戶頁(yè)面又有二級(jí)導(dǎo)航登錄、注冊(cè)兩個(gè)頁(yè)面。

路由規(guī)則

const routes = [
    {
        path: '/',
        component: IndexComponent
    },
    {
        path: '/user',
        component: UserComponent,
        children: [
            { path: '/user/register', component: RegisterComponent },
            { path: '/user/login', component: LoginComponent }
        ]
    }
]

children描述的是UserComponent組件內(nèi)的路由規(guī)則,當(dāng)根據(jù)路由規(guī)則匹配出對(duì)應(yīng)的組件后,這個(gè)組件在UserComponent組件內(nèi),找到router-view渲染。

UserComponent組件

點(diǎn)擊嵌套路由的鏈接時(shí),只會(huì)在嵌套路由組件出口顯示對(duì)應(yīng)的組件。

<router-link to="/user/register">注冊(cè)</router-link>
<router-link to="/user/login">登錄</router-link>
<router-view></router-view>

聲明式導(dǎo)航、編程式導(dǎo)航

  • 聲明式導(dǎo)航:html中的router-link標(biāo)簽實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)
  • 編程式導(dǎo)航:通過js代碼實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)

向history中添加記錄

<router-link to="/">
this.$router.push("/")
this.$router.push({ path: '/html2', query:{a:1,b:2}})

不會(huì)向history中添加新紀(jì)錄

<router-link to="/" replace>
this.$router.replace("/")

歷史記錄中前進(jìn)及后退

this.$router.go(1)

路由對(duì)象下有2個(gè)常用的屬性,一個(gè)是route,一個(gè)是router:

  • route 這里存儲(chǔ)的是屬性,比如route.query、$route.params
  • router 這里存儲(chǔ)的是方法,比如router.push()、router.replace()、router.go() 編程式導(dǎo)航方法都存到了這里

命名路由

給定義的路由規(guī)則起個(gè)名字,頁(yè)面跳轉(zhuǎn)時(shí),使用該名字完成路由跳轉(zhuǎn)。

路由規(guī)則

const routes = [
    {
        name: 'abc',
        path: '/html1/:a/:b',
        component: a
    }
]

頁(yè)面跳轉(zhuǎn)

<router-link :to="{name:'abc',params:{a:1,b:2}}">html1/1/2</router-link>
<router-view></router-view>

this.$router.push({ name: 'abc', params:{a:1,b:2}})

命名視圖

一個(gè)頁(yè)面中,有多個(gè)路由出口,每個(gè)router-view渲染哪個(gè)組件呢?

路由規(guī)則

const routes = [
    { path: '/a', components: {one:a, two:b} },
    { path: '/b', components: {one:c} }
]

html部分

<router-link to="/a">a</router-link>
<router-link to="/b">b</router-link> 

<router-view name="one"></router-view>
<router-view name="two"></router-view>

訪問a時(shí),one渲染a組件,two渲染b組件。訪問b時(shí),one渲染c組件,two不渲染組件,節(jié)點(diǎn)移除。

重定向

當(dāng)我們?cè)L問a時(shí),自動(dòng)跳轉(zhuǎn)到了b。

const routes = [
    { path: '/a', redirect: '/b' }
]

別名

當(dāng)我們?cè)L問c時(shí),url不變,但實(shí)際訪問的是a。

const routes = [
    { path: '/a', alias: '/c', component:a  }
]

守衛(wèi)

路由中的守衛(wèi)就是路由中的生命周期鉤子函數(shù)。

全局守衛(wèi)

只要發(fā)生頁(yè)面跳轉(zhuǎn),無論是什么頁(yè)面跳轉(zhuǎn),都會(huì)執(zhí)行該鉤子函數(shù)。

const router = new VueRouter({routes, mode:"history"})

router.beforeEach((to, from, next) => {
    // to 表示到哪里去
    // from 表示從哪里來
    console.log(to, from);
    // next 表示執(zhí)行跳轉(zhuǎn)
    next();
})

路由守衛(wèi)

在路由規(guī)則中,定義該鉤子函數(shù),表示渲染該組件之前執(zhí)行守衛(wèi)驗(yàn)證,如果有next則把組件渲染出來。

const routes = [
    {
        path: '/foo',
        component: Foo,
        beforeEnter: (to, from, next) => {
            console.log(to, from);
            next();
        }
    }
]

組件守衛(wèi)

在組件中定義該鉤子函數(shù)

{
    template: `...`,
    beforeRouteEnter (to, from, next) {
        // 不能獲取組件實(shí)例 this 因?yàn)楫?dāng)守衛(wèi)執(zhí)行前,組件實(shí)例還沒被創(chuàng)建
        // 組件被渲染之前
        console.log('beforeRouteEnter')
        next()
    }, 
    beforeRouteUpdate (to, from, next) {
        // 在當(dāng)前路由改變,但是該組件被復(fù)用時(shí)調(diào)用
        // 修改路由數(shù)據(jù)前
        console.log('beforeRouteUpdate')
        next()
    }, 
    beforeRouteLeave (to, from, next) {
        // 導(dǎo)航離開該組件的對(duì)應(yīng)路由時(shí)調(diào)用
        // 組件被移除前
        console.log('beforeRouteLeave')
        next()
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容