21路由 -- 重点
单页面应用
1 spa ----- single page application 单页面应用
通过路由的技术 实现页面切换
只有在第一次的时候加载页面
2 多页面应用
每次通过a标签实现页面跳转
浪费请求资源 由于刷新
3 路由的改变
前端 不同的访问路径 显示不同组件 (显示不同)
后端 不同的访问路径 返回不同的资源
1 下载 npm i vue-router -S
2 在 src目录下 生成一个 router/index.js
import Vue from "vue";
import VueRouter from "vue-router";
import Home from "@/views/Home";
import About from "@/views/About";
import Center from "@/views/Center";
Vue.use(VueRouter);
const routes = [
{
path: "/home",
component: Home, //不要加S
},
{
path: "/about",
component: About,
},
{
path: "/center",
component: Center,
},
];
export default new VueRouter({
routes,
});
3 导出 并且在 main.js里面导入 挂在到根实例
import a from "./router"
new Vue({
router:a
})
4 使用路由
1) router-view 显示路由切换组件内容的位置
2) router-link to="path"
23 router-link 属性
1 to="/path"
:to="{}" 传参
2 activeClass or active-class="" 设置高亮类名
3 tag =" 修改标签"
4 replace 默认路由跳转是push 可以修改成replace 无后退 - 无历史记录
适用与二级三级路由 不需要加历史记录
push添加栈 (有历史记录) 会做一个判断 如果当前栈路径与要添加的栈路径一样 不生效 ,
replace 替换栈(无历史记录) 会做一个判断 如果当前栈路径与要添加的栈路径一样 不生效 ,
5 精准匹配 exact 路径访问的
/center
/center/list
24 动态路由
<router-link to="path/参数">
routes :[
{path:"path/:变量"}
]
调用的时候通过 this.$route.param.变量
25嵌套路由
嵌套路由又名子路由
给谁添加子路由就在哪个配对对象里面配置children属性
以下代码 /about/one 和 about/two 就是 about他的子路由
ps 必须要在about 加 router-view 否则内容不显示
export default new VueRouter({
routes: [
{
path: "/",
component: Home,
},
{
path: "/about",
component: About, //必须要添加一个 router-view
children: [
{ path: "/about/one", component: One },
{ path: "/about/two", component: Two },
{
path: "/about",
redirect: "/about/one",
},
],
},
],
});
26 命名路由
1 需要给路由对象配置name属性 注意name必须唯一
2 可以 隐藏传递内容 但是不支持刷新 (刷新后传递内容为空)
export default new VueRouter({ routes: [ { path: "/home", name: "Home", component: Home, }, { path: "/about", name: "About", component: About, }, { path: "/center", name: "Center", component: Center, }, ], }); <router-link :to="{name:'Home',params:{name:'Home',pass:'123123'}}">home</router-link>
routes: [ { path: "/", components: { default: Home, menu: Menu, }, }, { path: "/about", components: { default: About, menu: Menu, }, // component: About, //必须要添加一个 router-view }, { path: "/center", components: { default: Center, menu: Menu, }, //必须要添加一个 router-view }, { path: "/detail", component:Detail//必须要添加一个 router-view }, ], <router-view></router-view> router-view 如果配置没有添加name属性 会对应显示 routes default组件 router-view 有name属性 则会匹配相同name属性的组件,如果匹配不到不显示
this.$router.history.push(path) 默认
this.$router.history.replace(path) 没有后退记录
this.$router.history.go() 正数前进 负数后退 0刷新
29 路由传参
1 传参 query 问题 地址栏上会显示你传递的内容 url http://localhost:8080/#/center?age=20&pass=123123 <router-link :to="{path:'/home',query:{name:'zhangsan',pass:'123123'}}">home</router-link> 编程试 this.$router.history.push({ path: "/home", query: { age: 20, pass: 123123 } })
重定向 { path : "/" ,redirect:"/path" ,{name:""}}
别名 { path: "/home", name: "Home", component: Home, alias: "/", },
以上 当我访问 / 目录也会显示Home组件 在这里访问 /home与 /作用一样
31 路由模式 (重点)
1 hash模式
不好看
有 #
js原生事件 onHashChange 事件
上线的时候不需要额外配置
http://localhost:8080/#/home?name=zzz 默认省略 #后面的资源路径 f
2 history模式 -- 能缓存 常用
好看
无 #
h5新增api historyAPI
需要在服务器配置资源路径
http://localhost:8080/home 容易出现 404
1 首屏加载时间过长
1) 加广告 (最主要赚钱)
2 ) 骨架屏
2 路由懒加载 首屏内容正常加载 其它内容通过路由跳转到 时候再加载
const Home = () => import("@/views/Home");
{
path: "/home",
name: "Home",
component: () => import("@/views/Home"),
alias: "/",
},
33 路由元信息
只有放在元信息里面的内容才能通过 this.$route来获取
this.$route.meta.til
{
path: 'bar',
component: Bar,
til:"adsf"
// a meta field
meta: { requiresAuth: true ,til:"首页" }
}
34 路由的生命周期
1 全局钩子
beforeEach
afterEach
// 哪些页面需要做登录验证
// 状态来判断我是否登录过
// 登录 后台 登录成功结果 -- 本地存储里面 token()
// wangshupeng-- > d6a9ad809feec3d5d5a62233961b039c ---- > wangshupeng
// 本地存储
const isLogin = false;
// 每一次跳转页面 不安全
// 1 是否需要登录验证 /center /about 需要做登陆验证
// 2 是否登录 (1)
//全局导航 跳转前进行
router.beforeEach((to, from, next) => {
document.title=to.meta.til
// 需要验证的 组件路径
let pathArr = ["/center", "/about"];
let result = pathArr.some((item) => item === to.path);
// to.path
// 判断是否需要验证
if (result) {
// 是否登陆
if (!isLogin) {
// router.history.replace("/login");
next({ name: "Login" }); // 死循环
} else {
next();
}
} else {
next();
}
});
// 路由进入之后
router.afterEach((to, from) => {
})
2 路由独享的守卫
beforeEnter: (to, from, next) => {
// to
console.log("this is home beforeEnter");
next();
},
3 组件内的守卫
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
// 它是重点 *** 当地址参数发生改变但是组件没有没销毁所以组件生命周期只执行了一次,这个导致通过动态路由传递的参数不能及时获取到 可以通过下面两种方式
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
替换
watch:{
$route:{
handler(){
// this.$route
}
}
}
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
35 keepAlive 很重要 缓存组件
<keep-alive></keep-alive> 是一个包裹组件 只对销毁的组件起作用 让组件不被销毁
1 需要在meta里面自定义字段 例如 isKeep :true /缓存 isKeep:false /不缓存
<keep-alive> <router-view v-if="$route.meta.isKeep"></router-view> </keep-alive> <router-view v-if="!$route.meta.isKeep"></router-view> routes { path: "/about", name: "About", component: About, meta: { til: "关于", isCheckLogin: false, isKeep: false }, 不被缓存 },
2 keepAlive include exclude
<keep-alive include="home,about,center" > include 包含的组件name会被缓存 <router-view></router-view> </keep-alive> <keep-alive exclude="home,about,center"> exclude 包含的组件name不会被缓存 <router-view></router-view> </keep-alive>
3 keepAlive 生命周期 被keepAlive 组件缓存的 才有
activated() {
console.log("activated")
this.num += 1
//
},
deactivated() {
console.log("deactivated")
},