Vue-router路由基础内容讲解

一、什么是Vue-router

Vue-router是Vue.js的官方路由。它与Vue.js核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。它是Vue.js 的一个插件库,专门用来实现SPA 应用。

SPA

单页 Web 应用(single page web application,SPA),整个应用只有一个完整的页面,点击页面中的导航链接不会刷新页面,只会做页面的局部更新,数据需要通过ajax请求获取。

 路由

一个路由就是一组映射关系,路由分为前端路由和后端路由。路由的工作过程,当浏览器路径改变时,展示其对应的路由组件。

二、路由的基本使用

安装

npm

npm i vue-router@4

yarn

yarn add vue-router@4

 注:vue2请安装vue-router@3,vue3安装其对应的vue-router@4,本篇使用Vue2实现路由。


配置路由

  1.  创建文件夹store,再其创建index.js文件,用于配置路由

  2. 一般来说,components文件主要用来存放一般组件,即未参与路由使用的组件,新建文件夹pages用于专门存放路由组件,使其文件脉络清晰。

index.js

// 该文件用于创建整个应用的路由器
import VueRouter from 'vue-router'
 
// 引入对应的路由组件
import About from '../pages/About'
import Home from '../pages/Home'

// 创建并暴露一个路由器
export default new VueRouter({
    routes: [{
        // 路径
        path: '/about',
        // 路由组件名
        component: About
    },
    {
        path: '/home',
        component: Home
    }]
})

main.js

// 引入vue
import Vue from 'vue'
import App from './App.vue'
// 引入路由
import VueRouter from 'vue-router'
import router from './router'

Vue.config.productionTip = false

// 使用路由,路由是Vue.js的一个插件库
Vue.use(VueRouter)

const vm = new Vue({
    el: '#app',
    render: h => h(App),
    // 创建路由配置项
    router,
})

使用路由

App.vue

<template>
	<div>
		<!-- Vue中借助router-link标签实现路由的切换 类似于a标签 -->
        <!-- active-class="active" 用来做选中时的样式切换 -->
		<router-link active-class="active" to="/about">
            About
    	</router-link>
		<router-link active-class="active" to="/home">
            Home
    	</router-link>
		<div>
			<!-- 指定组件的呈现位置 -->
            <!-- Home以及About组件的内容,将于此处展示 -->
			<router-view></router-view>
		</div>
	</div>
</template>


<script>
    export default {
        name: 'App',
    }
</script>

注:每个路由都有自己的$route属性,用于存放该路由的基本信息,而整个文件则存在一个$router属性,可以获得其他route的基本信息。通过切换路由组件隐藏时,默认是销毁了该路由组件,显示时则是重新挂载该路由组件。


三、多级路由

多级路由实为路由之间的嵌套。在路由的基本使用中,我们注册了Home和About路由组件,当在App组件中使用切换路由选项,则是将对应的路由显示在App.vue中的<router-view>标签中。现在我们同样创建两个组件,名为News和Message,并为其注册为路由组件,当在Home组件使用切换路由选项时,则是将对应的路由显示在Home.vue中的<router-view>标签中。

index.js

// 该文件用于创建整个应用的路由器
import VueRouter from 'vue-router'
 
// 引入路由组件,Message和News为我们新引入的路由组件
import About from '../pages/About'
import Home from '../pages/Home'
import Message from '../pages/Message'
import News from '../pages/News'
// 创建并暴露一个路由器
export default new VueRouter({
    routes: [{
        path: '/about',
        component: About
    },
    {
        path: '/home',
        component: Home,
        // 在Home路由配置项中,配置其子路由,使用children配置项
        // 并且path路径不需要/开头
        children: [{
            path: 'message',
            component: Message
        },
        {
            path: 'news',
            component: News
        }]
    }]
})

Home.vue

<template>
    <div>
        <h2>Home组件内容</h2>
        <!-- 用于切换路由组件,并选中用于展示的路由组件 -->
        <div>
            <ul>
                <li>
                    <router-link active-class="active" to="/home/news">
                        News
                    </router-link>
                </li>
                <li>
                    <router-link active-class="active" to="/home/message">    
                        Message                        
                    </router-link>
                </li>
            </ul>
            <!-- 在原先基础上新增<router-view>用于展示被选中的路由内容 -->
            <router-view></router-view>
        </div>
    </div>
</template>

<script>
    export default {
        name: 'Home',
    }
</script>

注:路由跳转的路径要写完整(/home/news),如只写(/news)为错误写法。配置路由规则,应使用children配置项。


四、query参数

