vue学习笔记-路由篇

什么是路由?

  • 路由就是通过url的地址去请求的资源,这个地址和资源有一种对应关系, 就被叫做路由

  • 路由分为前端路由和后端路由

    • 前端路由:通过hash值(锚链接)的变化实现
    • 后端路由:在服务器中实现,通过url的地址去访问不同的资源

实现一个简单的路由

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <div>
            <a href="#/nationNews">国内新闻</a>
            <a href="#/foreignNews">国际新闻</a>
            <a href="#/hotNews">热点新闻</a>
            <a href="#/playNews">娱乐新闻</a>
        </div>
        <hr />
        <component :is="componentId"></component>
    </div>

</body>
<script src="./lib/vue_2.5.22.js"></script>
<script>
    //点击a链接,就会改变url中的hash值,当hash发生变化时触发
    window.onhashchange = function () {
        console.log(location.hash)//获取hash值
        switch (location.hash.slice(1)) {//根据不同hash值实现路由切换
            case '/nationNews':
                vm.componentId = 'nation-news'
                break;
            case '/foreignNews':
                vm.componentId = 'foreign-news'
                break;
            case '/hotNews':
                vm.componentId = 'hot-news'
                break;
            case '/playNews':
                vm.componentId = 'play-news'
                break;
        }
    }

    //国内新闻组件
    var nationNews = {
        template: `
            <div><h1>国内新闻</h1></div>
        `
    }
    //国际新闻组件
    var foreignNews = {
        template: `
            <div><h1>国际新闻</h1></div>
        `
    }
    //热点新闻组件
    var hotNews = {
        template: `
            <div><h1>热点新闻</h1></div>
        `
    }
    //娱乐新闻组件
    var playNews = {
        template: `
            <div><h1>娱乐新闻</h1></div>
        `
    }
    //创建vue实例
    var vm = new Vue({
        el: "#app",
        data: {
            componentId: 'nation-news'//默认显示国内新闻
        },
        //注册组件
        components: {
            'nation-news': nationNews,
            'foreign-news': foreignNews,
            'hot-news': hotNews,
            'play-news': playNews
        }
    })

</script>

</html>

页面显示结果如下
在这里插入图片描述

Vue-Router

  • 它是一个Vue.js官方提供的路由管理器。是一个功能更加强大的前端路由器
  • 可以一起方便的实现SPA(single page web application),单页应用程序应用程序的开发

Vue-Router的特性

  • 支持H5历史模式或者hash模式
  • 支持嵌套路由
  • 支持路由参数
  • 支持编程式路由
  • 支持命名路由
  • 支持路由导航守卫
  • 支持路由过渡动画特效
  • 支持路由懒加载
  • 支持路由滚动行为

Vue-router使用步骤

  • 下载vue-router插件,https://router.vuejs.org/zh/installation.html
  • 引入vue-router
    -注意:要放置在vue.js后
  • 添加路由链接
    <router-link>
  • 添加路由填充位
    <router-view>
  • 定义路由组件
  • 配置路由
  • 挂载路由到vue实例中

示例代码如下

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

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <div>
            <!-- 使用router-link代替a标签,router-link默认是a标签 to属性默认是href属性 -->
            <router-link to="/nationNews">国内新闻</router-link>
            <router-link to="/foreignNews">国际新闻</router-link>
            <router-link to="/hotNews">热点新闻</router-link>
            <router-link to="/playNews">娱乐新闻</router-link>
        </div>
        <hr />
        <!-- 路由填充位,组件要显示的位置 -->
        <router-view />
    </div>

</body>
<!-- 引入vue.js -->
<script src="./lib/vue_2.5.22.js"></script>
<!-- 引入vue-router.js必须放在vue.js后 -->
<script src="./lib/vue-router_3.0.2.js"></script>
<script>

    //国内新闻组件
    var nationNews = {
        template: `
            <div><h1>国内新闻</h1></div>
        `
    }
    //国际新闻组件
    var foreignNews = {
        template: `
            <div><h1>国际新闻</h1></div>
        `
    }
    //热点新闻组件
    var hotNews = {
        template: `
            <div><h1>热点新闻</h1></div>
        `
    }
    //娱乐新闻组件
    var playNews = {
        template: `
            <div><h1>娱乐新闻</h1></div>
        `
    }

    //创建vue-router实例
    //这里的VueRouter是vue-router.js中提供的
    var router = new VueRouter({
        //配置路由规则,因为有多个路由,所以routes属性是一个数组,存放的是路由对象
        routes: [
            //设置默认页面,redirect表示要被重定向的新地址,这里默认重定向到国内新闻
            { path: '/', redirect: '/nationNews' },
            //path页面的地址,component组件对象
            { path: '/nationNews', component: nationNews },
            { path: '/foreignNews', component: foreignNews },
            { path: '/hotNews', component: hotNews },
            { path: '/playNews', component: playNews },
        ]
    })
    //创建vue实例
    var vm = new Vue({
        el: "#app",
        //将router挂载到vue实例中
        router: router
    })

