20201015李权

Vue-Router路由:

路由主要用来实现单页面开发

在传统的前端多页面应用中,网站的每一个url都相对应着服务器中的一个物理地址,当我们发送一个http请求的时候,服务器会自动把我们的请求对应到当前站点的路径下面的index.html文件,然后给与响应,当跳转到别的页面上,则重复一边这个过程

但是如果是单页面开发,有且只有一个html页面,当用户切花页面的时候,只是通过这个唯一的html文件进行动态的重写,从而达到响应用户的请求,也就是说从切换页面的应用,应用只是在第一次打开页面请求了服务器

前端路由的实现方式:

前端路由实现方式有两种:hash路由匹配 或者 html5中history路由的API

hash路由:

hash路由是通过浏览器的location对象中的hash属性实现的,他会记录链接地址#后面的地址,因此我们可以通过window.onhashChange事件获取到跳转前后访问的地址,从而实现切换地址的目的

history路由

history路由以前在html中是通过histor对象的go,back,forward方法来记录用户的历史纪录,实现页面的跳转,而现在history是通过html5中的pushState()事件和replaceState()事件,

在vue中,Vue Router是官方提供的路由管理器,他是vue的核心深度集成

路由的实现步骤:

1.首先将Vue Router 添加到项目中,获得前端路由的支持:

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

2.构建页面的时候,需要将每个路由的组件映射到router的规则中。

3.如果是引入vue router这个组件而不是脚手架,我们需要手动的将vue Router挂载到vue上,不然无法使用router-view标签

Vue.use(VueRouter)

4.配置路由,以及路由的模块

    //1.定义路由跳转的组件模板
    const home = {
        template:`<div><h3>首页内容</h3></div>`
    }
    const list = {
        template:`#tpl`
    }
    const login = {
        template:`<div>登录页面的内容</div>`
    }
    const register = {
        template:`<div>注册页面的内容</div>`
    }
    //2.定义路由的信息
    const routes = [
        //1.路由重定向:当路径为 / 时,路由重定向到home路径
        {
            path:'/',
            redirect:'/home'
        },
        {
            path:'/home',
            component:home
        },
        {
            path:'/list',
            component:list,
            //定义二级路由:
            children:[
                {
                    path:'login',
                    component:login,
                },
                {
                    path:'register',
                    component:register
                },
                //路径重定向
                {
                    path:'/list',
                    redirect:'/list/login'
                }
            ]
        }
    ]

5.实列化路由:

  //实例化路由
    let router = new VueRouter({
        //mode :'history' 使用hash路由还是history路由
        routes,
    })

6.将路由挂载到vue实列对象上

    //挂载到当前的Vue实列
    new Vue({
        el:'#app',
        data:{},
        methods: {
            
        },
        router,
    })

代码的全部:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #app{
            text-align: center;
        }
        .container{
            background-color: #73ffd6;
            margin-top: 20px;
            height: 300px;
        }
        .son{
            margin-top: 30px;
        }
    </style>
</head>
<body>
    <div id="app">
        <!-- 通过router-link 标签来生成导航标签 -->
         <router-link to="/home">首页</router-link>
         <router-link to="/list">列表</router-link>
         <div class="container">
             <!-- 将选中的路由 渲染到 router-view 下 -->
             <router-view></router-view>
         </div>
    </div>
    <template id="tpl">
        <div>
            <h3>列表内容</h3>
            <!-- 生成嵌套子路由 -->
            <router-link to='/list/login'>登录</router-link>
            <router-link to='/list/register'>注册</router-link>
            <div class="son">
                <router-view></router-view>
            </div>
        </div>
    </template>
<script src="../vue-router-dev/dist/vue-router.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    console.log(VueRouter);
    //要把VueRouter挂载到Vue上
    Vue.use(VueRouter)
    //1.定义路由跳转的组件模板
    const home = {
        template:`<div><h3>首页内容</h3></div>`
    }
    const list = {
        template:`#tpl`
    }
    const login = {
        template:`<div>登录页面的内容</div>`
    }
    const register = {
        template:`<div>注册页面的内容</div>`
    }
    //2.定义路由的信息
    const routes = [
        //1.路由重定向:当路径为 / 时,路由重定向到home路径
        {
            path:'/',
            redirect:'/home'
        },
        {
            path:'/home',
            component:home
        },
        {
            path:'/list',
            component:list,
            //定义二级路由:
            children:[
                {
                    path:'login',
                    component:login,
                },
                {
                    path:'register',
                    component:register
                },
                //路径重定向
                {
                    path:'/list',
                    redirect:'/list/login'
                }
            ]
        }
    ]

    //实例化路由
    let router = new VueRouter({
        //mode :'history' 使用hash路由还是history路由
        routes,
    })
    //挂载到当前的Vue实列
    new Vue({
        el:'#app',
        data:{},
        methods: {
            
        },
        router,
    })