现在我们在新配置一个路由组件,名为Details。并在Message中嵌套该路由组件,并传入data参数,现将Message中的data数据传到Details中,Details读取数据,并且当Message切换路由时,Details将对应数据展示到Message组件的<router-view>标签中。在路由中我们通过query实现数据传递。

index.js

// 该文件用于创建整个应用的路由器
import VueRouter from 'vue-router'
 
import About from '../pages/About'
import Home from '../pages/Home'
import Message from '../pages/Message'
import News from '../pages/News'
import Detail from '../pages/Detail'
// 创建并暴露一个路由器
export default new VueRouter({
    routes: [{
        path: '/about',
        component: About
    },
    {
        path: '/home',
        component: Home,
        children: [{
            path: 'message',
            component: Message,
            // 在Home路由下的Message路由中配置子路由Details,也应使用children配置项
            children: [{
                path: 'detail',
                component: Detail
            }]
        },
        {
            path: 'news',
            component: News
        }]
    }]
})

Message.vue

<template>
    <div>
        <ul>
            
            <li v-for="m in messageList" :key="m.id">
                <!-- 跳转路由并携带query参数,to的字符串写法 -->
                <!-- <router-link 
                    :to="`/home/message/detail?                            
                    id=${m.id}&title=${m.title}`">
                    {{m.title}}
                </router-link> -->
                <!-- 跳转路由并携带query参数,to的对象写法 -->
                <router-link :to="{
                path:'/home/message/detail',
                query:{
                    id:m.id,
                    title:m.title
                }
            }">
                {{m.title}}
            </router-link>
            </li>   
        </ul>
        <!-- 对应的Details路由组件将展示于此标签中 -->
        <router-view></router-view>
    </div>
</template>

<script>
    export default {
        name: 'Message',
        // 在data中设置一个messageList数组对象
        data() {
            return {
                messageList: [
                    {id:'001',title:'a'},
                    {id:'002',title:'b'},
                    {id:'003',title:'c'}
                ]
            }
        },
    }
</script>

Details.vue

<template>
    <ul>
        <!-- 使用$route.query读取数据 -->
        <li>消息编号:{{$route.query.id}}</li>
        <li>消息名称:{{$route.query.title}}</li>
    </ul>
</template>

<script>
    export default {
        name: 'Detail',

    }
</script>

五、命名路由

简化可以简化路由的跳转,我们可以在配置路由中,增加一个name配置项。

export default new VueRouter({
    routes: [{
        // 命名路由
        name: 'guanyu',
        path: '/about',
        component: About
    },

})
<template>
	<div>
        <!-- 指定组件的呈现位置 -->
        <!-- 通过name配置项跳转路由,通常使用于多级路由,用于简化跳转路由路径 -->
		<router-link active-class="active" :to"{name:'guanyu'}">
            About
    	</router-link>
		<router-link active-class="active" to="/home">
            Home
    	</router-link>
		<div>
			<router-view></router-view>
		</div>
	</div>
</template>


<script>
    export default {
        name: 'App',
    }
</script>

六、params参数

该参数与query参数作用一样,都是为了传递数据使用。

index.js

export default new VueRouter({
    routes: [
    {
        path: '/home',
        component: Home,
        children: [{
            path: 'message',
            component: Message,
            children: [{
                // 命名路由
                name: 'xiangqing',
                // 表明在
                path: 'detail/:id/:title',
                component: Detail
            }]
        }]
    }]
})

Message.vue 

<template>
    <div>
        <ul>
            <!-- 跳转路由并携带params参数,to的字符串写法 -->
            <li v-for="m in messageList" :key="m.id">
                  :to="`/home/message/detail/id=${m.id}/&title=${m.title}`">                                
                  {{m.title}}
            </router-link>
                <!-- 跳转路由并携带params参数,to的对象写法 -->
                <!-- <router-link :to="{
                    name: 'xiangqing',
                    <!-- 如果使用params传递参数,不可以使用path配置项,只能用name -->
                    params:{
                        id:m.id,
                        title:m.title
                    }
                }">
                    {{m.title}}
                </router-link> -->
            </li>
    
        </ul>
        <router-view></router-view>
    </div>
</template>

Details.vue

<template>
    <ul>
        <!-- 使用$route.params读取数据 -->
        <li>消息编号:{{$route.params.id}}</li>
        <li>消息名称:{{$route.params.title}}</li>
    </ul>
</template>

<script>
    export default {
        name: 'Detail',

    }
</script>

注:使用params参数传参,必须使用name配置项,而不是path。


七、路由的props配置

路由的props配置让路由更方便的接收到参数。

// props第一种写法,值为对象,该对象中的所有key-value的形式传给组件
// 使用该方式传递数据,数据单一
props: {a:1,b:'hello'}
// props第二种写法,值为布尔值,若布尔值为真,就会把该路由组件接收到的params参数,
// 以props的形式传给组件
props: true
// 第三种写法,值为函数,使用该方法更加灵活,可读取$route中的数据
props($route) {
    return {id:$route.params.id,title:$route.params.title}
}

// 亦可传递query中的数据
props($route) {
    return {id:$route.query.id,title:$route.query.title}
}
<!-- Details组件中,可以接收到上述三种方式传递的数据 -->
<!-- 在配置项props中接收 -->
<template>
    <ul>
        <li>消息编号:{{id}}</li>
        <li>消息名称:{{title}}</li>
    </ul>
</template>

<script>
    export default {
        name: 'Detail',
        props: ['id','title']
    }
</script>

八、replace和push属性 

<router-link>标签中有replace和push两个属性,在官方文档中是这样解释的:push,通过在历史堆栈中推送一个 entry,以编程方式导航到一个新的 URL;replace,通过替换历史堆栈中的当前 entry,以编程方式导航到一个新的 URL。简单来说就是使用push属性,我们可以通过浏览器单击以返回按钮,即左上角向左箭头返回上一步,以及单机以继续按钮返回下一步操作。而使用replace属性则是无法返回到使用该属性的路由组件。<router-link>标签默认值为push属性。

<!-- 开启replace属性 -->
<router-link replace>News</router-link>

九、编程式路由导航

我们之前都是借助<router-link>标签,实现路由的跳转,该标签与a标签形式类似,但如果我们想让其他标签如button标签实现路由跳转,那使用<router-link>则做不到。我们借助编程式路由导航,使路由跳转更加灵活。

<template>
    <div>
        <ul>
            <li v-for="m in messageList" :key="m.id">
            <button @click="pushShow(m)">push一下</button>
            <button @click="replaceShow(m)">replace一下</button>
            </li>
        </ul>
        <router-view></router-view>
    </div>
</template>

<script>
    export default {
        name: 'Message',
        data() {
            return {
                messageList: [
                    {id:'001',title:'a'},
                    {id:'002',title:'b'},
                    {id:'003',title:'c'}
                ]
            }
        },
        methods: {
            pushShow(m) {
                this.$router.push({
                    name: 'xiangqing',
                    params:{
                        id:m.id,
                        title:m.title
                    }
                })
            },
            replaceShow(m) {
                this.$router.replace({
                    name: 'xiangqing',
                    params:{
                        id:m.id,
                        title:m.title
                    }
                })
            }
        }
    }
</script>

 我们创建两个button,通过这两个按钮来实现路由的切换以及路由的跳转,首先我们分别给两个路由设置点击事件,事件名称后的(m)为传递m参数。其次编写这两个点击事件的方法,通过$router中的push和replace属性(与上述原理一样)实现路由跳转。

十、缓存路由组件

通过第二点路由的基本使用可知,当路由进行切换时,被隐藏的那个路由组件实际是被销毁了,而展示路由组件则是被重新挂载,这就导致当我们某个路由组件存在输入数据时,由于切换路由,导致该路由组件被销毁,输入数据与之销毁。因此当我们切换路由时不该销毁该路由,而是通过缓存保持路由的挂载状态,切换路由时,输入数据仍然保留。

<keep-alive include="News,Message">
    <router-view></router-view>
</keep-alive>>

通过使用keep-alive标签将router-view标签进行包裹,若没有特别指示,则是将所有在这展示的路由进行缓存,如仅想指定个别路由进行缓存,则通过include属性,添加需要进行缓存的路由组件名,若需要多个路由进行缓存,仅需使用逗号分隔开。

十一、路由守卫

。。。

十二、两个生命周期钩子

路由组件所独有的两个生命周期钩子,用于捕获路由组件的激活状态。activated:路由组件被激活时触发,deactivated:路由组件失活时触发。

activated():在vue对象存活的情况下,进入当前存在activated()函数的页面时,一进入页面就触发;可用于初始化页面数据、keepalive缓存组件后,可执行方法。

deactivated():离开组件时执行。

注:activated()和deactivated()只有在<keep-alive>标签包裹的时候才有效

十三、路由器的两种工作模式

路由器中有两种工作模式hush和history。hash模式:它在内部传递的实际 URL 之前使用了一个哈希字符(#);history模式:用于路由实现历史记录。

hash模式:

  1. 地址中永远带着#,不美观

  2. 若以后将地址通过第三方手机app分享给,若app校验严格,则地址会被标记为不合法。

  3. 兼容性好

history模式:

  1. 地址干净,美观

  2. 兼容性和hash模式相比略差

  3. 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值