vue系列教程-11vuerouter路由

本内容为系列内容,全部内容请看我的vue教程分类

  • 我的个人博客
  • 本节仓库地址
  • 视频教程地址

什么是路由

大家还记得我最开始提到的spa单页面吗,通过不同的路径显示不同的组件,这个就是通过router实现的

那么首先我们还需要引入一个 router文件


这里的话我们还是以上面的bilibili消息中心为示例,使用到刚刚的代码

还是先定义组件模板




然后定义组件

const writeback = {
    template: '#writeback'
}
const aite = {
    template: '#aite'
}
const zan = {
    template: '#zan'
}

基础使用

在组件那一节我们是通过动态组件来实现界面切换的,这里我们就使用路由来实现页面切换

这里我们实例化vue的时候,属性里面的 router传入一个 VueRouter 的实例,这个数组routes就是详细的路径和对应的组件信息,比如我们浏览器访问 www.lookroot.cn/writeback的时候,页面就展示上面定义好的 writeback组件

let vm = new Vue({
    el: '#app',
    data() {
    },
    router: new VueRouter({
        routes: [
            {
                path: '/writeback',
                component: writeback
            },
            {
                path: '/aite',
                component: aite
            },
            {
                path: '/zan',
                component: zan
            },
        ],
    })
})

那么原本的导航也要进行修改 这个 router-link就会在页面中渲染成a标签,作为导航

  • 回复我的
  • @我的
  • 收到赞的

那么我们原本的选中效果是没有了的因为没有绑定点击事件,但是路由会给默认激活的导航加上一个class名为router-link-active ,我们简单编写一下

 /* 当前显示路由的颜色 */
 .bili-content .bili-leftnav li .router-link-active {
     color: #2fbbea;
 }

然后和动态组件一样要有个展示的容器吧,这里我们也给它加上过渡动画,这个router-view就是路由界面的展示容器和动态组件的component是一样的

好的这就完成了改造了看看效果吧完全是可以的,注意看路径的变化

vue系列教程-11vuerouter路由_第1张图片

路由重定向

如果我们打开这个界面的时候,路径后面没有跟着具体的路径,界面就不会显示任何的组件,这肯定是不友好的

必须设置一个默认界面,我们咋路由配置文件里面增加一个路由信息

{
    path: '/',
    redirect: '/writeback',
},

这里的意思就是,默认为初始界面的时候,就重定向到 writeback这个路径,这样writeback就成了默认界面了

命名视图和命名路由

命名视图

如果我们页面中同时有两个 的时候,点开页面要展示两个组件,那么你怎么知道哪个组件应该展示到哪个 view里面呢?这就是命名视图

我们在添加一个 view,并且namecommon

定义一个组件模板


定义这个组件

const vuefooter = {
    template: '#vuefooter'
}

然后修改一下 writeback的路由配置,component就换成components了,并且默认的容器展示writeback组件,命名为common的容器展示 刚刚定义的这个vuefooter组件

{
    path: '/writeback',//点击的路径
    // 命名视图
    components: {
        default: writeback,
        common: vuefooter
    },
},

看看效果,是可以的,这就是命名视图

vue系列教程-11vuerouter路由_第2张图片

命名路由

我们给路由也起名字,这样方便使用,这里还是以 writeback为例

{
    path: '/writeback',//点击的路径
    // 命名视图
    components: {
        default: writeback,
        common: vuefooter
    },
    // 命名路由
    name: 'writeback',
},

修改它的导航链接,这样就完成了

回复我的

嵌套路由和路由传参

这个嵌套大家就知道了,肯定是路由中有路由,就像组件中有组件一样,又是套娃行为

来看下这个界面,1部分是导航,2部分是路由展示的组件同时相对于3部分又是一个导航,3部分是路由展示的组件,这就是一个很明显的路由嵌套,我们就来实现一下

vue系列教程-11vuerouter路由_第3张图片

首先我们要添加这个我的消息这个导航链接

 
  • 回复我的
  • @我的
  • 收到赞的
  • 我的消息

然后定义第二部分和第三部分的组件

这个第二部分的组件模板,它里面首先是一个导航,这个导航我循环渲染出来的,模拟了十个用户聊天导航,并且是使用了 :to也就是绑定动态的路径,路径后面跟上了 index也就是把当前是第几个用户传递给第三部分这就是路由传参params方式

路由传参params方式


定义第三部分组件模板


定义这两个组件,为什么要使用 props来接受传值那?下面解释

//第二部分组件
const mymsg = {
    template: '#mymsg',
}
//第三部分组件
const msgcontent = {
    template: '#msgcontent',
    props: ['index'],
}

嵌套路由

然后定义这个嵌套路由,这个 mymsg就是第二部分的路由配置,然后给它配置一个children这里面就是嵌套的路由配置了,首先path后面的 :id就是匹配我们上面定义的router-link传参的index,这个props: true就是将我们传递的index值,自动注册为第三部分组件的 props

// 嵌套路由
{
    path: '/mymsg',
    component: mymsg,
    children: [{
        path: 'msgcontent/:index',
        component: msgcontent,
        props: true
    }]
}

看下效果,这就完成了

vue系列教程-11vuerouter路由_第4张图片

路由传参query方式

我们回到前面的第一部分的导航,修改一下这个我得消息的导航,使用?连接传递值

我的消息

如果我们不适用上面的props来接受传值该怎么做呢?

修改一下组件定义,created周期时使用this.$route.query来接受query方式的传值,赋值给username

