Vue基础知识-脚手架开发-Vue Router路由及params、query传参
一、项目结构与完整代码
1. 项目目录
src/
├── components/ # 一般组件(非路由组件)
│ └── 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.jsVue.use(VueRouter)Vue.config.productionTip = falsenew 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',component:Student},{//一级路由/path:'/school',component:School,//二级路由不用加/children:[{path:'news', //表示路径为:/school/newscomponent:News,},{//query传参path:'message',component:Message,children:[{name:'detail',//可以给路由命名并搭配<router-link :to="{name:detail}">而无需指定pathpath:'detail',component:Detail}]},{//params传参path:'message2',component:Message2,children:[{name:'detail2',path:'detail2/:id/:title/:content', //resetful风格,使用:来占位component: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-value1 现实中:key相当于路由器的接口,value相当于计算机2 Vue中:key为路径,value可能是component组件或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@32 Vue.useBanner.vue称为一般组件。一般放在components目录School.vue和Student.vue由路由器管理切换的组件称为路由组件,一般放在pages目录-->
<script>import Banner from './components/Banner.vue';export default {name:'App',components:{Banner}}
</script><style></style>
(4)一般组件:components/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、唯一标识) |
三、常见问题与解决方案
跳转后参数无法获取?
- 检查是否混淆
$router
与$route
:$router
是路由实例(用于跳转),$route
是当前路由信息(用于获取参数); - params 传参需确认路由配置是否有动态占位符,且跳转时用
name
。
- 检查是否混淆
params 传参用 path 导致参数丢失?
- 牢记:params 传参必须用
name
,删除path
配置,改用路由命名跳转。
- 牢记:params 传参必须用
二级路由跳转 404?
- 检查二级路由
path
是否加了/
:二级路由path
不加/
,否则会被解析为一级路由(如path: '/news'
会被解析为/news
,而非/school/news
)。
- 检查二级路由
四、总结
本文通过完整案例讲解了 Vue Router2 中两种核心传参方式:
- query 传参:适合非必填参数,URL 显式,配置简单;
- params 传参:适合必填参数,URL 美观,需动态路由配置。