路由核心:改变URL路径,但是页面不进行整体刷新
路由可以理解为指向
路由表,是一个映射表,一个路由就是一组映射关系,
key:value key表示路由,value可以为function或者Component
function为后端路由用来处理后端请求
Component(组件)为前端路由用来展示不同内容
安装路由Router并挂载
npm install vue-router@4
可以在任意组件中以 this.$router 的形式访问它,
并且以 this.$route 的形式访问当前路由、
import router from './router'
const app =createApp(App)
app.use(router)
app.mount('#app')
导入的Router index文件
import { createRouter, createWebHashHistory } from 'vue-router'
// 1. 定义路由组件.
// 也可以从其他文件导入
import Home from '../views/Home.vue'
import About from '../views/About.vue'
import Disan from '../views/Disan.vue'
// 2. 定义一些路由
// 每个路由都需要映射到一个组件。
//路径、子组件名
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About },
{ path: '/Disan/:id', component: Disan }
]
// 3. 创建路由实例并传递 `routes` 配置
// 你可以在这里输入更多的配置,但我们在这里
// 暂时保持简单
const router = createRouter({
// 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
history: createWebHashHistory(),
routes, // `routes: routes` 的缩写
})
export default router
用户
app组件
Hello App!
Go to Home
Go to About
Go to Disan
如果动态参数找不到404的话要给一个提示
import News from '../views/News.vue'
// 报错文件
import NotFound from '../views/NotFound.vue'
定义一些路由
const routes = [
{
// 动态路由的参数一定是数字
// 这里注意需要使用两个反斜杠,第一个反斜杠用来转义。所以\\d表示匹配任何一个数字字符。
path: '/News/:id(\\d+)',
// 有多个参数 +
path: '/News/:id+',
// 参数可有可无,参数可以重复叠加
path: '/News/:id*',
// 参数可有可无
path: '/News/:id?',
component: News
// ?与*区别,?后面不可以有多个参数,*可以
},
// 报错文件使用正则来表示。匹配任意的
// 404页面
{ path: '/:path(.*)', component: NotFound },
]
首先把父组件与需要嵌套的子组件引入到index文件。
import { createRouter, createWebHashHistory } from 'vue-router'
import Qiantao from '../views/Qiantao.vue'
import Qiantaoone from '../views/Qiantaoone.vue'
import Qiantaotwo from '../views/Qiantaotwo.vue'
const routes = [
{
path: '/Qiantao',
component: Qiantao,
children:[ //children类似于上面const routes
{
path: 'Qiantaoone',
component: Qiantaoone
},
{
path: 'Qiantaotwo',
component: Qiantaotwo
},
]
在父组件中写入(子组件已写好ol列表与ul列表)
嵌套练习
样式一
样式二
//占位符输出口
$router 相当于全局路由器,可以拿到push,forword ,back,go方法
$route 当前活跃的路由对象
通过$route 来拿到path,params获取参数,query,name
this.$router.push用来跳转页面 。
Page编程式
作用类似于router.push,不同点在于导航不会像 history 添加新记录,
router.push({ path:"/home" , replace: true})
相当于 router.replace({ path:"/home" })
// 替换当前位置
//第一种方式
this.$router.push({path:"/about",query:{name:"zhangsan"},replace:true })
//第二种方式
this.$router.replace({path:"/about",query:{name:"zhangsan"}})
比如有3个页面,主页,页面1(page),页面2(about)
我进入主页然后进入页面1,点击按钮执行上面代码替换为页面2,
点击浏览器左上角的后退,返回到主页面,而不是页面1.
再次点击浏览器左上角前进,返回到页面2。
模板中写入按钮
绑定一个@click事件,执行下列代码
// 前进,传入为正值,后退,传入为负值
methods:{
goBack(){
// 前进,传入为正值,后退,传入为负值
this.$router.go(-2)
// this.$router.back() //等于go(-1),但是不可以传参
//this.$router.forworf() //等于go(1)
}
}
index路由文件中
import News from '../views/News.vue'
const routes = [
{
name:"news",
path: '/News/:id*',
component: News
}
App组件通过path与命名路由
Go to News
Go to News
当我们想要展示多个视图,而不是嵌套展示,就需要命名视图了
index路由中
import ShopTop from '../views/ShopTop.vue'
import ShopMain from '../views/ShopMain.vue'
import ShopFooter from '../views/ShopFooter.vue'
const routes = [{
path:'/Shop',
components:{
default:ShopMain,
// 它们与上的属性匹配
ShopTop:ShopTop,
ShopFooter:ShopFooter
}
}
]
app组件中
例如home页面 path路径为/home 进行跳转,通过重定向可以实现“ / ”达到跳转home页面
index.js路由
const routes = [
{
path: '/' ,
// 重定向
redirect:"/home"
//命名路由
// redirect:{name:'home'}
// 方法
redirect:(to)=>{
console.log(to);
return {name:"home"}
},
{ path: '/home',name:"home", component: Home },
]
当我们的path路径过长等,需要一个或多个别名,多个用数据
path: '/Qiantao',
// alias:'/father',//起别名
alias:["/father","/faqin"],
component: Qiantao,
http://localhost:5173/#/Qiantao
http://localhost:5173/#/father
http://localhost:5173/#/fuqin
结果是一样的
index路由
import Disan from '../views/Disan.vue'
{ path: '/Disan/:id', component: Disan , props: true },
选项式API写法
export default{
props:['id'],
mounted(){
console.log(this.id);
组合式API写法(defineProps({ }))
index路由中需要给每个都要加上props
const router = [{
path:'/Shop/:id',
components:{
default:ShopMain,
// 它们与上的属性匹配
ShopTop:ShopTop,
ShopFooter:ShopFooter
},
props:{default:true,ShopTop:false,ShopFooter:false}
}]
这个时候ShopMain.vue 组件中就可以接受到id值
另外组件接收的话,结果为空,除非index中props修改为ture进行接收
1、Hash模式使用createWebHashHistory()创建的
路径上有一个# 叫做哈希字符
2、HTML5 模式用 createWebHistory()创建的
区别:html5需要后端服务器配置好,不然刷新可能会出现404,
哈希字符不会请求后端。
一个有#号 一个没有
导航守卫主要用于跳转或取消的方式守卫导航,
植入路由导航中:全局、单个路由、组件级。
有3个参数
to 即将要进入的目标
from 当前导航正要离开的路由
next:相当于加了一个关卡,需要调用一下
next()//直接进to 所指路由
next(false) //中断当前路由
next('route') //跳转指定路由
next('error') //跳转错误路由
全局前置路由:
router.beforeEach((to,from,next)=>{
console.log(to);
console.log(from);
next()//通行证
})
{
path: '/about',
component: About,
// 每路守卫(路由独享守卫)
beforeEnter:(to,from,next)=>{//if判断token值
console.log(to);
console.log(from);
if(123===123){
next()
}
}
}
有3个守卫 路由进入组件之前,更新之前,离开之前
beforeRouteEnter(){}
beforeRouteUpdate(){}
beforeRouteLeave(){}
// 注意在 beforeRouteEnter是拿不到this的因为这是在组件创建之前。
//拿不到实例对象,通过next的回调函数来进行获取
export default{
data(){
return{
age:18
}
},
beforeRouteEnter(to,from,next){
console.log("路由进入组件之前");
console.log(to);
console.log(from);
// console.log(age);不能执行
next((vm)=>{
console.log(vm.age);
})
},
beforeRouteUpdate(){
console.log("路由更新组件之前");
},
beforeRouteLeave(){
console.log("路由离开组件之前");
}
}
在项目中一次引入过多,JavaScript包变的特别大.影响页面加载。
让静态导入变成动态导入 需要用到在加载。
静态引入 import Home from '../views/Home.vue'
动态引入 const home = ()=>import('../views/Home.vue')
{
path: '/home',
name:"home",
component: home
}
如果 命名视图的话
想要展示多个视图
// import ShopTop from '../views/ShopTop.vue'
// import ShopMain from '../views/ShopMain.vue'
// import ShopFooter from '../views/ShopFooter.vue'
改为动态
const Top = ()=>import('../views/ShopTop.vue')
const Main = ()=>import('../views/ShopMain.vue')
const Footer = ()=>import('../views/ShopFooter.vue')
const router = {
path:'/Shop/:id',
components:{
default:Main,
// 它们与上的属性匹配
ShopTop:Top,
ShopFooter:Footer
}]