Vue2路由知识大杂烩, 一下给你全整明白(中)https://blog.csdn.net/weixin_48524561/article/details/125625003
Vue2路由知识大杂烩, 一下给你全整明白(下)https://blog.csdn.net/weixin_48524561/article/details/125636588
现在就来讲解一下在vue中非常重要的一个技术, 也就是路由; 只要是使用vue书写的项目必定会涉及到路由的问题.
从生活中出发, 我们说路由首先会想到路由器.
生活中的路由器可以让多台设备同时上网, 也就是说每一个接口都会对应着一个设备; 一个接口对应一个接口.
路由就是一组key-value的对应关系, 多个路由(多组对应关系route)就需要被路由器所管理router.
生活中的路由是为了能够上完, 那么代码中路由就是为了spa单页面应用的导航区和展示区的来来回回切换.
在以前的项目都是多页面的应用, 多个页面互相跳转, 不好的就是有抖动; 单页面就是不断的匹配路由, 然后切换显示组件.
router会一直监听的路由变化, 如果路由发送变化就会找到与当前路由匹配的组件显示到页面, 这就是路由的整个流程.
1. 注册router:
想要将router挂载到vue实例上面, 我们就得借助到vue-router这个插件库了(npm i vue-router或yarn add vue-router).
但是现在推出了vue-router 4 的版本, 它只服务于vue3. 3的版本是服务于vue2的, 所以就得指定版本下载npm i vue-router@3.
// 第一步, 导入Vue, 后面将vue-router注册插件
import Vue from 'vue'
// 第二步, 导入VueRouter构造器
import VueRouter from 'vue-router'
// 第三步, 将路由插件库注册
Vue.use(VueRouter)
// 第四步, 使用VueRouter创建实例对象
const router = new VueRouter({
// 第五步, 创建路由规则
routes: [
{
path: '/home',
component: () => import('@/views/HomeView')
},
{
path: '/about',
component: () => import('@/views/AboutView')
}
]
})
// 第六步, 将路由实例导出
export default router
import Vue from 'vue'
import App from './App.vue'
import store from './store'
// 第七步, 将路由实例导入
import router from './router/index.js'
Vue.config.productionTip = false
new Vue({
// 第八步, 将路由实例挂载到Vue的实例上面
router,
store,
render: h => h(App)
}).$mount('#app')
<template>
<div id="app">
<nav>
<!-- 第十步, 设置链接 -->
<router-link to="/home">home</router-link> |
<router-link to="/about">about</router-link>
</nav>
<!-- 第九步, 设置路由出口 -->
<router-view></router-view>
</div>
</template>
<style lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>
注意点:
- home组件和about组件, 我们并没有这样使用<home />和<about />
- 这两个组件是通过router对路由进行检测而进行路由匹配自动切换的组件
- 我管这样的组件叫做路由组件, 我们通常将路由组件放在views或pages文件夹中
- 然而自己手动<组件名 />这样的组件我们叫做一般组件
- 在实际开发中, 我们都会将路由组件和一般组件进行区分管理, 会将一般组件放在component文件中
- 一般组件又分为全局组件和局部组件, 局部组件会在当前的父文件家中创建component文件夹, 人后将其放入
那我们再思考一个问题, 现在路由匹配规则匹配的组件是about组件; 那home组件去哪了?
我们home组件被效果了, 上代码:
<template>
<h3>home</h3>
</template>
<script>
export default {
name: 'HomeCom',
beforeDestroy () {
console.log('home组件即将被销毁')
},
mounted () {
console.log('home组件挂载完毕')
}
}
</script>
<template>
<h3>
about
</h3>
</template>
<script>
export default {
name: 'AboutCom',
beforeDestroy () {
console.log('about组件即将被销毁')
},
mounted () {
console.log('about组件挂载完毕')
}
}
</script>
这里我们再抛出一个面试题:
router和route区别在哪?
- 简单的来说route就是当前跳转的路由对象, router是VueRouter的实例对象
2. 嵌套路由:
嵌套路由我们也可以称之为多级路由, 我们需要在一级路由中设置一个属性"children", 它得是一个数组. 因为一个一级路由可以有n多个二级路由, 以数组包对象的形式.
// 第一步, 导入Vue, 后面将vue-router注册插件
import Vue from 'vue'
// 第二步, 导入VueRouter构造器
import VueRouter from 'vue-router'
// 第三步, 将路由插件库注册
Vue.use(VueRouter)
// 第四步, 使用VueRouter创建实例对象
const router = new VueRouter({
// 第五步, 创建路由规则
routes: [
{
path: '/home',
component: () => import('@/views/HomeView'),
// children得是一个数组, 因为一个一级路由可以有n多个二级路由
children: [
{
path: 'secondone',
component: () => import('@/views/Second_one')
},
{
path: '/secondtwo',
component: () => import('@/views/Second_two')
}
]
},
{
path: '/about',
component: () => import('@/views/AboutView')
}
]
})
// 第六步, 将路由实例导出
export default router
<template>
<div>
<h3>home</h3>
<!-- 在书写二级路由的路径的时候, 需要加上一级路由的路径 -->
<router-link to="/home/secondone">第一个子组件</router-link> |
<router-link to="/home/secondtwo">第二个子组件</router-link>
<!-- 当然二级路由也需要设置路由出口, 我们将这个出口称为二级路由出口 -->
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'HomeCom'
}
</script>
<style>
</style>
注意:
- 子路由的path路径的前面最好不要加"/", 因为路由在遍历子路由的时候, 会在路径前面自动加上'"/".
3. 路由传参(query):
query传参的方法是在路径后面以"?"进行拼接, 以键值对的形式显示在地址栏, 比如搜索引擎的搜索.
- 这是一个字符串拼接的方法, 此方法不便于阅读, 看上去很费劲
<template>
<div>
<h3>我是第三个页面</h3>
<template v-for="item in threeList">
<router-link :to="`/one/three/threeDetail?id=${item.id}&name=${item.name}`" :key="item.id">第三个页面的第{{ item.id }}个详情页</router-link> 
</template>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'ThreeCom',
data () {
return {
threeList: [
{ id: 1, name: '大帅' },
{ id: 2, name: '张三' },
{ id: 3, name: '李四' }
]
}
}
}
</script>
<style>
</style>
<template>
<div>
<h3>我是第三个页面</h3>
<template v-for="item in threeList">
<router-link :to="{
path: '/one/three/threeDetail',
query: {
id: item.id,
name: item.name
}
}" :key="item.id">我是第三个页面的第{{ item.id }}个详情页面</router-link> 
</template>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'ThreeCom',
data () {
return {
threeList: [
{ id: 1, name: '大帅' },
{ id: 2, name: '张三' },
{ id: 3, name: '李四' }
]
}
}
}
</script>
<style>
</style>
- 其实router-link还有一个对象的写法
<template>
<div>
<h3>我是第三个页面</h3>
<template v-for="item in threeList">
<router-link :to="{
path: '/one/three/threeDetail',
query: {
id: item.id,
name: item.name
}
}" :key="item.id">我是第三个页面的详情页面</router-link> 
</template>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'ThreeCom',
data () {
return {
threeList: [
{ id: 1, name: '大帅' },
{ id: 2, name: '张三' },
{ id: 3, name: '李四' }
]
}
}
}
</script>
<style>
</style>
4. 命名路由:
顾名思义就是跟你的路由起一个规则, 想给路由起个名字非常简单, 直接配置一个name属性, 它是一个字符串.
它的作用就是可以简化一些编码. 比如, 如果router-link中to属性的值太多的话, 我们可以直接使用name代替. 来上代码:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
routes: [
{
path: '/one',
name: 'OneCom',
component: () => import('@/pages/One.vue'),
children: [
{
path: 'three',
name: 'ThreeCom',
component: () => import('@/pages/Three.vue'),
children: [
{
path: 'threeDetail',
name: 'ThreeDetail',
component: () => import('@/pages/ThreeDetail')
}
]
},
{
path: 'four',
name: 'FourCom',
component: () => import('@/pages/Four.vue')
}
]
},
{
path: '/two',
name: 'TwoCom',
component: () => import('@/pages/Two.vue')
}
]
})
export default router
- 我们直接这样写to="FourCom"是无效的, 浏览器会把它当做path来进行解析
- 所以必须得使用键值对的方法书写, 且加上v-bind
<template>
<div>
<h3>我是第一个页面</h3>
<router-link to="/one/three">第三个页面</router-link> |
<router-link :to="{name: 'FourCom'}">第四个页面</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'OneCom'
}
</script>
<style>
</style>
- 如果to属性的属性值是以对象的显示存在的, 我们就需要将path替换成name
<template>
<div>
<h3>我是第三个页面</h3>
<template v-for="item in threeList">
<router-link :to="{
name: 'ThreeDetail',
query: {
id: item.id,
name: item.name
}
}" :key="item.id">我是第三个页面的第{{ item.id }}个详情页面</router-link> 
</template>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'ThreeCom',
data () {
return {
threeList: [
{ id: 1, name: '大帅' },
{ id: 2, name: '张三' },
{ id: 3, name: '李四' }
]
}
}
}
</script>
<style>
</style>
5. 路由params传参:
- 上述query传参方式是在路径后面用"?"键值对的方法进行拼接: localhost:8080?id=1&name=大帅.
- 这里params传参的形式就是在路径后面以"/"进行拼接: localhost:8080/1/大帅.
- query传参更适合于关键字的搜索, 如: 搜索引擎.
- params传参更适合于详情页面的查询, 如: 一个新闻页面点击新闻, 通过id跳转到详情页面.
{
path: 'four',
name: 'FourCom',
component: () => import('@/pages/Four.vue'),
children: [
{
// params传参需要对路由匹配规则进行配置一下
path: 'fourDetail/:id/:name',
name: 'FourDetail',
component: () => import('@/pages/FourDetail.vue')
}
]
}
- 我们需要先对路由匹配规则做配合, 通常称之为占位符
<template>
<div>
<h3>我是第四个页面</h3>
<router-link to="/one/four/fourDetail/1/大帅">第四个页面的详情页</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'FourCom'
}
</script>
<style>
</style>
- 当然params传参也是可以使用对象的方式表示的, 上代码:
<template>
<div>
<h3>我是第四个页面</h3>
<router-link :to="{
name: 'FourDetail',
params: {
id: 1,
name: '大帅'
}
}">第四个页面的详情页</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'FourCom'
}
</script>
<style>
</style>
注意:
- 如果是params传参且使用对象的显示传递, 就不能使用path属性书写地址.
- 而是使用name属性书写地址, 不然浏览器是不认的.
演示一下, 将name改为path:
<template>
<div>
<h3>我是第四个页面</h3>
<!-- <router-link to="/one/four/fourDetail/1/大帅">第四个页面的详情页</router-link> -->
<router-link :to="{
path: 'FourDetail',
params: {
id: 1,
name: '大帅'
}
}">第四个页面的详情页</router-link>
<router-view></router-view>
</div>
</template>