【vuejs路由】vuejs 路由基礎入門實戰操做詳細指南

官方文檔:

https://router.vuejs.org/zh-cn/css

用 Vue.js + vue-router 建立單頁應用,是很是簡單的。使用 Vue.js ,咱們已經能夠經過組合組件來組成應用程序,當你要把 vue-router 添加進來,咱們須要作的是,將組件(components)映射到路由(routes),而後告訴 vue-router 在哪裏渲染它們。vue

hash 和 history模式

默認hash模式:

以#/開始匹配,這種叫做哈希模式(hash)vue-router

HTML5 History 模式:

/開始,就是咱們常見的方式沒有 # 符號數組

<a href="/">首頁</a>
    <a href="/work">工做</a>
咱們此時使用a標籤來切換比較麻煩,每次更改路由模式的時候,須要單獨改a標籤裏面herf的連接

在vue裏面提供了一個更好的方式,來解決這個問題app

<router-link to="/">home主頁</router-link>
    <router-link to="/work">個人工做</router-link>

<router-view/>

每次切換路由的時候,裏面的內容都依靠<router-view/> 來顯示在頁面上

只有頁面有導航的地方,打算讓組件顯示在頁面上,必須寫<router-view/>這個標籤dom

<template>
  <div id="app">
    <router-link to="/">home主頁</router-link>
    <router-link to="/work">個人工做</router-link>
    <router-view/> 這個標籤用來顯示頁面內容
  </div>
</template>

router-link 默認解析成a標籤

<a href="#/" class="router-link-active">home主頁</a>
<a href="#/work" class="router-link-exact-active router-link-active">個人工做</a>

給導航添加激活樣式

經過css裏面設置函數

.router-link-active{
    background-color:red
}
當咱們單獨設置激活樣式的時候,根路由 / 永遠都會匹配到樣式

咱們能夠在標籤中添加 exact 方式來解決永遠都會匹配到跟路徑樣式問題

直接加在標籤屬性上
    <router-link exact to="/">home主頁</router-link>

咱們本身來給導航添加自定義class名字

經過 設置 active-class屬性值 改變默認的激活樣式類
<router-link to="/work" active-class="starkwang">個人工做</router-link>

統一更改激活樣式

在 router/index.js裏面設置 linkExactActiveClass屬性post