</script>
</body>
</html>

命名路由,命名视图,路由传参:

命名路由:

在某些时候,可能有多级路由,url地址过长,导致使用会非常不方便,可以通过一个名称标志一个路由,我们可以路由设定一个name属性,然后动态绑定router-link的to属性,进行指定跳转,从而方便调用路由

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

下面是路由实列:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #app{
            text-align: center;
        }
        .container{
            background-color: #73ffd6;
            margin-top: 30px;
            height: 300px;
        }
        .son{
            margin-top: 30px;
        }
    </style>
</head>
<body>
    <!-- 命名路由  -->
    <div id="app">
        <!-- 通过router-link标签生成导航栏链接 -->
        <router-link :to="{name:'home'}">首页</router-link>
        <router-link :to="{name:'list'}">列表</router-link>
        <div >
            <router-view></router-view>
        </div>

    </div>
    <template id="tpl">
        <div>
            <h3>列表内容</h3>
            <router-link to='/list/login'>注册</router-link>
            <router-link to='/list/register'>登录</router-link>
            <div class="son">
                <!-- 生成嵌套的子路由渲染点 -->
                <router-view></router-view>
            </div>
        </div>
       
    </template>
    <script src="../vue-router-dev/dist/vue-router.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        //将Vue Router 挂载到 Vue上
        Vue.use(VueRouter)
        //1.定义路由跳转的组件模板
        //home组件
        const home = {
            template:`<div><h3>首页内容</h3></div>`
        }
        //list组件
        const list ={
            template:'#tpl'
        }
        //login组件
        const login = {
            template:`
                <div>登陆页面的内容</div>
            `
        }
        //注册主键的内容
        const register ={
            template:`
                <div>注册页面的内容</div>
            `
        }
        //2.定义路由的信息
        const router = new VueRouter({
            routes:[
                {
                  path:'/',
                  redirect:'/home'  
                },
                {
                    path:'/home',
                    name:'home',
                    component:home,
                }
                ,{
                    path:'/list',
                    name:'list',
                    component:list,
                    //二级路由
                    children:[
                        {
                            path:'login',
                            name:'login',
                            component:login,
                        },
                        {
                            path:'register',
                            name:'register',
                            component:register
                        },

                    ]
                },
            ]
        })
        //挂载到Vue实列上
        new Vue({
            el:'#app',
            data:{},
            router,
        })
    </script>
</body>
</html>

注意,当我们给二级路由写路径的时候,不能加上根标签,不然会显示不出来

当我如果使用指定名字跳转路由,想要传参的时候,可以使用 params属性传递参数

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

命名视图:

router-view就是视图,命名视图其实和命名路由类似,在router-view的标签上添加一个name属性,然后再在配置路由的时候,要用components,用对象接受一个页面的几个组件

实现命名视图的实列:

<div id="app">
    <router-view></router-view>
    <div>
        <router-view name="sidebar"></router-view>
        <router-view name="main"></router-view>
    </div>
</div>
<script>
    //定义路由的信息
    const router = new VueRouter({
        routes:[
            {
                path:'/',
                components:{
                    default:header,
                    sidebar:sidebar,
                    main:main
                }
            }
        ]
    })
</script>

在router-view中,默认的name属性值为default,所以这里的header组件对应的router-view标签可以不设定name属性

命名视图一个小实列:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .style1{
            height: 20vh;
            background-color: #0bb20c;
            color: whitesmoke;
        }
        .style2{
            background-color: #9e8158;
            float: left;
            width: 30%;
            height: 70vh;
            color: white;
        }
        .style3{
            background-color: #2d309e;
            float: left;
            width: 70%;
            height: 70vh;
            color: white;
        }
    </style>
</head>
<body>
    <div id="app">
        <div class="style1">
            <router-view></router-view>
        </div>
        <div class="container">
            <div class="style2">
                <router-view name="sidebar"></router-view>
            </div>
            <div class="style3">
                <router-view name="main"></router-view>
            </div>
        </div>
    </div>
    <template id="sidebar">
        <div class="sidebar">
            侧边导航栏
        </div>
    </template>
    <script src="../vue-router-dev/dist/vue-router.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        //1.定义路由跳转的组件模板
        const header = {
            template:`<div class="header">头部内容</div>`
        }
        const sidebar = {
            template:`#sidebar`
        }
        const main ={
            template :`
                <div class="main">正文部分</div>
            `
        }
        //2.定义路由的信息
        const routes = [{
            path:'/',
            //命名视图
            components:{
                default:header,
                sidebar:sidebar,
                main:main,
            }
        }]
        //3.实例路由
        const router = new VueRouter({
            routes
        })
        //4.将路由对象挂载到实例对象上
        new Vue({
            el:'#app',
            data:{},
            router,
        })
    </script>
