vue - vue-router

楚俊迈
2023-12-01

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

vue-router 是 Vue.js 官方的路由管理器。它和Vue.js深度集成,让构建单页面应用变得易如反掌。

1,这是一个简单的栗子

HTML:


<script src="http://unpkg.com/vue/dist/vue.js"></script>
<script src="http://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>
    <!-- 路由出口 -->
    <!-- 匹配到的组件会被渲染在这里 -->
    <router-view></router-view>
</div>

JavaScript:


// 如果使用模块化机制编程,导入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 访问当前路由。

2,动态路由匹配

当需要把某种模式匹配到的所有路由,全部映射到同一个组件上。例如,我们有一个User组件,对于ID各不相同的用户,都要使用这个组件来渲染,在路由路径中使用动态路由参数实现该效果

const User = {
    template: '<div>User</div>'
}

const router = new VueRouter({
    routes: [
        // 动态路由参数,以冒号开头
        { path: '/user/:id', component: User }
    ]
})

这时,像 /user/id1/user/id2都会映射到同一组件
使用 this.$route.params.id 获取 参数的值

:当路由参数发生变化时,例如从/user/id1跳转到/user/id2原来的组件实例会被复用,因为两个路由都渲染同个组件,比起销毁再创建,复用会显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用

解决方案

1,使用 watch (监听变化)$route 对象

const User = {
    template: '...',
    watch: {
        '$route' (to, from) {
            // 对路由变化做出相应
        }
    }
}

2,使用 2.2 中引入的 beforeRouteUpdate 守卫

const User = {
    template: '...',
    beforeRouteUpdate(to, from, next) {
        // react to route change ...
        // don't forget to call next()
    }
}

3,嵌套路由

父组件中需要 <router-view> 组件

父组件的路由对象中,需要有【children】属性,当子组件的path为空时,代表父组件匹配成功时, <router-view> 中需要渲染的组件。

先来个栗子

User组件

const User = {
    template: `
        <div id="user">
            <h2>{{ $route.params.id }}</h2>
            <router-view></router-view>
        </div>
    `
}

路由

const router = new VueRouter({
    routes: [
        { path: '/user/:id', component: User,
            children: [
                // 当/user/:id 匹配成功,
                // userHome 会被渲染在 User的 <router-view>中
                { path: '', component: UserHome },
                {
                    // 当 /user/:id/profile渲染成功,
                    // UserProfile 会被渲染再User的<router-view>中
                    path: 'profile',
                    component: 'UserProfile'
                },
                {
                    // 当 /user/:id/posts渲染成功,
                    // UserPosts 会被渲染再User的<router-view>中
                    path: 'posts',
                    component: 'UserPosts'
                }
            ] 
        }
    ]
})

4,编程式导航

(1)router.push 会向 history栈中添加一个新纪录,当用户点击浏览器后退按钮时,会回到之前的URL,类似于 window.history.pushState

  • 声明式:<router-link :to=""></router-link>
  • 编程式:router.push(…)

栗子:

const userId = 123
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 当 path 和 params同时存在时 params不生效
router.push({ path: '/user', params: { userId }}) // -> /user

(2)router.replace 不会向 history 栈中添加新记录,会替换掉当前的history 记录(用法同上),类似于window.history.replaceState

  • 声明式:<router-link :to='...' replace>
  • 编程式:router.replace(…)

(3)router.go(n)表示在history记录中,向前或者向后退多少步,类似window.history.go(n)

栗子

// 在浏览器中前进一步,等同于 history.forward()
router.go(1)

// 后退一步记录,等同于 history.back()
router.go(-1)

// 如果 history 记录不够用,那就默默地失败呗
router.go(100)
router.go(-100)

5,命名路由

来个栗子

const router = new VueRouter({
    routes: [
        path: '/user/:userId',
        name: 'user', // 对路由进行命名
        component: User
    ]
})

声明式路由跳转写法

<router-link :to="{ name: 'user', params: { userId: 123 } }"></router-link>

编程式路由跳转写法

router.push({ name: 'user', params: { userId: 123 } })

6,命名视图

当需要创建一个布局,有 sidebar(侧导航)和main(主内容)两个试图时,就可以使用命名试图

<router-view class='view one'></router-view>
<router-view class='view two' name='a'></router-view>
<router-view class='view three' name='b'></router-view>

使用 【components】(注意,这里多个s)配置【router-view】的name值和需要显示的组件绑定,如果没有name属性,默认使用【default】

const router = new VueRouter({
    routes: [
        {
            path: '/',
            components: {
                default: Foo,
                a: Bar,
                b: Baz
            }
        }
    ]
})
 类似资料: