一、单页面应用SPA
单页面应用: 所有功能在一个页面上实现
单页面-多页面对比:
对比部分 | 单页应用 | 多页面应用 |
---|---|---|
组成 | 一个html文件多个组件组成 | 多个html文件 |
静态资源公用 | 共用,一次性加载完毕 | 不共用,每个页面都加载一遍 |
刷新方式 | 页面局部刷新 | 整页加载 |
url模式 | itcast.com/#/pageone | itcast.com/pageone.html |
用户体验 | 用户体验良好 | 页面切换加载缓慢体验较差 |
数据传递 | 容易 | 依赖url传参,cookie,localStorage |
搜索引擎优化 | 不利于seo优化,需要ssr优化 | 支持良好 |
使用场景 | 追求高体验 不要求seo | 高度要求seo |
开发成本 | 较高 需要依赖专业的框架, 开发效率高 | 较低 重复代码多, 开发效率低 |
二、路由使用
- 前端路由的本质:对url的hash值进行改变和监听,切换挂载点的component组件
- vue中的路由:是hash和component的对应关系, 一个哈希值对应一个组件
- .vue文件分两类:页面组件(页面展示,配合路由)、复用组件(展示数据,用于复用)
- vue-router模块使用
//1.安装
yarn add vue-router
//2.导入路由 main.js
import VueRouter from 'vue-router'
//3.使用路由插件
// 在vue中,使用使用vue的插件,都需要调用Vue.use()
Vue.use(VueRouter)
//4.创建路由规则数组
const routes = [
{
path: "/home",
component: MyHome
},
{
path: "/movie",
component: MyMovie
},
{
path: "/about",
component: MyAbout
}
]
//5.创建路由实例对象 - 传入路由规则数组
const router = new VueRouter({
routes
})
//6.关联到vue实例,挂载路由实例对象
new Vue({
router
})
//7.components换成router-view,挂载点
<router-view></router-view>
三、链接导航
作用:可用全局组件router-link来代替a标签
- vue-router提供了一个全局组件 router-link: 作用用于提供路由链接
- router-link实质上最终会渲染成a链接 ; to属性默认会被渲染为href属性;to属性的值默认会被渲染为#开头的hash地址
- router-link提供了链接导航高亮的功能,active-class属性,自定义高亮类名
<router-link active-class="active" to="/home">首页</router-link>
<router-link exact-active-class="active" to="/home">首页</router-link>
- router-view :路由填充位(路由占位符),将来通过路由规则匹配到的组件,将会被渲染到router-view所在的位置
- 跳转传参,在跳转路由时, 可以给路由对应的组件内传值
// ?key=value 用$route.query.key 取值
<li><router-link to="/goods?name=外套">看外套</router-link></li>
// /值 提前在路由规则/path/:key 用$route.params.key 取值
<li><router-link to="/goods/裤子">看裤子</router-link></li>
四、重定向
作用:默认上来强制显示某个路由页面,找不到路径给个提示页面
import NotFound from "@/components/NotFound";
const routes = [
{
path: "/",
redirect: "/home" // 重定向
},
// ...正常路由
{ // 当上面路由都不匹配, 匹配这个通配符, 显示NotFound页面
path: "*",//匹配所有路径
component: NotFound
}
]
五、模式
作用:修改路由在地址栏的模式
const router = new VueRouter({
routes,
mode: "history" // 打包上线后需要后台支持, 模式是hash
})
- hash路由例如: http://localhost:8081/#/home
- history路由例如: http://localhost:8081/home (部署后服务器端支持)
- abstract模式:不显示路由路径
六、编程式导航
作用:用js代码跳转,导航链接时用a标签
this.$router.push({
path: "路由路径", // 都去 router/index.js定义,页面上能看见,在路径上显示
name: "路由名" //页面上看不见
})
- 跳转传参
//第一种 对应路由接收 $route.params.key 取值
//name+params方式 -> 在内存中传递(刷新就没了)
this.$router.push({
name: "路由名字",
params: {
"key": 值
}
})
// 第二种 对应路由接收 $route.query.key 取值
// path+query方式 -> 在url?传递
this.$router.push({
path: "路由路径",
query: {
"key": 值
}
})
七、路由嵌套
作用:在现有的一级路由下,再嵌套二级路由
main.js - 专门转路由配置和导出路由对象
-
一级路由path从/开始定义
-
二级路由往后path直接写名字, 无需/开头
-
嵌套路由在上级路由的children数组里编写路由信息对象
const routes = [
{
path: "/",
redirect: "find"
},
{
path: "/find",
component: FindMusic,
// 1. 找准属于哪个一级路由下属的
// 2. 二级路由path无需加/
children: [
{
path: "recommend",
component: Recommend
}
]
}
];
八、路由守卫
- 全局前置守卫:路由跳转之前, 会触发一个函数
// 路由前置守卫
router.beforeEach((to, from, next) => {
// to代表要跳转到哪个路径去, to的值是个对象可以打印看到
// from代表从哪个路径跳过去
console.log(to);
console.log(from);
// fullPath带?后面参数的, path是完整的路径
console.log("路由要跳转了");
// 模拟判断登录了没有, 登录后才能去我的音乐
let loginFlag = false; // 假设false代表未登录
if (to.path == "/my" && loginFlag == false) {
// 如果去个人中心页面, 判断未登录, 提示登录(并强制跳转回find)
alert("请先登录!");
next("/find");
} else {
// 如果不去/my页面就直接跳转
next();
}
});
- 全局后置守卫:路由跳转后, 触发的函数
router.afterEach((to, form) => {
console.log(to);
console.log(form);
console.log("路由发生了跳转");
})