Vue基础知识-脚手架开发-Vue Router路由及params、query传参

Vue基础知识-脚手架开发-Vue Router路由及params、query传参

一、项目结构与完整代码

1. 项目目录

src/
├── ***ponents/       # 一般组件(非路由组件)
│   └── Banner.vue    # 页面头部组件
├── pages/            # 路由组件(由Vue Router管理)
│   ├── Student.vue   # 学生组件
│   ├── School.vue    # 学校组件(一级路由容器)
│   ├── News.vue      # 新闻组件(二级路由)
│   ├── Message.vue   # 消息组件(二级路由,query传参)
│   ├── Detail.vue    # 消息详情(三级路由,接收query参数)
│   ├── Message2.vue  # 消息2组件(二级路由,params传参)
│   └── Detail2.vue   # 消息2详情(三级路由,接收params参数)
├── router/           # Vue Router配置目录
│   └── index.js      # 路由规则配置
├── App.vue           # 根组件
└── main.js           # 入口文件

2. 运行效果:

3. 完整代码文件

(1)入口文件:main.js

import Vue from 'vue'

import App from './App.vue'

import VueRouter from 'vue-router'
import router from './router' //自动检索到index.js

Vue.use(VueRouter)

Vue.config.productionTip = false

new Vue({
    render: h => h(App),
    router,
}).$mount('#app')
(2)路由配置:router/index.js
import VueRouter from 'vue-router'

import Student from '../pages/Student' //注意是..
import School from '../pages/School' 
import News from '../pages/News.vue'
import Message from '../pages/Message.vue'
import Detail from '../pages/Detail.vue'
import Message2 from '../pages/Message2.vue'
import Detail2 from '../pages/Detail2.vue'

export default new VueRouter({
    routes:[
        {
            path:'/student',
            ***ponent:Student
        },
        {
            //一级路由/
            path:'/school',
            ***ponent:School,
            //二级路由不用加/
            children:[
                {
                    path:'news',    //表示路径为:/school/news
                    ***ponent:News,
                },
                {
                    //query传参
                    path:'message',
                    ***ponent:Message,
                    children:[
                        {
                            name:'detail',//可以给路由命名并搭配<router-link :to="{name:detail}">而无需指定path
                            path:'detail',
                            ***ponent:Detail
                        }
                    ]
                },
                {
                    //params传参
                    path:'message2',
                    ***ponent:Message2,
                    children:[
                        {
                            name:'detail2',
                            path:'detail2/:id/:title/:content', //resetful风格,使用:来占位
                            ***ponent:Detail2
                        }
                    ]
                }
            ]
        }
    ]
})
(3)根组件:App.vue
<template>
    <div>
    <div class="row">
      <Banner/>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">

         <!--  由router-link帮你转成<a>标签 -->
          <router-link class="list-group-item" active-class="active" to="/student">Student</router-link>
          <router-link class="list-group-item" active-class="active" to="/school">School</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            <!--指定路由展示位置-->
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>

</template>
<!--
    1 路由(route)就是一组key-value
        1 现实中:key相当于路由器的接口,value相当于计算机
        2 Vue中:key为路径,value可能是***ponent组件或function(发请求)
    2 多个路由,需要经过路由器(router)的管理
    vue-router是一个插件库,专门实现spa单页面应用。
    单页面:
        1 整个应用只有一个完整页面(index.html)
        2 点击导航链接不会刷新页面,只做页面局部更新
        3 数据需要通过ajax获取

    使用:
        1 npm install vue-router@3  注意:vue3用vue-router@4;vue2用vue-router@3
        2 Vue.use

    Banner.vue称为一般组件。一般放在***ponents目录
    School.vue和Student.vue由路由器管理切换的组件称为路由组件,一般放在pages目录
        
-->
<script>
    import Banner from './***ponents/Banner.vue';
    export default {
        name:'App',
        ***ponents:{
            Banner
        }
    }
</script>

<style>
   
</style>
(4)一般组件:***ponents/Banner.vue
<template>
    <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header"><h2>Vue Router Demo</h2></div>
    </div>
</template>

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

<style>

</style>
(5)路由组件:pages/Student.vue
<template>
    <div class="demo">
        <h3>{{ name }}</h3>
        
    </div>
</template>
<script>
    export default { 
        name:'Student',
        data(){
            return {
                name:'张三'
            }
        },
       
    }
</script>

