第五章 Vue路由

1.Vue路由

1.1.Vue路由基础

Vue属于单页应用(SPA),即整个应用程序中只有一个html页面。

在单页应用中(SPA),由于只是更改DOM来模拟多页面,所以页面浏览历史记录的功能就丧失了。此时,就需要前端路由来实现浏览历史记录的功能。

<div id="app">
    <p>
        <!-- 使用 router-link 组件来导航. to属性指定导航地址-->
        <router-link to="/home">home</router-link>
        <router-link to="/news">news</router-link>
    </p>
    <!-- 路由出口(路由匹配到的组件将渲染在这里) -->
    <router-view></router-view>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>

<script type="text/javascript">
    // 1. 定义(路由)组件。
    const Home = {
        template: '<div>首页</div>'
    }
    const News = {
        template: '<div>新闻</div>'
    }

    // 2. 定义路由规则对象(每个路由应该映射一个组件)
    const routes = [
        {
            path: '/home',
            component: Home
        },{
            path: '/news',
            component: News
        }
    ]

    // 3. 创建 router 实例,然后传 `routes` 配置
    const router = new VueRouter({
        //如果路由规则对象名也为routes,那么就可以简写为 routes
        routes:routes     
    })

    // 4. 将路由对象挂载到Vue实例上
    // 通过 router 配置参数注入路由,从而让整个应用都有路由功能
    var vm = new Vue({
        el: '#app',
        data: {},
        // 将路由添加到Vue中
        router
    })
</script>
注意:

上面代码中,router-link标签默认会被渲染成一个a标签

在这里插入图片描述路由重定向:上面代码中,我们应该设置打开浏览器就默认调整到 “首页”,所以需要把根路由/重定向到/home。 修改路由配置:

// 2. 定义路由规则对象(每个路由应该映射一个组件)
const routes = [
    {
        path: '/',            //根路由
        redirect: '/home'     //把根路由重定向到home
    },{
        path: '/home',
        component: Home
    },{
        path: '/news',
        component: News
    }
]

1.2.嵌套路由

实际应用界面,通常由多层嵌套的组件组合而成。 比如,我们 “首页”组件中,还嵌套着 “登录”和 “注册”组件,那么URL对应就是/home/login和/home/reg。

<div id="app">
    <p>
        <!-- 使用 router-link 组件来导航. to属性指定导航地址-->
        <router-link to="/home">home</router-link>
        <router-link to="/news">news</router-link>
    </p>
    <!-- 路由出口(路由匹配到的组件将渲染在这里) -->
    <router-view></router-view>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>

<script type="text/javascript">
    // 1. 定义(路由)组件。
    const Home = {
        template: `<div>
                        <h2>首页</h2>
                        <router-link to="/home/login">登录</router-link>
                        <router-link to="/home/reg">注册</router-link>
                        <router-view></router-view>
                    </div>`
    }

    const News = {
        template: '<div>新闻</div>'
    }

    const Login = {
        template: '<div>登陆</div>'
    }

    const Reg = {
        template: '<div>注册</div>'
    }

    // 2. 定义路由规则对象(每个路由应该映射一个组件)
    const routes = [
        {
            path: '/',                //根路由
            redirect: '/home'         //把根路由重定向到home
        },{
            path: '/home',
            component: Home,
            children: [               //配置子路由
                {
                    path: '/home',
                    redirect: '/home/login'
                },{
                    path: '/home/login',
                    component: Login
                },{
                    path: '/home/reg',
                    component: Reg
                }
            ]
        }, {
            path: '/news',
            component: News
        },
    ]

    // 3. 创建 router 实例,然后传 `routes` 配置
    const router = new VueRouter({
        //如果路由规则对象名也为routes,那么就可以简写为 routes
        routes: routes
    })

    // 4. 将路由对象挂载到Vue实例上
    // 通过 router 配置参数注入路由,从而让整个应用都有路由功能
    var vm = new Vue({
        el: '#app',
        data: {},
        // 将路由添加到Vue中
        router
    })
</script>

1.3.路由传参

路由传参有多种方式,这里我们学习两种:params与query。
1.3.1.params形式传参