</script>

</html>

嵌套路由

  • 有时候可能在某一个组件中又包含着子级路由链接,这时需要使用嵌套路由实现

示例代码如下:

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

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <div>
            <!-- 使用router-link代替a标签,router-link默认是a标签 to属性默认是href属性,to属性的值会被渲染为#开头的hash地址 -->
            <router-link to="/nationNews">国内新闻</router-link>
            <router-link to="/foreignNews">国际新闻</router-link>
            <router-link to="/hotNews">热点新闻</router-link>
            <router-link to="/playNews">娱乐新闻</router-link>
        </div>
        <hr />
        <!-- 路由填充位,组件要显示的位置 -->
        <router-view />
    </div>

</body>
<!-- 引入vue.js -->
<script src="./lib/vue_2.5.22.js"></script>
<!-- 引入vue-router.js必须放在vue.js后 -->
<script src="./lib/vue-router_3.0.2.js"></script>
<script>

    //国内新闻组件
    //只做演示,这里只写一个嵌套路由
    var nationNews = {
        template: `
            <div>
                <h1>国内新闻</h1>
                <router-link to="/nationNews/heatRanking">热度排行榜</router-link>
                <router-view/>
            </div>
        `
    }
    //国际新闻组件
    var foreignNews = {
        template: `
            <div><h1>国际新闻</h1></div>

        `
    }
    //热点新闻组件
    var hotNews = {
        template: `
            <div><h1>热点新闻</h1></div>
        `
    }
    //娱乐新闻组件
    var playNews = {
        template: `
            <div><h1>娱乐新闻</h1></div>
        `
    }
    //热度排行榜组件
    var heatRanking = {
        template: `
            <div><h2>热度排行榜</h2></div>
        `
    }
    //创建vue-router实例
    //这里的VueRouter是vue-router.js中提供的
    var router = new VueRouter({
        //配置路由规则,因为有多个路由,所以route属性是一个数组,存放的是路由对象
        routes: [
            //设置默认页面,redirect表示要被重定向的新地址,这里默认重定向到国内新闻
            { path: '/', redirect: '/nationNews' },
            //path页面的地址,component组件对象
            {
                path: '/nationNews',
                component: nationNews,
                children: [{//children属性仍然是一个数组,存放的是路由对象
                    path: 'heatRanking',//这种方式前面不能带'/',还有另一种方式:/nationNews/heatRanking
                    component: heatRanking
                }]
            },
            { path: '/foreignNews', component: foreignNews },
            { path: '/hotNews', component: hotNews },
            { path: '/playNews', component: playNews },
        ]
    })
    //创建vue实例
    var vm = new Vue({
        el: "#app",
        //将router挂载到vue实例中
        router: router
    })

</script>

</html>

页面显示结果如下
在这里插入图片描述

动态路由

先看一段代码

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

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <div>
            <router-link to="/user">显示用户列表</router-link>
        </div>
        <!-- 路由填充位,组件要显示的位置 -->
        <router-view />
    </div>

</body>
<!-- 引入vue.js -->
<script src="./lib/vue_2.5.22.js"></script>
<!-- 引入vue-router.js必须放在vue.js后 -->
<script src="./lib/vue-router_3.0.2.js"></script>
<script>

    //用户列表
    var user = {
        template:
            `
            <div>
                <h1>用户列表</h1>
                <router-link to="/user/1">用户1</router-link>
                <router-link to="/user/2">用户2</router-link>
                <router-link to="/user/3">用户3</router-link>
                <router-link to="/user/4">用户4</router-link>
                <router-view/>
            </div>
            
        `
    }
    //用户1组件
    var user1 = {
        template: `
            <div>
                <h1>用户信息如下</h1>
                <span>姓名:张三</span></br>
                <span>性别:男</span></br>
                <span>年龄:18</span></br>
            </div>
        `
    }

    //用户2组件
    var user2 = {
        template: `
            <div>
                <h2>用户信息如下</h2>
                <span>姓名:李四</span></br>
                <span>性别:男</span></br>
                <span>年龄:19</span></br>
            </div>
        `
    }
    //用户3组件
    var user3 = {
        template: `
            <div>
                <h2>用户信息如下</h2>
                <span>姓名:王丹</span></br>
                <span>性别:女</span></br>
                <span>年龄:20</span></br>
            </div>
        `
    }
    //用户4组件
    var user4 = {
        template: `
            <div>
                <h2>用户信息如下</h2>
                <span>姓名:赵柳</span></br>
                <span>性别:男</span></br>
                <span>年龄:18</span></br>
            </div>
        `
    }

    //创建vue-router实例
    //这里的VueRouter是vue-router.js中提供的
    var router = new VueRouter({
        //配置路由规则,因为有多个路由,所以route属性是一个数组,存放的是路由对象
        routes: [
            //path页面的地址,component组件对象
            {
                path: '/user',
                component: user,
                //children属性仍然是一个数组,存放的是路由对象
                children: [
                    {
                        path: '1',//这种方式前面不能带'/',还有另一种方式:/user/1
                        component: user1
                    },
                    {
                        path: '2',//这种方式前面不能带'/',还有另一种方式:/user/2
                        component: user2
                    },
                    {
                        path: '3',//这种方式前面不能带'/',还有另一种方式:/user/3
                        component: user3
                    },
                    {
                        path: '4',//这种方式前面不能带'/',还有另一种方式:/user/4
                        component: user4
                    }
                ]
            },

        ]
    })
    //创建vue实例
    var vm = new Vue({
        el: "#app",
        //将router挂载到vue实例中
        router: router
    })