const mymsg = {
    template: '#mymsg',
    data() {
        return {
            username: ''
        }
    },
    created() {
        // query传值
        this.username = this.$route.query.username
    },
}

然后在组件模板中渲染这个数据


看下效果是可以的

vue系列教程-11vuerouter路由_第5张图片

@

目录
  • 什么是路由
  • 基础使用
  • 路由重定向
  • 命名视图和命名路由
    • 命名视图
    • 命名路由
  • 嵌套路由和路由传参
    • 路由传参params方式
    • 嵌套路由
    • 路由传参query方式
  • 路由模式
  • 编程式的导航
  • 全局路由守卫
  • 路由元信息
  • 组件内的路由守卫

路由模式

路由有两种模式historyhash模式,默认也就是我们前面使用的模式是hash模式

这种模式就是在后面跟着一长串,不是很好看,如果追求美观就可以使用history模式

来实例一下

定义两个组件模板



定义这两个组件

const page1 = {
    template: '#page1',
}
const page2 = {
    template: '#page2',
}

实例化一个router,指定modehistory模式

 const router = new VueRouter({
     mode: 'history',
     routes: [
         {
             path: '/',
             redirect: '/page1',
         },
         {
             path: '/page1',
             component: page1,
             name: 'page1',
         },
         {
             path: '/page2',
             component: page2,
             name: 'page2',
         },
     ],
 });

在页面中定义导航,这里我们介绍另外一种路由跳转的方式编程式的导航

那么这里都绑定上一个点击事件,然后传递一个地址字符串

编程式的导航

在当前组件(父组件)中编写一下这个点击事件,使用this.$router.push进行路由跳转

methods: {
    gotoPage(path) {
        // 编程式的导航 
        this.$router.push(path)
    }
},

运行一下查看效果,看下导航栏地址是不是就美观多了啊

vue系列教程-11vuerouter路由_第6张图片

但是这个模式有问题的,比如我们直接在浏览器中打开这个链接是会报错的

vue系列教程-11vuerouter路由_第7张图片

解决这个问题的方法需要后端处理官网文档

全局路由守卫

顾明思议,守卫嘛,就是拦截放行的效果

这里我们举一个登录的示例,但只是简单的举例哦,真实开发并不是这样做的

首先我们在vue的原型指向上挂载一个属性,用来记录用户是否登录

Vue.prototype.isLogin = false

然后编写,第三个组件 login,并添加一个login点击事件


然后定义这个组件,并编写点击事件,点击就修改isLogin的值为 true,并使用this.$router.back返回上一个页面

const login = {
    template: '#login',
    methods: {
        login() {
            Vue.prototype.isLogin = true;
            //返回的意思
            this.$router.back();
        }
    },
}

然后配置路由信息

{
    path: '/login',
    component: login,
    name: 'login'
},

好的定义全局守卫,记住要在定义router之后 to, from, next也不用解释吧,语义化的,前置守卫顾名思义也就是执行之前会调用的,所以我们在这里进行判断用户是否登录,如果未登录,我们就挑战到 命名路由为login这个路由地址

 // 全局的 前置守卫
 router.beforeEach((to, from, next) => {
         if (!Vue.prototype.isLogin) {
             next({
                 name: 'login'
             });
         } else {
             next();
         }
 })

效果就是我们点击切换路由的时候,如果没有登录,就跳转到登录页面,但是这里大家仔细想这样一个问题,我的login路由同样也会执行守卫,同样我也没有登录,然后他就会再次跳转,这样就成了死循环,怎么解决这个问题呢?

路由元信息

我们简单修改一下路由配置,我们在需要判断登录的路由中加上meta: { isLogin: true },表明当前路由是需要登录的

routes: [
    {
        path: '/',
        redirect: '/page1',
        meta: { isLogin: true }
    },
    {
        path: '/page1',
        component: page1,
        name: 'page1',
        meta: { isLogin: true }
    },
    {
        path: '/page2',
        component: page2,
        name: 'page2',
        meta: { isLogin: true }
    },
    {
        path: '/login',
        component: login,
        name: 'login'
    },
],

然后我们怎么在路由守卫中读取这个字段那?

我们修改一下这个守卫,matched是路由记录,那么我们就在要到达的路由中进行查找字段to.matched.some(item => item.meta.isLogin)如果有这个字段的才进行判断

 router.beforeEach((to, from, next) => {
     // matched 路由记录
     if (to.matched.some(item => item.meta.isLogin)) {
         if (!Vue.prototype.isLogin) {
             next({
                 name: 'login'
             });
         } else {
             next();
         }
     } else {
         // 执行下一个钩子
         next();
     }
 })

然后我们在else里面执行 next();就是执行下一个钩子,也就是放行的意思

测试一下看看效果,我们先把mode改为hash方便测试,可以看到要先点击login才能进行访问

vue系列教程-11vuerouter路由_第8张图片

组件内的路由守卫

大家记得有些网页你点击后退或者其他,会弹出提示 是否确定离开吗?

我们来实践一下,修改一下 page1的组件定义,在beforeRouteLeave的钩子里面进行判断

const page1 = {
    template: '#page1',
    beforeRouteLeave(to, from, next) {
        const result = window.confirm('确定离开页面吗?将不会保存')
        if (result) {
            next()
        } else {
            next(false)
        }
    }
}

vue系列教程-11vuerouter路由_第9张图片

那么还有其他更多的路由参数,这里就不一一讲解了

你可能感兴趣的:(vue系列教程-11vuerouter路由)