<div id="app">
    <p>
        <router-link :to="{name:'Home',params:{msg:'hello world!'}}">home</router-link>
        <router-link :to="{name:'News',params:{id:id,name:name}}">news</router-link>
    </p>
    <router-view></router-view>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>

<script type="text/javascript">
    const Home = {
        template: '<div>,首页</div>'
    }
    const News = {
        template: `<div>新闻;  
                        参数1:; 
                        参数2:
                    </div>`
    }

    const routes = [{
        path: '/home',
        name:'Home',              //每个路由规则中必须要有一个name属性
        component: Home
    }, {
        path: '/news',
        name:'News',
        component: News
    }]

    const router = new VueRouter({
        routes
    })

    var vm = new Vue({
        el: '#app',
        data: {
            id:1,
            name:'zhangsan'
        },
        router
    })
</script>

注意:

  • 使用v-bind绑定to属性
  • to属性的值是一个json对象,此对象有两个属性:name属性和params属性。
  • name属性就是要路由的对象。所以,在路由规则列表中,每一个路由规则都应用有一个name值。
  • params属性就是要传递的参数。也是一个json对象。
  • 组件接收参数时,使用 this.$route.params.参数名 的形式。

1.3.2.query形式传参

<div id="app">
    <p>
        <router-link :to="{path:'/home',query:{msg:'hello world!'}}">home</router-link>
        <router-link :to="{path:'/news',query:{id:id,name:name}}">news</router-link>
    </p>
    <router-view></router-view>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>

<script type="text/javascript">
    const Home = {
        template: '<div>,首页</div>'
    }
    const News = {
        template: `<div>新闻;  
                        参数1:; 
                        参数2:
                    </div>`
    }

    const routes = [{
        path: '/home',
        component: Home
    }, {
        path: '/news',
        component: News
    }]

    const router = new VueRouter({
        routes
    })

    var vm = new Vue({
        el: '#app',
        data: {
            id:1,
            name:'zhangsan'
        },
        router
    })
</script>

注意:

  1. to属性的值仍然是一个josn对象,但是两个属性变了,一个是path,一个是query。
  2. path属性就是路由地址,对应路由规则中的path值。
  3. query属性就是要传递的参数。也是一个json对象。
  4. 组件接收参数时,使用 this.$route.query.参数名 的形式。
    1.3.3.params方式与query方式的区别

query方式传值:
在这里插入图片描述
params方式传值:
在这里插入图片描述
总结:params方式与query方式的区别:

    query方式:

    类似于get方式,参数会在路由中显示,可以用做刷新后仍然存在的参数。

    利用路由规则中的path跳转。

    params方式:

    类似于post方式,参数不会在路由中显示,页面刷新后参数将不存在。

    利用路由规则中的name跳转。

2.编程式路由

2.1.利用JS实现路由跳转

router-link标签可以实现页面超链接形式的路由跳转。但是实际开发中,在很多情况下,需要通过某些逻辑判断来确定如何进行路由跳转。也就是说:需要在js代码中进行路由跳转。此时可以使用编程式路由。

1.使用"this. r o u t e r . p u s h " 方 法 可 以 实 现 路 由 跳 转 , 方 法 的 第 一 个 参 数 可 为 s t r i n g 类 型 的 路 径 , 或 者 可 以 通 过 对 象 将 相 应 参 数 传 入 。 2. 通 过 t h i s . router.push "方法可以实现路由跳转,方法的第一个参数可为string类型的路径,或者可以通过对象将相应参数传入。 2.通过this. router.push"string2.this.router.go(n)方法可以实现路由的前进后退,n表示跳转的个数,正数表示前进,负数表示后退。
3.如果只想实现前进后退可以使用this. r o u t e r . f o r w a r d ( ) ( 前 进 一 页 ) , 以 及 t h i s . router.forward()(前进一页),以及this. router.forward()this.router.back()(后退一页)。

<div id="app">
    <p>
        <button @click="toHome">首页</button>
        <button @click="toNews">新闻</button>
        <button @click="toLogin">登陆</button>
        <button @click="doForward1">前进</button>
        <button @click="doForward2">前进</button>
        <button @click="doBack1">后退</button>
        <button @click="doBack2">后退</button>
    </p>
    <router-view></router-view>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>

