路由器是router , 路由是route。
一个路由就是一组映射关系(key-value形式)。
多页面应用,就是很多个html页面,通过a标签啥的,来回跳转。
单页面应用的好处:
后端路由:
请求路径
对应 要执行的函数(进而返回数据)。
前端路由:
url路径
对应 要显示的组件页面
。vue-router是一个vue的插件库,专门用来实现SPA应用。
2022年2月7日以后,vue-router的默认版本也变为了4版本。并且vue-router4只能用于vue3中。
vue-router3才能在vue2中使用!
因为是vue2项目,所以要执行npm i vue-router@3命令。
main.js文件:
import Vue from "vue"
import App from "./App.vue"
Vue.config.productionTip = false;
//导入vuerouter
import VueRouter from 'vue-router'
//应用VueRouter插件
Vue.use(VueRouter)
//再次提醒./router/index.js的index.js可以省略。
import router from './router'
//之前的应用了vuex的插件,我们就可以在配置项中添加一个store配置项。
//现在引入了VueRouter,我们就可以在配置项中添加一个router配置项。
const vm = new Vue({
el:'#app',
render:h=>h(App),
router:router
})
src/router/index.js文件:
//该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
import About from '../components/About.vue'
import Home from '../components/Home.vue'
//创建一个路由器(管理多个路由规则)
const router = new VueRouter({
routes:[
{
//指定好路径和组件。
path:'/about',
component:About
},
{
path:'/home',
component:Home
},
]
})
//暴露router路由器
export default router
App.vue组件:
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header"><h2>Vue Router Demoh2>div>
div>
div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<router-link class="list-group-item" active-class="active" to="/about">Aboutrouter-link>
<router-link class="list-group-item" active-class="active" to="/home">Homerouter-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>
<script>
export default{
name:'App',
}
script>
测试需要的两个组件:
About.vue组件:
<template>
<h2>我是About内容h2>
template>
<script>
export default {
name:'About'
}
script>
<style>
style>
Home.vue组件:
<template>
<h2>我是Home内容h2>
template>
<script>
export default {
name:'Home'
}
script>
<style>
style>
一般组件 和 路由组件:
开发中,存放组件一般有两个目录:
就是当我们切换组件的显示的时候,不被使用的组件是被隐藏了,还是被销毁了?
可以通过钩子函数,beforeDestroy()或者mounted()钩子函数来验证。
打印当前this组件的时候,我们能够看到一个$route 和 $router:
嵌套路由就是不断的嵌套。
src/router/index.js文件:
//该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
import News from '../pages/News.vue'
import Message from '../pages/Message.vue'
//创建一个路由器(管理多个路由规则)
const router = new VueRouter({
routes:[
//一级路由:一级路由加 ' / '。
{
path:'/about',
component:About
},
{
path:'/home',
component:Home,
children:[
//二级路由:vue会自动添加 ' / '不需要我们添加!!
{
path:'news',
component:News
},
{
path:'message',
component:Message
}
]
},
]
})
//暴露router路由器
export default router
Home.vue文件:
<template>
<div>
<h2>Home组件内容h2>
<div>
<ul class="nav nav-tabs">
<li>
<router-link class="list-group-item" active-class="active" to="/home/news">Newsrouter-link>
li>
<li>
<router-link class="list-group-item" active-class="active" to="/home/message">Messagerouter-link>
li>
ul>
<router-view>router-view>
div>
div>
template>
<script>
export default {
name:'Home',
// mounted() {
// console.log('Home组件挂载完毕。',this)
// },
// beforeDestroy(){
// console.log('Home组件将要被销毁。')
// }
}
script>
<style>
style>
两个嵌套组件:
Message.vue文件:
<template>
<div>
<ul>
<li>
<a href="">message001a>
li>
<li>
<a href="">message001a>
li>
<li>
<a href="">message001a>
li>
ul>
div>
template>
<script>
export default {
name:'Message'
}
script>
News.vue文件:
<template>
<ul>
<li>news001li>
<li>news002li>
<li>news003li>
ul>
template>
<script>
export default {
name:'News'
}
script>
query参数 和 body参数:
get方法只能query参数。
post方法既可以query参数也可以body参数。
简而言之,query参数就是拼接在url后面的表单形式的参数。
Message.vue文件:
<template>
<div>
<ul>
<li v-for="item in messageList" :key="item.id">
<router-link :to="{
path:'/home/message/detail',
query:{
id:item.id,
title:item.title,
}
}">
{{item.title}}
router-link>
li>
ul>
<hr>
<router-view>router-view>
div>
template>
<script>
export default {
name:'Message',
data(){
return {
messageList:[
{id:'001',title:'消息001'},
{id:'002',title:'消息002'},
{id:'003',title:'消息003'},
]
}
}
}
script>
src/router.index.js文件:
//该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
import News from '../pages/News.vue'
import Message from '../pages/Message.vue'
import Detail from '../pages/Detail.vue'
//创建一个路由器(管理多个路由规则)
const router = new VueRouter({
routes:[
//一级路由:一级路由加 ' / '。
{
path:'/about',
component:About
},
{
path:'/home',
component:Home,
children:[
//二级路由:vue会自动添加 ' / '不需要我们添加!!
{
path:'news',
component:News
},
{
path:'message',
component:Message,
children:[
{
path:'detail',
component:Detail,
}
]
}
]
},
]
})
//暴露router路由器
export default router
Detail.vue文件:
<template>
<ul>
<li>消息标号:{{$route.query.id}}li>
<li>消息标题:{{$route.query.title}}li>
ul>
template>
<script>
export default {
name:'Detail',
mounted() {
//打印查看相关信息
// console.log(this.$route)
}
}
script>
<style>
style>
命名路由是为了简化跳转。
{
path:'message',
component:Message,
children:[
{
//设置了name,我们就不用配置全路径,直接在router-link的to属性中配置一个{name:xiangqing}就可以了。
name:'xiangqing',
path:'detail',
component:Detail,
}
]
}
<li v-for="item in messageList" :key="item.id">
<router-link :to="{
name:'xiangqing',
query:{
id:item.id,
title:item.title,
}
}">
{{item.title}}
router-link>
li>
什么是params参数?
当我们查看this.$route中的内容时:
params的对象写法有一个很大的坑:
<router-link :to="{
//只能使用name,不能使用path。
name:'xiangqing',
params:{
id:item.id,
title:item.title,
}
}">
{{item.title}}
router-link>
params参数使用:
{
path:'message',
component:Message,
children:[
{
name:'xiangqing',
//:id和:title 叫做站位符。负责拿到发送过来的params参数。
path:'detail/:id/:title',
component:Detail,
}
]
}
同样params也是有两种写法,字符串写法和对象写法!
<li v-for="item in messageList" :key="item.id">
<router-link :to="`/home/message/detail/${item.id}/${item.title}`">
{{item.title}}
router-link>
<router-link :to="{
//只能使用name,不能使用path。
name:'xiangqing',
params:{
id:item.id,
title:item.title,
}
}">
{{item.title}}
router-link>
li>
自然读取的使用也是直接读取当前组件的$route下的params就可以了。
<ul>
<li>消息标号:{{$route.params.id}}li>
<li>消息标题:{{$route.params.title}}li>
ul>
props的第一种写法:值为对象。(不常用)
children:[
{
name:'xiangqing',
path:'detail/:id/:title',
component:Detail,
/*
props的第一种写法:值为对象。
该对象中的所有的key-value都会以props的形式传给Detail组件。
这种写法因为数据是固定的,所以不常用!
*/
props:{a:1,b:'hello'}
}
]
<template>
<ul>
<li>消息标题:a:{{a}}li>
<li>消息标题:b:{{b}}li>
ul>
template>
<script>
export default {
name:'Detail',
props:['a','b']
}
script>
props的第一种写法:值为布尔值。
children:[
{
name:'xiangqing',
path:'detail/:id/:title',
component:Detail,
/*
props的第一种写法:值为布尔值。
若布尔值为真,就会把该路由组件收到的所有params参数,以props的形式传给对应组件也就是detail组件。
*/
props:true
}
]
<li v-for="item in messageList" :key="item.id">
<router-link :to="{
//只能使用name,不能使用path。
name:'xiangqing',
params:{
id:item.id,
title:item.title,
}
}">
{{item.title}}
router-link>
li>
<template>
<ul>
<li>消息标号:{{id}}li>
<li>消息标题:{{title}}li>
ul>
template>
<script>
export default {
name:'Detail',
props:['id','title']
}
script>
props的第三种写法:值为函数。(推荐)
children:[
{
name:'xiangqing',
path:'detail/:id/:title',
component:Detail,
/*
props的第三种写法:值为函数。
props(){}同样是简写形式。
这个函数式有参数的,传入的参数就是$route!
这样种方式既可以传params又可以传query参数。
props($route){
return {id:$route.params.id,title:$route.params.title}
// return {id:$route.query.id,title:$route.query.title}
}
也可以通过解构赋值来得到简化版本的。
*/
props({query:{id,title}}){
//解构赋值
return {
id,
title
}
}
}
]
浏览器的历史记录操作如下按钮,本质上是一个栈的结构。
栈的replace模式:
router-link最终展示到页面上,就是一个加工后的a标签而已。
但是如果我们想要咋一个按钮或者其他标签上绑定就没办法在使用router-link来实现了。
可以打印一下$router路由器查看一下:
对于编程式路由导航,可以直接通过操作$router路由器
来操作。
对于push模式和replace模式,对浏览器历史记录栈的两个操作:
methods:{
pushShow(item){
// this.$router.push({})操作,会以push模式来进入栈,这样浏览几率读取栈,以push模式读取的。
//并且可以携带参数。
this.$router.push({
name:'xiangqing',
query:{
id:item.id,
title:item.title,
}
})
},
replaceShow(item){
// this.$router.replace({})操作,会以replace模式来进入栈,这样浏览几率读取栈,以replace模式读取的。
this.$router.replace({
name:'xiangqing',
query:{
id:item.id,
title:item.title,
}
})
}
}
<template>
<ul>
<li>消息标号:{{id}}li>
<li>消息标题:{{title}}li>
ul>
template>
<script>
export default {
name:'Detail',
props:['id','title']
}
script>
对路由导航的回退和前进操作:
methods:{
back(){
//对路由导航回退(要注意是push模式还是replace模式。)
this.$router.back()
},
forward(){
//对路由导航前进(要注意是push模式还是replace模式。)
this.$router.forward()
}
}
对于连续向前或向后跳转路由可以使用go函数:
test(){
/*
this.$router.go(n)需要传递参数。
当n为整数的时候,就是连续往前推进n步,路由导航前进三步。
当n为负数的时候,就是连续后退n步,路由导航后退三步。
*/
this.$router.go(-2)
}