export default new Router({
    // mode: 'history',
    mode: 'hash',
    linkExactActiveClass: 'shudong', //經過設置這個屬性值,給全部的激活樣式,添加統一的類


當咱們統一設置後,每次激活的路由標籤,都帶着本身設置的這個shudong類
<a href="#/work" class="shudong starkwang">個人工做</a>

使用屬性 tag 統一更改路由編譯後的標籤名字 -> <li> </li>

默認編譯的標籤名字是 a
<router-link to="/stark" tag="li">個人Stark</router-link>

更改完後的dom
<li class="shudong router-link-active">個人Stark</li>

路由嵌套 chidren

使用方式this

{
            path: '/about',  // 這是一級路由
            component: About,
            children: [{  // 裏面是嵌套路由
                    path: 'blog',  //若是在這個嵌套
                    name: 'blog',
                    component: Blog
                },
                {
                    path: '/info',
                    name: 'info',
                    component: Info
                }
            ]
        }

若是在這個嵌套裏面的path:'' 留空,默認會顯示這個組件

http://localhost:8080/#/about
此時會把 這個默認留空的嵌套路由組件顯示出來,也就是上面的blog 組件顯示出來

若是嵌套路由裏面的path:'blog' 寫具體的路由,則訪問的時候必須匹配

必須是這個路由精準匹配

http://localhost:8080/#/about/blog

這樣纔會把這個blog嵌套路由組件顯示出來

以 / 開頭的嵌套路徑會被看成根路徑。

這讓你充分的使用嵌套組件而無須設置嵌套的路徑。code

{
            path: '/about',  // 這是一級路由
            component: About,
            children: [{  // 裏面是嵌套路由
                    path: 'blog',  //若是在這個嵌套
                    name: 'blog',
                    component: Blog
                },
                {
                    path: '/info', // 以 / 開頭的嵌套路徑會被看成跟路徑
                    name: 'info',
                    component: Info
                }
            ]
        }

    訪問方式:
    http://localhost:8080/#/info

若是去掉/ 此時去掉了 '/info' -> 'info'

{
            path: '/about',  // 這是一級路由
            component: About,
            children: [{  // 裏面是嵌套路由
                    path: 'blog',  //若是在這個嵌套
                    name: 'blog',
                    component: Blog
                },
                {
                    path: 'info', // 此時去掉了 '/info'  -> 'info'
                    name: 'info',
                    component: Info
                }
            ]
        }

      訪問方式:
    http://localhost:8080/#/about/info
你會發現,children 配置就是像 routes 配置同樣的路由配置數組,因此呢,你能夠嵌套多層路由。

此時,基於上面的配置,當你訪問 /about/info 時,about 的出口是不會渲染任何東西,這是由於沒有匹配到合適的子路由。

重定向

使用方式 path:'*'

這個 * 是匹配上面沒有找到的路徑,會到這裏
能夠直接寫:component: NotFound,

redirect 這是一個函數,裏面有參數 to
to 打印出來是一個對象
{name: undefined, meta: {…}, path: "/aaa", hash: "", query: {…}, …}

經過 to.path 能夠獲取當前用戶訪問的路徑,來寫一些邏輯跳轉下面是使用詳細方式

{
    path: '*',
    // component: NotFound,
    redirect: (to) => {
        console.log(to);
        if (to.path === '/aaa') {
            return '/work'
        } else if (to.path === '/bbb') {
            return '/info'
        } else {
            return '/'
        }
    }
}

最後附上全部路由文件代碼

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Work from '@/components/Work'
import Stark from '@/components/Stark'

Vue.use(Router)
const UserProfile = { template: `<div> 我是profile 組件 </div>` };
const UserPosts = { template: `<div> 我是UserPosts 組件 </div>` };
const Blog = { template: `<div> 我是Blog 組件 </div>` };
const Info = { template: `<div> 我是Info 組件 </div>` };
const NotFound = { template: `<div>404 您訪問的頁面不存在 </div>` };
const About = { template: `<div> 我是About組件 <router-view> </router-view> </div>` };
const User = {
    // template: '<div>User {{ $route.params.id }}</div>'
    template: ' <div class="user"> \
            <h2> User {{ $route.params.id } } </h2> \
            <router-view> </router-view> \
            </div>'
}

export default new Router({
    // mode: 'history',
    mode: 'hash',
    linkExactActiveClass: 'shudong',
    routes: [{
            path: '/',
            name: 'Hello',
            component: HelloWorld
        },
        {
            path: '/work',
            name: 'Work',
            component: Work
        },
        {
            path: '/stark',
            name: 'stark',
            component: Stark
        },
        // { path: '/user/:id', component: User }
        {
            path: '/user/:id',
            component: User,
            children: [{
                    // 當 /user/:id/profile 匹配成功,
                    // UserProfile 會被渲染在 User 的 <router-view> 中
                    path: 'profile',
                    component: UserProfile
                },
                {
                    // 當 /user/:id/posts 匹配成功
                    // UserPosts 會被渲染在 User 的 <router-view> 中
                    path: 'posts',
                    component: UserPosts
                }
            ]
        },
        {
            path: '/about',
            component: About,
            children: [{
                    path: 'blog',
                    name: 'blog',
                    component: Blog
                },
                {
                    path: '/info',
                    name: 'info',
                    component: Info
                }
            ]
        },
        {
            path: '*',
            // component: NotFound,
            redirect: (to) => {
                console.log(to);
                if (to.path === '/aaa') {
                    return '/work'
                } else if (to.path === '/bbb') {
                    return '/info'
                } else {
                    return '/'
                }
            }
        }
    ]
})

路由傳參

傳一個參數

在路由裏面的path:'/user/:stark'   這個冒號後面跟的字符串至關於 key 
在組件裏面使用 this.$route.params.stark 來獲取這個value的值
訪問方式:

http://localhost:8080/#/user/wang

wang 就是console.log(this.$route.params.stark) 值

在後面跟 ?號
能夠 寫wang 或不寫 後面的參數
若是不跟?號 ,必須寫這個參數

若是想傳多個參數

在路由裏面添加多個key
path: '/user/:stark?/:name?

訪問方式
http://localhost:8080/#/user/wang/stark

打印結果 console.log(this.$route.params)
{stark: "wang", name: "shudong"}
{
    path: '/user/:stark?/:name?',
    name: 'user',
    component: User
},

案例:

user 組件

<template>
    <div>
        <router-link :to="'/user/' + item.id" v-for="item in userList">{{item.username}} </router-link>
        <div>
                <p> 姓名:{{userInfo.username}}</p>
                <p> 愛好:{{userInfo.hobby}}</p>
                <p> 性別:{{userInfo.sex}}</p>
        </div>
    </div>
</template> 

<script>
    let data = [
        {
            id:1,
            tip:'vip',
            username:'luchang',
            sex:'男',
            hobby:'coding'
        },
        {
            id:2,
            tip:'vip',
            username:'guomian',
            sex:'男',
            hobby:'女'
        },
        {
            id:3,
            tip:'common',
            username:'zhangming',
            sex:'男',
            hobby:'bug'
        },
    ]
    export default{
        data(){
            return{
                userList:data,
                userInfo:''
            }
        },
        watch:{
            $route(){
                this.getData();
            }
        },
        created(){
            this.getData();
        },
        methods:{
            getData(){
                // let id = this.$route;
                console.log(this.$route);
                let id = this.$route.params.userId;
                if(id){
                    this.userInfo = this.userList.filter((item)=>{
                        return item.id == id;
                    })[0]
                }
                console.log(this.userInfo);
                // console.log(this.$route.params.stark);
            }
        }
    }
</script>

路由

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Work from '@/components/Work'
import Stark from '@/components/Stark'
import User from '@/components/User'

Vue.use(Router)
const UserProfile = { template: `<div> 我是profile 組件 </div>` };
const UserPosts = { template: `<div> 我是UserPosts 組件 </div>` };
const Blog = { template: `<div> 我是Blog 組件 </div>` };
const Info = { template: `<div> 我是Info 組件 </div>` };
const NotFound = { template: `<div>404 您訪問的頁面不存在 </div>` };
const About = { template: `<div> 我是About組件 <router-view> </router-view> </div>` };
const Users = {
    // template: '<div>User {{ $route.params.id }}</div>'
    template: ' <div class="user"> \
            <h2> User {{ $route.params.id } } </h2> \
            <router-view> </router-view> \
            </div>'
}

export default new Router({
    // mode: 'history',
    mode: 'hash',
    linkExactActiveClass: 'shudong',
    routes: [{
            path: '/',
            name: 'Hello',
            component: HelloWorld
        },
        {
            path: '/work',
            name: 'Work',
            component: Work
        },
        {
            path: '/user/:userId?/:name?',
            name: 'user',
            component: User
        },
        {
            path: '/stark',
            name: 'stark',
            component: Stark
        },
        // { path: '/user/:id', component: User }
        {
            path: '/users/:id',
            component: Users,
            children: [{
                    // 當 /user/:id/profile 匹配成功,
                    // UserProfile 會被渲染在 User 的 <router-view> 中
                    path: 'profile',
                    component: UserProfile
                },
                {
                    // 當 /user/:id/posts 匹配成功
                    // UserPosts 會被渲染在 User 的 <router-view> 中
                    path: 'posts',
                    component: UserPosts
                }
            ]
        },
        {
            path: '/about',
            component: About,
            children: [{
                    path: 'blog',
                    name: 'blog',
                    component: Blog
                },
                {
                    path: '/info',
                    name: 'info',
                    component: Info
                }
            ]
        },
        {
            path: '*',
            // component: NotFound,
            redirect: (to) => {
                // console.log(to);
                if (to.path === '/aaa') {
                    return '/work'
                } else if (to.path === '/bbb') {
                    return '/info'
                } else {
                    return '/'
                }
            }
        }
    ]
})
相關文章
相關標籤/搜索