<script type="text/javascript">
    const Home = {
        template: '<div>首页</div>'
    }
    const News = {
        template: '<div>新闻:</div>'
    }
    const Login = {
        template: '<div>登陆</div>'
    }

    const routes = [{
        path: '/',
        component: Home
    }, {
        path: '/home',
        component: Home
    }, {
        path: '/news',
        component: News
    }, {
        path: '/login',
        component: Login
    }]

    const router = new VueRouter({
        routes
    })

    var vm = new Vue({
        el: '#app',
        data: {},
        router,
        methods:{
            toHome(){
                //无参数时,push方法中直接写路由地址
                this.$router.push('/home');
            },
            toNews(){
                //有参数时,push方法中写一个json对象
                this.$router.push({path:'/news',query:{name:'zhangsan'}});
            },
            toLogin(){
                this.$router.push('/login');
            },
            doForward1(){
                this.$router.forward();
            },
            doForward2(){
                this.$router.go(1);
            },
            doBack1(){
                this.$router.back();
            },
            doBack2(){
                this.$router.go(-1);
            }
        }
    })
</script>

2.2.通过watch实现路由监听

通过watch属性设置监听$route变化,达到监听路由跳转的目的。

在上面代码中添加watch监听:

watch: {
    // 监听路由跳转。
    $route(newRoute, oldRoute) {
        console.log('watch', newRoute, oldRoute)
    }
}

2.3.导航守卫

路由跳转前做一些验证,比如登录验证,是网站中的普遍需求。 对此,vue-route 提供了实现导航守卫(navigation-guards)的功能。

你可以使用 router.beforeEach 注册一个全局前置守卫:

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
    // ...
})

每个守卫方法接收三个参数:

  1. to:即将要进入的目标路由对象(去哪里),可以使用 to.path 获取即将要进入路由地址。

2.from:当前导航正要离开的路由对象(从哪来),可以使用 from.path 获取正要离开的路由地址。

  1. next:一个函数,表示继续执行下一个路由。(如果没有next,将不会进入到下一个路由)

下面例子中实现了如下功能:

1.列举需要判断登录状态的 “路由集合”,当跳转至集合中的路由时,如果“未登录状态”,则跳转到登录页面
2.当直接进入登录页面LoginPage时,如果“已登录状态”,则跳转到首页HomePage;

<div id="box">
    <p>
        <router-link to="/home">home</router-link>
        <router-link to="/news">news</router-link>
        <router-link to="/music">music</router-link>
        <router-link to="/login">login</router-link>
    </p>
    <router-view></router-view>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>

<script type="text/javascript">
    const Home = {
        template: '<div>首页</div>'
    }
    const News = {
        template: '<div>新闻</div>'
    }
    const Music = {
        template: '<div>音乐</div>'
    }
    const Login = {
        template: '<div>登录</div>'
    }

    const routes = [{
        path: '/',
        component: Home
    }, {
        path: '/home',
        component: Home
    }, {
        path: '/news',
        component: News
    }, {
        path: '/music',
        component: Music
    }, {
        path: '/login',
        component: Login
    }]

    const router = new VueRouter({
        routes // (缩写)相当于 routes: routes
    })

    var vm = new Vue({
        el: '#box',
        data: {},
        router
    })

    // 添加全局路由守卫
    router.beforeEach((to, from, next) => {
        //创建守卫规则集合(这里表示'/news'与'/music'路径是需要权限验证的)
        const nextRoute = ['/news', '/music'];
        // 使用isLogin来模拟是否登录
        let isLogin = false;
        // 判断to.path(要跳转的路径)是否是需要权限验证的
        if (nextRoute.indexOf(to.path) >= 0) {
            if (!isLogin) {
                router.push({
                    path: '/login'
                })
                location.reload(); //必须要有
            }
        }
        // 已登录状态;当路由到login时,跳转至home
        if (to.path === '/login') {
            if (isLogin) {
                router.push({
                    path: '/home'
                });
                location.reload();
            }
        }
        next(); //必须要有
    });
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值