</body>
</html>

路由传参:

将实例化的VueRouter挂载到实例对象上,VueRouter就在Vue实例上创建了两个对象 this.\(router(router的实)和 this.\)route(当前页面的路由信息)

1.query传参:

query传参就是直接将参数写在url地址中,以key=value的形式

举个列子,我们使用一个form表单传递数据给另一个页面,在另一页面的参数形式应该是 /当前路由的路径?email='xxx' & password='xxxx',如果我们想要获取当前页面的路由信息,我们可以使用this.$route.query 获取当前页面的路由信息和参数,在this.route.query里面有一个属性 fullPath 他可以获取到一个当前页面的路由和传递参数,path只能获取当前页面的路由

query传递参数的实例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .style1{
            background-color: #0bb20c;
            color: white;
            padding: 15px;
            margin:15px 0;
        }
        .main{
            padding: 10px;
        }
    </style>
</head>

<body>
    <div id="app">
        <div class="style1">
            <!-- 默认的视图 -->
            <router-view></router-view>
        </div>
        <div class="main">
            <router-view name="main"></router-view>
        </div>
    </div>
    <template id="sidebar">
        <div>
            <ul>
                <router-link v-for="(item,index) in menu" :key="index" :to={item.url} tag='li'>
                    {{item.name}}
                </router-link>
            </ul>
        </div>
    </template>
    <template id="main">
        <div>
            <router-view></router-view>
        </div>
    </template>
    <template id="form">
        <div>
            <form >
                <div>
                    <label for="exampleInputEmail">邮箱</label>
                    <input 
                    type="email" 
                    id="exampleInputEmail" 
                    placeholder="请输入你的邮箱" 
                    v-model="email"
                    >
                </div>
                <div>
                    <label for="exampleInputPassword">密码</label>
                    <input 
                    type="password"  
                    id="exampleInputPassword" 
                    placeholder="请输入密码" 
                    v-model="password"
                    >
                </div>
                <button type="submit" @click="submit">提交</button>
            </form>
        </div>
    </template>
    <template id="info">
            <div class="card" style="margin-top:5px;">
                <div class="card-header">
                    输入的信息
                </div>
                <div class="card-body">
                    <blockquote class="blockquote mb-0">
                        <p>邮箱:{{$route.query.email}}</p>
                        <p>密码:{{$route.query.password}}</p>
                        
                    </blockquote>
                </div>
            </div>
    </template>
    <script src="../vue-router-dev/dist/vue-router.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        Vue.use(VueRouter)
        //1.定义组件跳转的组件模板
        const header = {
            template:`<div class="header">头部</div>`
        }
        const sidebar = {
            template:'#sidebar',
            data(){
                return {
                    menu:[
                        {
                            name:'Form',
                            url:'/form'
                        },
                        {
                            name:'Info',
                            url:'/info'
                        }
                    ]
                }
            }
        }
        const main = {
            template:`#main`
        }
        const form = {
            template:'#form',
            data(){
                return{
                    email:'',
                    password:''
                }
            },
            methods:{
                submit(){
                    this.$router.push({
                        path:'/info?email='+this.email+'&password='+this.password
                    })
                }
            },
        }
        const info = {
            template:`#info`
        }
        //2定义路由的信息
        const routes = [{
            path:'/',
            components:{
                default:header,
                sidebar:sidebar,
                main:main
            },
            children:[
                {
                    path:'',
                    redirect:'form'
                },
                {
                    path:'form',
                    component:form
                },
                {
                    path:'info',
                    component:info
                }
            ]
        }]
        //4.实例VueRouter对象
        const router = new VueRouter({
            routes
        })
        //5.将对象挂载到Vue实例对象上
        new Vue({
            el:'#app',
            data(){
                return{

                }
            },
            router,
            mounted() {
                console.log(this.$route);
            },
        })
    </script>
</body>
</html>

param传参:

与query传参的相同点:

param传参和query传参其实相同的,都是通过\(route来获取当前的页面信息,从而在param对象中,通过\)route.param参数名的形式,获取到通过param方式进行传递参数的值。

不同点:

在定义路由信息的时候,需要以占位符(:参数名)的方式将需要传递的参数 指定到路由地址中去

代码如下:

const routes = [{
    path:'/',
    components:{
        default:header,
        sidebar:sidebar,
        main:main
    },
    childern;[
        {
            path:'',
            redirect:'form'
        },
        {
            path:'form',
            name:'form',
            component:form
        },
        { 
            //这里进行了param接收参数
            path:'info/:email/:password',
            name:'info',
            component:info
        }
    ]
}]

