Vue-路由

路由可以分为前端路由和后端路由

后端路由:
  • 概念:根据不同的用户url请求,返回不同的内容
  • 本质:URL请求地址和服务器资源之间的对应关系

为什么要有前端路由:


image.png
前端路由
  • 概念:前端路由指的是根据不同的用户事件,显示不同的页面内容
  • 本质:用户事件与事件处理函数之间的对应关系
image.png
实现简单前端路由

一个简单的模拟路由代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="./js/vue.js"></script>
    <title>Document</title>
</head>
<body>
    <div id="app">
        <a href="#/index">主页</a>
        <a href="#/tecn">科技</a>
        <a href="#/economic">财经</a>
        <a href="#/joy">娱乐</a>
        <component :is="comName"></component>
        <!-- 这个component是用来占位的,为了可以更换组件 -->
    </div>
    <script>
        const index = {
            template:`<h1>主页</h1>`
        }
        const tecn = {
            template:`<h1>科技</h1>`
        }
        const economic = {
            template:`<h1>财经</h1>`
        }
        const joy = {
            template:`<h1>娱乐</h1>`
        }
        var app = new Vue({
            el:'#app',
            data:{
                comName:'index'
            },
            components:{
                index,
                tecn,
                economic,
                joy
            }
        })

        window.onhashchange = function(){//检测hash的改变但是不刷新页面
            console.log(location.hash);//新的hash存储在这儿
            // var str = location.hash
            // var path = ''
            // for(var i = 2;i<str.length;i++){
            //     path+=str[i]
            // }
            // app.comName = path
            app.comName = location.hash.slice(2)
            //用slice做字符串截取比较的方便
        }
    </script>
</body>
</html>

这样子做的网页,可以是回退的

vue-router

vue-router是Vue官方提供的路由管理器
其支持的功能有:

  • 支持HTML5 历史模式或hash模式
  • 支持嵌套路由
  • 支持路由参数
  • 支持编程式路由
  • 支持命名路由
vue-router的基本使用

1 引入相关库文件
2 添加路由链接
3 添加路由填充位
4 定义路由组件
5 配置路由规则并创建路由实例
6 把路由挂载到Vue根实例中
一个例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="./js/vue.js"></script>
    <script src="./js/vue-router.js"></script>
    <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>
        const User = {
            template:`<h1>User</h1>`
        }
        const Register = {
            template:`<h1>Register</h1>`
        }

        const router = new VueRouter({
            routes: [
                //每个路由规则都是一个配置对象,其中至少包含path和component两个属性
                //pash表示当前路由规则说匹配的hsah地址
                //component表示当前路由规则对应要展示的组件
                {path:'/user',component:User},
                {path:'/Register',component:Register}
            ]
        })

        var vm = new Vue({
            el:'#app',
            data:{},
            //挂载路由
            // router:router
            router//在ES6中,属性名和属性对象是同名的话,可以直接这么简写
        })
    </script>
</body>
</html>
路由重定向:

通过路由规则的redirect属性,指向一个新的路由地址。
比如刚才的案例,我们想要实现一上来展示的默认组件就是User,就可以用到路由重定向

const router = new VueRouter({
            routes: [
                //每个路由规则都是一个配置对象,其中至少包含path和component两个属性
                //pash表示当前路由规则说匹配的hsah地址
                //component表示当前路由规则对应要展示的组件
                {path:'/',redirect:User},
                {path:'/user',component:User},
                {path:'/Register',component:Register}
            ]
        })
vue-router嵌套路由

