单文件组件
单文件组件:一个文件就是一个组件,都是以.vue结尾的,允许正常的编写html,支持模块化的样式
如果没有单文件组件的话:
1.多个组件写在一个页面中,乱
2.没有html提示,没有语法高亮
3.样式的模块化很明显被遗漏了
vue-router
安装
npm install vue-router
//安装指定版本
npm install vue-router@3.2.0
2.使用步骤
1.引入vue、 vue-router
2.注册VueRouter
3.定义路由配置项
4.创建VueRouter实例,传入配置项
路由的两个核心
(1)定义路由配置项
(2)定义路由视图的显示位置(router-view)
路由的懒加载
component: () => import('../views/About.vue')
关于路径的写法
后面没加后缀的情况:
1.如果当前目录下有demo文件夹,那么是去引入的demo文件夹下的index.js
2.如果不存在demo文件夹,会有选去找当前目录下的demo.vue文件
3.如果不存在.vue文件,那么会优先查找当前目录下的demo.js文件
路径中@代表的是src目录,本质上是因为webpack内部配置的
嵌套路由
每一级路由都必须要有该级路由的router-view
哪个组件还有子路由,那么需要在该组件内部定义router-view,代表该组件的子路由显示在该位置上
子路由的配置,定义在父路由的children属性下,配置内容同父路由
子路由如果不加斜线,那么默认在上级路由上叠加,如果加了斜线,那么前面必须带上 上级路由
const routes = [
{
path: '/home',//"/"是默认路径
//懒加载:一开始不加载,等被调用时才加载
component: ()=>import("../views/MyHome"),
//子路由
children:[
{
path:"/home/about",
component:()=>import("../views/MyAbout")
}
]
}
路由的跳转
js形式的跳转
如果看到了某个方法是以$打头的,基本可以断定,该方法是Vue根实例的方法
标签形式的跳转
<router-link to="/about">跳转</router-link>
// to 可以是字符串路径 还可以时对象 {path:"路径"} {name:"名字"}
<router-link :to="{path:"/login"}">跳转</router-link>
浏览器的跳转(得有浏览记录才能跳转)
// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
// 如果 history 记录不够用,那就默默地失败呗
router.go(-100)
router.go(100)
动态路由
注:
$route 当前路由实例
$router 根路由实例(整个项目的路由实例)
动态路由作用: 多个路由匹配到同一个页面
动态路由匹配:
在路径后面加/:名字
{ path: '/users/:id', component: User },
//可以同时存在多个动态路由
{ path: '/users/:id/:no', component: User },
注意:
只改后面动态路径参数是不会重新触发组件生命周期的,但是如果页面中用到了动态路由的数据,那么切换动态路径的时候,是会触发组件更新的生命周期的
动态路由的跳转:
router.push({ name: 'user', params: { userId: '123' }})
router.push({ path: '/user/123' })
router.push( '/user/123')
//下面的写法是错误的
//path,params都能写动态路径,会发生冲突
router.push({ path: '/user', params: { userId: '123' }})
同样的规则适用于router-link
查询参数
作用:用于跨组件传递数据(传值时要传基本数据类型,不能传引用数据类型(对象,数组),会乱码)
跳转的时候直接在地址后面拼接?key=value
router.push({ path: '/register', query: { plan: 'private' }})
router.push({ path: '/register?key=value'}})
router.push("/register?key=value")
注意:
name和params配套
path和query 配套
捕获所有路由
{
// 会匹配所有路径(通配符)
path: '*'
}
{
// 会匹配以 `/user-` 开头的任意路径
path: '/user-*'
}
组件路由对象
在组件中通过this.$route拿到当前组件的路由信息
{
name:"组件的名字",
fullPath:"完整路径",
path:"当前组件路径",
redirect:"重定向(当输入path的路径时会直接跳转到重定向所定义的路径)",
matched:[匹配上的所有路由],
meta:"路由元信息",
params:"动态路径参数",
query:"查询参数"
}
重定向和别名
重定向: “重定向”的意思是,当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b
语法:
redirect:"要跳转的路径"
重定向的目标也可以是一个命名的路由:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: { name: 'foo' }}
]
})
别名: /a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
别名的作用:
“别名”的功能让你可以自由地将 UI 结构映射到任意的 URL,而不受限于配置的嵌套路由结构
路由组件传参
将动态路径传到组件中当参数
给动态路径赋值可以直接渲染到页面里
const User = {
props: ['id',"num"],//加一个属性,在属性里面传参
template: '<div>User {{ id }} {{ num }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id/:num', component: User, props: true },
]
})
路由模式
hash和history功能基本一样,但是history更美观
history有刷新404的问题
解决方法:
后端配置nginx做一个重定向,如果请求页面不存在就自动跳转到首页
导航守卫
全局前置守卫
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
全局前置守卫作用(我理解的):在路由执行前判断一些条件,符合条件才可以使用路由
例:在进入home页面前先判断是否登录
上面图片代码中有死循环的问题,下面是更正以后