我们传递参数的方式有两种

第一种:

this.$router.push({
    name:'info',
    params:{
        email:this.email,
        password:this.password
    }
})

第二种:

this.$router.push({
    path:`/info/${this.emali}/${this.password}`
})

注意:

当我们这里使用this.$router跳转的时候,如果提供了path属性,那么params属性会被忽略,所以我们一般以命名路由的方式跳转,也就是第一种方法

编程式导航:

在使用Vue Router时,我们通常通过router-link标签去生成跳转到指定路由的链接,但是在实际开发中,更多的是通过JavaScript的方式进行跳转,

​ 举个列子,当我们用户调教表单时候,提交成功,返回上一页面,提交失败,留在当前页面,如果我们使用router-link肯定就不好了,所以我们要通过javascript 根据表单返回的状态进行交互

在使用Vue Router实例化对象的时候并且挂载到Vue的实例对象,会自动生成两个对象 this.\(router(路由对象),和this.\)route(当前页面的路由信息),我们可以通过路由对象也就是this.$router实例方法,通过JavaScript代码的方式进行路由之间的跳转,而这就是编程导航。

在Vue Router有三种导航方法:分别为push,replace和go,最常见的是通过在页面上设置router-link标签进行路由地址间的跳转,等同于执行了一次push

push方法:

​ 当需要跳转新页面的时候,可以通过push方法将一条新的路由记录添加到浏览器的history栈中,通过history的特性,从而驱使浏览器页面进行跳转,同时因为在history会话历史中会一直保存这个浏览器记录,所以可以返回上一页面,

在push方法中,参数可以是一个字符串的路径,也可以是一个对象。

第一种:

this.$router.push({
    name:'info',
    params:{
        email:this.email,
        password:this.password
    }
})
//这是第二种
this.$router.push({
    path:`/info/${this.emali}/${this.password}`
})

go方法:

​ 当使用go方法的时候,可以在history的记录中向前或向后退多少步,也就是说通过go方法可以在已经存储的history路由历史中来回跳转。

this.$router.go(1)

replace方法:

使用replace的方法,是替换当前的页面,不会保存上一条的浏览器记录,所以无法通过后退按钮返回上一步的操作

this.$router.replace({
    path:'info'
})

一个小实例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <button @click="handOne">第一页面</button>
        <button @click ="handTwo">第二页面</button>
        <button @click="handThree">第三页面</button>
        <button @click="handFour">第四页面</button>
        <button @click="handFive">第五页面</button>
        <div>
            <router-view></router-view>
        </div>
    </div>
    <template id="one">
        <div>
            <h1>这是第一页面</h1>
        </div>
    </template>
    <template id="two">
        <div>
            <h2>这是第二页面</h2>
        </div>
    </template>
    <template id="three">
        <div>
            <h3>这是第三页面</h3>
        </div>
    </template>
    <template id="four">
        <div>
            <h1>这是第四页面</h1>
        </div>
    </template>
    <template id="five">
        <div>
            <h1>这是第五页面</h1>
        </div>
    </template>
    <script src="../vue-router-dev/dist/vue-router.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        Vue.use(VueRouter)
        //1.创建路由模板
        const one = {
            template:'#one'
        }
        const two = {
            template:'#two'
        }
        const three = {
            template:'#three'
        }
        const four ={
            template:'#four'
        }
        const five = {
            template:'#five'
        }
        //2.配置路由
        const routes = [
            {
                path:'/',
                redirect:'/one'
            },
            {
                path:'/one',
                name:'one',
                component:one,
            },
            {
                path:'/two',
                name:'two',
                component:two
            },
            {
                path:'/three',
                name:'three',
                component:three
            },
            {
                path:'/four',
                name:'four',
                component:four
            },
            {
                path:'/five',
                name:'five',
                component:five
            }
        ]
        //3.实例化VueRouter对象
        const router = new VueRouter({
            routes,
        })
        //4.将对象挂载到Vue实例的对象上去
        new Vue({
            el:'#app',
            data(){
                return{}
            },
            methods: {
                handOne(){
                    this.$router.push({
                        path:'/one'
                    })
                },
                handTwo(){
                    this.$router.push({
                        path:'/two'
                    })
                },
                handThree(){
                    this.$router.push({
                        path:'/three'
                    })
                },
                handFour(){
                    this.$router.push({
                        path:'/four'
                    })
                },
                handFive(){
                    this.$router.push({
                        path:'/five'
                    })
                }
            },
            router
        })
    </script>
</body>
</html>

组件和VueRouter解耦:

标签

评论