对之前的案例做如下改进

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="./js/vue.js"></script>
    <script src="./js/vue-router.js"></script>
    <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>
        const User = {
            template:`<h1>User</h1>`
        }
        const Register = {
            template:`
            <div>
                <h1>Register组件</h1>
                <hr>
                <router-link to='/register/tab1'>tab1</router-link>
                <router-link to='/register/tab2'>tab2</router-link>
                <router-view></router-view>
            </div>
            `
        }
        const Tab1 = {
            template:`<h3>tab1</h3>`
        }
        const Tab2 = {
            template:`<h3>tab2</h3>`
        }
        const router = new VueRouter({
            routes: [
                //每个路由规则都是一个配置对象,其中至少包含path和component两个属性
                //pash表示当前路由规则说匹配的hsah地址
                //component表示当前路由规则对应要展示的组件
                {path:'/',redirect:User},
                {path:'/user',component:User},
                {path:'/register',component:Register,
                    children:[
                        {path:'/register/tab1',component:Tab1},
                        {path:'/register/tab2',component:Tab2}
                    ]
                },
                
            ]
        })

        var vm = new Vue({
            el:'#app',
            data:{},
            //挂载路由
            // router:router
            router//在ES6中,属性名和属性对象是同名的话,可以直接这么简写
        })
    </script>
</body>
</html>

vue-router路由动态匹配

eg:

var router = new VueRouter({
  routers:[
    //动态路由参数,以冒号开头
    {path:'/user/:id',component:User}
  ]
})
const User = {
  template:`<div>User {{ $route.params.id }}</div>` //使用刚刚从路由中获取到的id
}

像上面那种写法,确实可以做到路由传参,但是$route与对应的路由高度耦合,不够灵活,所以可以使用props将组件和路由解耦合

props路由传参

三种方法:
1 传递路由参数

var User = {
            props:['id'],
            template: "<h1>User {{id}}</h1>"    
        }
                {path:'/User/:id',component:User,props:true},

2 传递静态资源

{path:'/User/:id',component:User,props:{uname:'zhangsan',age:22}},

3 同时传递路由参数和静态资源

{path:'/User/:id',component:User,
                    props:(route)=>({    //这样写会直接返回一个对象给props
                            uname:'zhangsan',
                            age:22,
                            id:route.params.id
                        })
                    
                },
注:箭头函数的后面不用花括号,而是直接用小括号包裹一个对象会直接返回这个对象
vue-router命名路由
        <router-link :to='{name:"user",params:{id:3}}'>User3</router-link>
                {
                    path:'/user/:id',
                    name:"user",
                    component:User
                },

编程式导航

页面导航的两种方式
  • 声明式导航:
    如<a>标签,<router-link>标签等
  • 编程式导航:
    通过调用JS的API实现导航的方式
    例如:普通网页中的location.href

Vue中常用的编程式导航基本用法:

  • this.$router.push('hash地址')
  • this.$router.go(n) //这是前进或后退的,n是数字,如果填1,就代表在历史记录中向前走一位
    push的使用规则:


    image.png
路由导航守卫

场景:我们希望必须已经登陆后才能访问home页面,可是默认情况下直接在浏览器url地址栏输入localhost:8080/home还是能进入home页面,显然这是不符合需求的。
因此需要添加路由导航守卫
目标:如果用户没有登陆,但是通过url访问特定页面,则直接重新导航到login页面去


image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容

  • PS:转载请注明出处作者: TigerChain地址https://www.jianshu.com/p/9a7d7...
    TigerChain阅读 63,646评论 9 218
  • 本文转载于前端工匠。如有侵权联系本人立刻删除 一、首先带着问题 要学习vue-ro...
    qiaoguoxing阅读 458评论 0 1
  •   通常我们会用一个或多个路由表,来匹配所有页面的路径。但这不能满足一些特定的需求。 # 解惑   好几次被问到怎...
    果汁凉茶丶阅读 2,261评论 0 8
  • Vue Router 官网已经写得很好了,这里自己再总结巩固下。(注意:这里所有的例子都是基于Vue/cli 3....
    李牧敲代码阅读 838评论 1 1
  • 这里说的Vue中的路由是指前端路由,与后端路由有所区别。我们可以使用url来获取服务器的资源,而这种url与资源的...
    一颗脑袋阅读 589评论 0 0