<style scoped>
</style>
(6)路由组件:pages/School.vue(一级路由容器)
<template>
    <div class="demo">
        <h3>{{name}}</h3>
        <div>
			<ul class="nav nav-tabs">
				<li>
					<router-link class="list-group-item" active-class="active" to="/school/news">News</router-link>
				</li>
				<li>
					<router-link class="list-group-item" active-class="active" to="/school/message">Message</router-link>
				</li>
                <li>
					<router-link class="list-group-item" active-class="active" to="/school/message2">Message2</router-link>
				</li>
			</ul>
			<router-view></router-view>
		</div>
    </div>
</template>
<script>



    export default {
        name:'School',
        data(){
            return {
                name:'北京大学'
            }
        },
       /* 
        beforeDestroy(){
            //切换组件时,当前组件会被销毁。
            console.log('School即将被销毁')
        } 
        */
        /* 
        mounted(){
            //现在,每个vc都有一个$router和$route。其中,$route存储自己的路由信息。$router都是一样的,一个应用一个
            console.log(this)
        } 
        */
    }
</script>

<style scoped>

</style>
(7)路由组件:pages/News.vue(二级路由)
<template>
	<ul>
		<li>news001</li>
		<li>news002</li>
		<li>news003</li>
	</ul>
</template>

<script>
	export default {
		name:'News'
	}
</script>
(8)路由组件:pages/Message.vue(二级路由,query 传参)
<template>
	<div>
		<ul>
			<li v-for="msg in messages" :key="msg.id">
				<!-- 
				路由的querry传参
					1 在to里面传参数
					2 使用$route.query.xx接受参数
				-->
				<!-- 
				方式1:to的字符串写法。使用:to来解析表达式``
				<router-link :to="`/school/message/detail?id=${msg.id}&title=${msg.title}&content=${msg.content}`">{{msg.title}}</router-link> 
				-->
				<!-- 方式2:to的对象写法(推荐)-->
				<router-link :to="{
					path:'/school/message/detail',
					//name:'detail',可以不使用path,直接使用name来指定路由位置
					query:{
						id:msg.id,
						title:msg.title,
						content:msg.content
					}
				}">{{msg.title}}</router-link>
			</li>
		</ul>
		<router-view></router-view>
	</div>
</template>

<script>
	export default {
		name:'Message',
		data() {
			return {
				messages:[
					{id:'1',title:'标题1',content:'内容1'},
					{id:'2',title:'标题2',content:'内容2'},
					{id:'3',title:'标题3',content:'内容3'},
				]
			}
		},
	}
</script>
(9)路由组件:pages/Detail.vue(三级路由,接收 query 参数)
<template>
    <div>
    
       id:{{ $route.query.id }}
       title:{{ $route.query.title }}
       content:{{ $route.query.content }}
    </div>
</template>

<script>
export default {
    name:'Detail',
    mounted(){
        console.log(this.$route)
    }
}
</script>

<style>

</style>
(10)路由组件:pages/Message2.vue(二级路由,params 传参)
<template>
	<div>
		<ul>
			<li v-for="msg in messages" :key="msg.id">
				<!-- 
				路由的params传参(restful风格)
					1 在to里面传参数
					2 使用$route.params.xx接受参数
				-->
				<!-- 
				方式1:to的字符串写法。使用:to来解析表达式``
				<router-link :to="`/school/message2/detail2/${msg.id}/${msg.title}/${msg.content}`">{{msg.title}}</router-link> 
				-->
				<!-- 方式2:to的对象写法(推荐)-->
				 <router-link :to="{
					//注意这里必须使用name不能指定path:/school/message2/detail2
					//原因:path的语义是 “明确指定最终URL路径”,而params的语义是 “为路由规则中的动态片段传值”。若写path会直接跳到path使params无效。
					name:'detail2',
					params:{
						id:msg.id,
						title:msg.title,
						content:msg.content
					}
				}">{{msg.title}}</router-link> 
			</li>
		</ul>
		<router-view></router-view>
	</div>
</template>

<script>
	export default {
		name:'Message2',
		data() {
			return {
				messages:[
					{id:'1',title:'标题1',content:'内容1'},
					{id:'2',title:'标题2',content:'内容2'},
					{id:'3',title:'标题3',content:'内容3'},
				]
			}
		},
	}
</script>
(11)路由组件:pages/Detail2.vue(三级路由,接收 params 参数)
<template>
    <div>
    
       id:{{ $route.params.id }}
       title:{{ $route.params.title }}
       content:{{ $route.params.content }}
    </div>
