路由的基本概念

image-20201102135258470

image-20201102135508671

VueRouter基本使用

官方地址:https://router.vuejs.org/zh/

  1. 引入相关库文件

    VueRouter依赖于vue,因此需要先引入vue

    <script src="../js/vue.js"></script>
    <script src="../js/vue-router_3.0.2.js"></script>
  2. 添加路由链接

    <router-link to='/user'>user</router-link>
    <router-link to='/register'>register</router-link>

    router-link标签会被渲染成a标签,to属性则会被渲染成href属性。

  3. 添加路由填充位

    <router-view></router-view>
  4. 定义路由组件

    const User = {
        template: '<div>User组件</div>'
    }
    const Register = {
        template: '<div>Register组件</div>'
    }
  5. 配置路由规则并创建路由实例

    // 创建路由实例对象
    const router = new VueRouter({
        // 所有路由规则
        routes: [
            { path: '/user', component: User },
            { path: '/register', component: Register },
        ]
    })
  6. 把路由挂载到Vue根实例中

    let app = new Vue({
        el: '#app',
        router: router
    })

完整版的案例:

87110fcb-76ee-48b3-9546-badfde499d9d

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">

        <router-link to='/user'>user</router-link>
        <router-link to='/register'>register</router-link>

        <!-- 路由占位符 -->
        <router-view></router-view>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue-router@3.4.8/dist/vue-router.js"></script>
    <script>
        const User = {
            template: '<div>User组件</div>'
        }
        const Register = {
            template: '<div>Register组件</div>'
        }
        // 创建路由实例对象
        const router = new VueRouter({
            // 所有路由规则
            routes: [
                { path: '/user', component: User },
                { path: '/register', component: Register },
            ]
        })

        let app = new Vue({
            el: '#app',
            router: router
        })
    </script>
</body>

</html>

重定向

路由规则存在redirect属性,可以实现重定向。

const router = new VueRouter({
    // 所有路由规则
    routes: [
        { path: '/', redirect: '/user' },
        { path: '/user', component: User },
        { path: '/register', component: Register },
    ]
})

嵌套路由

  1. 创建父级路由链接和父级路由填充位

  2. 子路由链接和子路由填充位

    const Register = {
        template: `
    <div>
    <h1>Register组件</h1>    
    <!-- 子路由链接 -->
    <router-link to='/register/tab1'>tab1</router-link>
    <router-link to='/register/tab2'>tab2</router-link>
    
    <!-- 子路由占位符 -->
    <router-view></router-view>
    </div>
    `
    }

    子路由的链接及占位符需要定义在父路由的模板中。

  3. 父级路由通过children属性配置子集路由

    const Tab1 = {
        template: '<h3>Tab1子组件</h3>'
    }
    const Tab2 = {
        template: '<h3>Tab2子组件</h3>'
    }
    // 创建路由实例对象
    const router = new VueRouter({
        // 所有路由规则
        routes: [
            { path: '/', redirect: '/user' },
            { path: '/user', component: User },
    
            {
                path: '/register', component: Register, children: [
                    { path: '/register/tab1', component: Tab1 },
                    { path: '/register/tab2', component: Tab2 },
                ]
            },
        ]
    })

    children属性表示子路由,是一个数组,使用方式与routers属性类似。

image-20201102143540342

路由传递参数

基本用法

动态路由规则使用:开头。在组件中通过$route.params获取。

<router-link to='/user/1'>user</router-link>
<router-link to='/user/2'>user</router-link>
<router-link to='/user/3'>user</router-link>
const User = {
    template: '<div>User{{$route.params.id}}组件</div>'
}
const router = new VueRouter({
    routes: [
        { path: '/user/:id', component: User },
    ]
})

组件传参

props为布尔值

  1. 开启props传参

    const router = new VueRouter({
        // 所有路由规则
        routes: [
            { path: '/user/:id', component: User, props: true },
        ]
    })

    props的值是一个布尔类型的值。

  2. 接受属性

    const User = {
        props: ['id'],
        template: '<div>User{{id}}组件</div>'
    }