</script>

</html>

页面显示结果如下
在这里插入图片描述

  • 从代码中可以发现几个问题

    • 代码太冗余,大量重复代码
    • 每添加一个路由链接就需要添加一个路由对象,并且模板都是一样的
    • 如果有100个用户?需要添加100个吗?

为了解决这个问题,可以使用vue-router中的动态路由解决

示例代码如下:

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

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <div>
            <router-link to="/user">显示用户列表</router-link>
        </div>
        <!-- 路由填充位,组件要显示的位置 -->
        <router-view />
    </div>

</body>
<!-- 引入vue.js -->
<script src="./lib/vue_2.5.22.js"></script>
<!-- 引入vue-router.js必须放在vue.js后 -->
<script src="./lib/vue-router_3.0.2.js"></script>
<script>

    //用户列表,一般会调用后台接口遍历用户,这里不做演示
    var user = {
        template:
            `
            <div>
                <h1>用户列表</h1>
                <router-link to="/user/1">用户1</router-link>
                <router-link to="/user/2">用户2</router-link>
                <router-link to="/user/3">用户3</router-link>
                <router-link to="/user/4">用户4</router-link>
                <router-view/>
            </div>
            
        `
    }
    //用户信息组件
    var userInfo = {
        props: ["id"],//通过props获取参数,我们可以根据id查询用户信息再渲染到模板中,这里不做演示
        template: `
            <div>
                <h1>用户信息如下</h1>
                <span>用户id:{{id}}</span></br>
                <span>姓名:张三</span></br>
                <span>性别:男</span></br>
                <span>年龄:18</span></br>
            </div>
        `
    }

  

    //创建vue-router实例
    //这里的VueRouter是vue-router.js中提供的
    var router = new VueRouter({
        //配置路由规则,因为有多个路由,所以route属性是一个数组,存放的是路由对象
        routes: [
            //path页面的地址,component组件对象
            {
                path: '/user',
                component: user,
                //children属性仍然是一个数组,存放的是路由对象
                children: [
                    //通过/:参数名  的形式传递参数 
                    //如果props设置为true,route.params将会被设置为组件属性
                    {
                        path: ':id',//这种方式前面不能带'/'
                        component: userInfo,
                        props:true
                    },
                ]
            },

        ]
    })
    //创建vue实例
    var vm = new Vue({
        el: "#app",
        //将router挂载到vue实例中
        router: router
    })

</script>
</html>

页面显示结果如下:
在这里插入图片描述

  • 这样一来,解决了以上问题,可以根据动态路由显示不同用户信息

补充

  • prop还可以是对象,将prop设置为对象形式
props:{username:'李四',age:18}
  • prop也可以是动态传参+对象,将prop设置为函数形式
props:(route)=>{
      	return {username:"jack",pwd:123,id:route.params.id}
      } 

命名路由

  • 给路由取别名
const router = new VueRouter({
  routes: [
    {
      path: '/user/:id',
      name: 'user',
      component: User
    }
  ]
})
<router-link 
	//可以使用别名进行跳转
	:to="{ name: 'user', params: { id: 1}}">用户1
</router-link>

编程式导航

页面导航有两种方式

  • 声明式导航:通过点击链接的方式实现的导航
  • 编程式导航:调用jsapi方法实现导航

vue-router中的编程式导航
router.push()

// 字符串
router.push('home')

// 对象
router.push({ path: 'home' })

// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})

// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

router.go()

this.$router.go( n );//n为数字,参考history.go

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值