</template>

<script>
export default {
    name:'Detail2',
    mounted(){
        console.log(this.$route)
    }
}
</script>
 
<style>
    
</style>

二、核心知识点解析

1. 环境准备:Vue2 与 Vue Router 版本对应

Vue Router 版本与 Vue 版本强相关,必须匹配:

  • Vue2 → Vue Router3(安装命令:npm install vue-router@3
  • Vue3 → Vue Router4(安装命令:npm install vue-router@4

版本不匹配会导致语法错误(如 Vue2 用 Vue Router4 会报export 'createRouter' was not found)。

2. 路由配置关键规则

(1)一级路由 vs 二级路由
  • 一级路由:path/开头(如/student/school);
  • 二级路由:path不加/,自动拼接父路由path(如父路由/school + 子路由news → 完整路径/school/news);
  • 路由容器:需在父组件中添加<router-view>,用于渲染子路由组件(如School.vue中包含<router-view>渲染二级路由)。
(2)路由命名(name属性)
  • 作用:给路由起一个唯一标识,可替代path用于跳转(尤其适合params传参);
  • 优势:当路由path修改时,无需修改所有跳转代码(只需保证name不变)。

3. query 传参:URL 查询串方式

(1)核心特点
  • URL 显示:参数以?id=xxx&title=xxx形式附加在 URL 后(如/school/message/detail?id=1&title=消息1);
  • 路由配置:无需特殊配置(不需要动态占位符);
  • 参数接收:通过this.$route.query.参数名获取;
  • 参数缺省:支持缺省参数(如只传id,不传title,不会导致路由匹配失败)。
(2)跳转写法对比
写法 示例代码 特点
字符串写法 :to="/school/message/detail?id={msg.id}&title={msg.title}" 直观,但拼接复杂
对象写法 :to="{ path: '/school/message/detail', query: { id: msg.id } }" 清晰,推荐使用

4. params 传参:动态路由方式

(1)核心特点
  • URL 显示:参数嵌入 URL 路径中(如/school/message2/detail2/1/消息1/内容1);
  • 路由配置:必须定义动态占位符(path: 'detail2/:id/:title/:content':后为参数名);
  • 参数接收:通过this.$route.params.参数名获取;
  • 参数缺省:不支持缺省(未传参数会导致路由匹配失败,返回 404)。
(2)跳转写法关键注意点
  • 必须用name,不能用path
    原因:path的语义是 “明确指定最终 URL 路径”,而params是 “为动态占位符传值”。若用path,Vue Router 会直接按path跳转,忽略params(导致参数丢失)。
    错误写法::to="{ path: '/school/message2/detail2', params: { id: msg.id } }"params无效);
    正确写法::to="{ name: 'detail2', params: { id: msg.id } }"(通过name关联路由规则,自动填充动态占位符)。

5. query 与 params 传参对比

对比维度 query 传参 params 传参
URL 显示 显式查询串(?key=value) 隐式路径嵌入(/key/value)
路由配置 无需动态占位符 必须定义动态占位符(:key)
跳转方式 支持 path 或 name 仅支持 name(不能用 path)
参数缺省 支持(缺省不影响路由匹配) 不支持(缺省导致 404)
刷新页面 参数不丢失(URL 中可见) 参数不丢失(URL 中可见)
适用场景 非必填参数(如列表筛选、搜索) 必填参数(如详情页 ID、唯一标识)

三、常见问题与解决方案

  1. 跳转后参数无法获取?

    • 检查是否混淆$router$route$router是路由实例(用于跳转),$route是当前路由信息(用于获取参数);
    • params 传参需确认路由配置是否有动态占位符,且跳转时用name
  2. params 传参用 path 导致参数丢失?

    • 牢记:params 传参必须用name,删除path配置,改用路由命名跳转。
  3. 二级路由跳转 404?

    • 检查二级路由path是否加了/:二级路由path不加/,否则会被解析为一级路由(如path: '/news'会被解析为/news,而非/school/news)。

四、总结

本文通过完整案例讲解了 Vue Router2 中两种核心传参方式:

  • query 传参:适合非必填参数,URL 显式,配置简单;
  • params 传参:适合必填参数,URL 美观,需动态路由配置。
转载请说明出处内容投诉
CSS教程网 » Vue基础知识-脚手架开发-Vue Router路由及params、query传参

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买