props为对象

传递对象时会导致无法匹配路由时所传递的参数。

  1. 开启props传参

    const router = new VueRouter({
        // 所有路由规则
        routes: [
            { path: '/user/:id', component: User, props: { name: '张三' } },
        ]
    })
  2. 接受属性

    const User = {
        props: ['name'],
        template: '<div>User{{name}}组件</div>'
    }

函数类型

函数类型可以获取路由中传递的值,也可以返回自定义的值。

传递对象时会导致无法匹配路由时所传递的参数。

  1. 开启props传参

    const router = new VueRouter({
        // 所有路由规则
        routes: [
            {
                path: '/user/:id', component: User, props: router => ({
                    name: '张三',
                    id: router.params.id
                })
            },
        ]
    })
  2. 接受属性

    const User = {
        props: ['id', 'name'],
        template: '<div>User{{name}}组件{{id}}</div>'
    }

9341765a-51ae-48bc-8159-3b2427a3d778

命名路由

即对路由起一个别名,当使用router-link的to属性时绑定一个对象,通过name属性表示跳转的路由,params表示携带的参数。

const router = new VueRouter({
    // 所有路由规则
    routes: [
        {
            name: 'user',
            path: '/user/:id', component: User, props: router => ({
                name: '张三',
                id: router.params.id
            })
        },
    ]
})
<router-link :to='{name:"user",params:{id:"3"}}'>user</router-link>

image-20201102145723058

编程式导航

  1. 通过this.$router.push指定跳转的路由

    const User = {
        props: ['id', 'name'],
        template: `
    <div>User{{name}}组件{{id}}
    <button @click='goPush'>跳转</button>
    </div>
    `,
        methods: {
            goPush: function () {
                this.$router.push('/register')
            }
        },
    }

    push可以传递参数的类型:

    // 字符串(路径名称)
    this.$router.push('/register')
    // 对象
    this.$router.push({ path: '/register' })
    // 命名的路由(传递参数)
    this.$router.push({ name: '/user', params: { userId: 123 } })
    // 带查询参数,变成/register?uname=lisi
    this.router.push({ path: '/register', query: { uname: 'lissi' } })
  2. 通过this.$router.go指定回退或前进的步数

    const Register = {
        template: `
    <div>Register组件
    <button @click='go'>跳转</button>
    </div>
    `,
        methods: {
            go: function () {
                // 正数表示前进的步数,负数表示后退的步数
                this.$router.go(-1)
            }
        },
    }

携带参数

  1. 如果使用name那么使用params

    this.$router.push({
        name: '/goods/edit',
        params: { a: 1 }
    })
  2. 如果使用path那么使用query

    this.$router.push({
        path: '/goods/edit',
        query: { a: 1 }
    })

案例:后台管理路由

