vue路由简介和基础使用
生活中的路由:设备和ip的映射关系
node.js中的路由:接口和服务的映射关系
前端路由:路径和组件的映射关系
http://localhost:8080/#/home
http://localhost:8080/#/search
那么为什么要使用路由呢?一个网页可以局部刷新吗?
就比如网易云音乐首页 https://music.163.com/
单页面应用SPA指所有功能在一个HTML页面上实现(single page web application)
使用路由的优点:整体不刷新页面,用户体验更好;数据传递容易,开发效率高。 使用路由的缺点:开发成本高,首次加载会慢一点,不利于Seo
在Vue中通过引入vue-router这个包,vue文件分两类,一个是页面组件,一个是复用组件。下包/引入/注册/规划/路由对象/注入/挂载点
src/views文件夹常用于页面组件,页面展示,配合路由用。
src/components文件夹常用于复用组件,展示数据,常用于复用。
声明式导航
<template>
<div>
<div class="footer_wrap">
<a href="#/find">发现音乐</a>
<a href="#/my">我的音乐</a>
<a href="#/part">朋友</a>
//<router-link to="/find">发现音乐</router-link>
//<router-link to="/my">我的音乐</router-link>
//<router-link to="/part">朋友</router-link>
</div>
<div class="top">
<!-- 7. 设置挂载点-当url的hash值路径切换, 显示规则里对应的组件到这 -->
<router-view></router-view>
</div>
</div>
</template>
两种使用方法router-link实质上最终会渲染成a链接 to属性等价于提供href属性(to无需#)
router-link提供了声明式导航高亮的功能
/*激活时样式 */
.footer_wrap .router-link-active{
color: white;
background: black;
}
声明式导航跳转时,如何传值给路由页面?
/path?参数名=值
/path/值
<template>
<div>
<div class="footer_wrap">
<router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/part?name=小传">朋友-小传</router-link>
<router-link to="/part/小智">朋友-小智</router-link>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
对应页面用$route.quert.参数名或者 $route.params.参数名来接受
<template>
<div>
<p>关注明星</p>
<p>发现精彩</p>
<p>寻找伙伴</p>
<p>加入我们</p>
<p>人名: {{ $route.query.name }}
--
{{ $route.params.username }}
</p>
</div>
</template>
重定向和模式
网页打开变成默认页面,redirect是设置要重新定向到哪个路由路径。如果页面找不到,我们就应该跳出其余提示。
const routes = [{
path: "/", // 默认hash值路径
redirect: "/find" // 重定向到/find
// 浏览器url中#后的路径被改变成/find-重新匹配规则
},
// 404在最后(规则是从前往后逐个比较path)
{
path: "*",
component: NotFound
}]
const router = new VueRouter({
routes, // routes是固定key(传入规则数组)
mode: "history" // 默认不写是"hash"
})
编程式导航
a标签可以切换路由路径,用JS方式可以切换吗。
可以,我们可以定义click方法,传入相关参数,如下所示。
可以通过path属性或者name属性进行跳转。
<template>
<div>
<div class="footer_wrap">
<span @click="btn('/find', 'Find')">发现音乐</span>
<span @click="btn('/my', 'My')">我的音乐</span>
<span @click="btn('/part', 'Part')">朋友</span>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
methods: {
btn(targetPath, targetName){
// 方式1: path跳转
this.$router.push({
// path: targetPath,
name: targetName
})
}
}
// 语法:
// this.$router.push({path: “路由路径”})// this.$router.push({name: “路由名”})
虽然用name跳转,但是url的hash值还是切换path路径值。name路有名在页面上看不到,因此可以随便定义。path可以在url的hash值看到。因此尽量要符合命名规范。
那么如果我们要传递参数,该如何传递呢?
<span @click="oneBtn">朋友-小传</span>
<span @click="twoBtn">朋友-小智</span>
oneBtn(){
this.$router.push({
name: 'Part',
params: {
username: '小传'
}
})
},
twoBtn(){
this.$router.push({
name: 'Part',
query: {
name: '小智'
}
})
}
嵌套和守卫
在现有的一级路由下,再嵌套二级路由,路由规则里children中配置二级路由规则对象,一级页面中设置router-view显示二级路由页面。二级路由需要注意path不写根路径。跳转时路径要从/写全。
{
path: "/find",
name: "Find",
component: Find,
children: [{
path: "recommend",
component: Recommend
},
{
path: "ranking",
component: Ranking
},
{
path: "songlist",
component: SongList
}
]
}
router-link-extract-active精确匹配url中hash值路径,与href属性值完全相同,设置次类名
router-link-active模糊匹配url中hash值,包含href属性值这个路径。
下面介绍全局前置首位,路由跳转之前,先检查是否登录
// 例子: 判断用户是否登录, 是否决定去"我的音乐"/my
const isLogin = false; // 登录状态(未登录)
router.beforeEach((to, from, next) => {
if (to.path === "/my" && isLogin === false) {
alert("请登录")
next(false) // 阻止路由跳转
} else {
next() // 正常放行
}
})