地址:Demo

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <title>基于vue-router的案例</title>
        <style type="text/css">
            html,
            body,
            #app {
                margin: 0;
                padding: 0px;
                height: 100%;
            }

            .header {
                height: 50px;
                background-color: #545c64;
                line-height: 50px;
                text-align: center;
                font-size: 24px;
                color: #fff;
            }

            .footer {
                height: 40px;
                line-height: 40px;
                background-color: #888;
                position: absolute;
                bottom: 0;
                width: 100%;
                text-align: center;
                color: #fff;
            }

            .main {
                display: flex;
                position: absolute;
                top: 50px;
                bottom: 40px;
                width: 100%;
            }

            .content {
                flex: 1;
                text-align: center;
                height: 100%;
            }

            .left {
                flex: 0 0 20%;
                background-color: #545c64;
            }

            .left a {
                color: white;
                text-decoration: none;
            }

            .right {
                margin: 5px;
            }

            .btns {
                width: 100%;
                height: 35px;
                line-height: 35px;
                background-color: #f5f5f5;
                text-align: left;
                padding-left: 10px;
                box-sizing: border-box;
            }

            button {
                height: 30px;
                background-color: #ecf5ff;
                border: 1px solid lightskyblue;
                font-size: 12px;
                padding: 0 20px;
            }

            .main-content {
                margin-top: 10px;
            }

            ul {
                margin: 0;
                padding: 0;
                list-style: none;
            }

            ul li {
                height: 45px;
                line-height: 45px;
                background-color: #a0a0a0;
                color: #fff;
                cursor: pointer;
                border-bottom: 1px solid #fff;
            }

            table {
                width: 100%;
                border-collapse: collapse;
            }

            td,
            th {
                border: 1px solid #eee;
                line-height: 35px;
                font-size: 12px;
            }

            th {
                background-color: #ddd;
            }
        </style>
        <script src="../js/vue.js"></script>
        <script src="../js/vue-router_3.0.2.js"></script>
    </head>

    <body>
        <div id="app">
            <router-view></router-view>
        </div>

        <script>
            const app = {
                template: `
<div>
<!-- 头部区域 -->
<header class="header">传智后台管理系统</header>
<!-- 中间主体区域 -->
<div class="main">
<!-- 左侧菜单栏 -->
<div class="content left">
<ul>
<li><router-link to='/users'>用户管理</router-link></li>
<li><router-link to='/rights'>权限管理</router-link></li>
<li><router-link to='/goods'>商品管理</router-link></li>
<li><router-link to='/orders'>订单管理</router-link></li>
<li><router-link to='/settings'>系统设置</router-link></li>
            </ul>
            </div>
<!-- 右侧内容区域 -->
<div class="content right">
<router-view />
            </div>
            </div>
<!-- 尾部区域 -->
<footer class="footer">版权信息</footer>
            </div>
`}

            const Users = {
                data: function () {
                    return {
                        userList: [
                            { id: 1, name: '张三', age: 10 },
                            { id: 2, name: '李四', age: 11 },
                            { id: 3, name: '王五', age: 12 },
                            { id: 4, name: '赵六', age: 13 },
                        ]
                    }
                },
                methods: {
                    goDetail: function (id) {
                        this.$router.push('/userinfo/' + id)
                    }
                },
                template: `
<div>
<h3>用户管理区域</h3>
<table>
<thead>
<tr><th>编号</th><th>姓名</th><th>年龄</th><th>操作</th></tr>
            </thead>
<tbody>
<tr v-for='item in userList' :key='item.id'>
<th>{{item.id}}</th>
<th>{{item.name}}</th>
<th>{{item.age}}</th>
<th><a @click='goDetail(item.id)' href='javascript:;'>操作</a></th>
            </tr>
            </tbody>
            </table></div>
`
            }
            const UserInfo = {
                props: ['id'],
                template: `<div>
<h5>用户详情页-{{id}}</h5>
<button @click="goback()">回退</button>
            </div>`,
                methods: {
                    goback: function () {
                        this.$router.go(-1)
                    }
                },
            }
            const Rights = {
                template: `
<h3>权限管理区域</h3>
`
            }
            const Goods = {
                template: `
<h3>商品管理区域</h3>
`
            }
            const Orders = {
                template: `
<h3>订单管理区域</h3>
`
            }
            const Settings = {
                template: `
<h3>系统设置区域</h3>
`
            }
            // 创建路由对象
            const router = new VueRouter({
                routes: [
                    {
                        path: '/',
                        component: app,
                        redirect: '/users',
                        children: [
                            { path: '/users', component: Users },
                            { path: '/userinfo/:id', component: UserInfo, props: true },
                            { path: '/rights', component: Rights },
                            { path: '/goods', component: Goods },
                            { path: '/orders', component: Orders },
                            { path: '/settings', component: Settings },
                        ]
                    },
                ]
            })
            let vm = new Vue({
                el: '#app',
                router
            })
        </script>
    </body>

</html>