- 能够说出单页面概念和优缺点
- 能够掌握vue-router路由系统
- 能够掌握声明式导航和编程式导航
- 能够掌握路由嵌套和守卫
一.Vue路由简介和基础使用
1.生活中的路由
目标:设备和ip的映射关系
2.nodejs路由
目标:接口和服务的映射关系
3.前端路由
目标:路径和组件的映射关系
1. 路由是什么呢? 路由是一种映射关系
2. Vue中的路由是什么?路径和组件的映射关系
4.为何使用路由
目标:了解为何使用路由
- 具体使用示例: 网易云音乐 https://music.163.com/
- 单页面应用(SPA): 所有功能在一个html页面上实现
- 前端路由作用: 实现业务场景切换
优点:
- 整体不刷新页面,用户体验更好
- 数据传递容易, 开发效率高
缺点:
- 开发成本高(需要学习专门知识)
- 首次加载会比较慢一点。不利于seo
1. 什么是单页面应用? 所有的业务都在一个页面编写, 只有一个html
2. 单页面应用好处? 开发效率高, 用户体验好
3. 单页面如何切换场景?依赖路由切换显示
5.vue-router
目标: vue-router本质是一个第三方包
官网: https://router.vuejs.org/zh/
vue-router模块包
- 它和 Vue.js 深度集成
- 可以定义 - 视图表(映射规则)
- 模块化的
- 提供2个内置全局组件
- 声明式导航自动激活的 CSS class 的链接
6.组件分类
目标: .vue文件分2类, 一个是页面组件, 一个是复用组件
.vue文件本质无区别, 方便大家学习和理解, 总结的一个经验
src/views文件夹
- 页面组件 - 页面展示 - 配合路由用
src/components文件夹
- 复用组件 - 展示数据/常用于复用
1. 为何把.vue文件分类? 方便理解和使用
2. 页面组件用在哪里? 配合路由, 切换页面
3. 复用组件用在哪里?页面组件, 重复渲染结构一样的标签
7.vue-router模块
步骤
- 1. 下载vue-router模块到当前工程
- 如果遇到版本不兼容的问题,可以手动编辑项目的
package.json
文件,将vue-router
的依赖版本指定为与您当前项目中安装的vue
版本兼容的版本。在重新npm install一下 - 2. 在main.js中引入VueRouter函数
-
import VueRouter from 'vue-router'
- 3. 添加到Vue.use()身上 – 注册全局RouterLink和RouterView组件
- 4. 创建路由规则数组 – 路径和组件名对应关系
- 5. 用规则生成路由对象
- 6. 把路由对象注入到new Vue实例中
- 7. 用router-view作为挂载点, 切换不同的路由页面
main.js
import Vue from 'vue'
import App from './App.vue'
import FindPage from '@/views/Find' // @是src的绝对地址
import MyProfile from '@/views/My'
import PartDetail from '@/views/Part'
// 目标: vue-router基础使用
// 1. 下载vue-router (yarn add vue-router)
// 2. 引入
import VueRouter from 'vue-router'
// 3. 注册全局组件
Vue.use(VueRouter)
// 4. 规则数组
const routes = [
{
path: "/",
redirect: "/find"
},
{
path: "/find",
name: "Find",
component: FindPage,
},
{
path: "/my",
name: "My",
component: MyProfile
},
{
path: "/part",
name: "Part",
component: PartDetail
}
]
// 5. 生成路由对象
const router = new VueRouter({
routes,
// mode: "history" // 默认不写是"hash"
})
Vue.config.productionTip = false
// 6. 路由对象注入到vue实例中, this可以访问$route和$router
new Vue({
router,
render: h => h(App),
}).$mount('#app')
App.vue
<template>
<div>
<div class="footer_wrap">
<a href="#/find">发现音乐</a>
<a href="#/my">我的音乐</a>
<a href="#/part">朋友</a>
</div>
<div class="top">
<!-- 7.设置挂载点-当url的hash值路径切换,显示规则里对应的组件到这 -->
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {};
</script>
<style scoped>
.footer_wrap {
position: fixed;
left: 0;
top: 0;
display: flex;
width: 100%;
text-align: center;
background-color: #333;
color: #ccc;
}
.footer_wrap a {
flex: 1;
text-decoration: none;
padding: 20px 0;
line-height: 20px;
background-color: #333;
color: #ccc;
border: 1px solid black;
}
.footer_wrap a:hover {
background-color: #555;
}
.top {
padding-top: 62px;
}</style>
Find.vue
<template>
<div>
<p>推荐</p>
<p>排行榜</p>
<p>歌单</p>
</div>
</template>
<script>
export default {
name: 'FindPage',
}
</script>
<style>
</style>
My.vue
<template>
<div>
<p>我的收藏</p>
<p>我的历史记录</p>
</div>
</template>
<script>
export default {
name: 'MyProfile',
}
</script>
<style>
</style>
Part.vue
<template>
<div>
<p>关注明星</p>
<p>发现精彩</p>
<p>寻找伙伴</p>
<p>加入我们</p>
</div>
</template>
<script>
export default {
name: 'PartDetail',
}
</script>
<style>
</style>
注意: 一切都要以url上hash值为准
1. vue-router本质是什么?第三方包, 下载后集成到vue项目中
2. vue-router如何使用? 下包/引入/注册/规则/路由对象/注入/挂载点
3. 规则如何生效?切换url上hash值, 开始匹配规则, 对应组件展示到 router-view位置
声明式导航
1.声明式导航
目标:可用组件router-link来替代a标签
- 1. vue-router提供了一个全局组件 router-link
- 2. router-link实质上最终会渲染成a链接 to属性等价于提供 href属性(to无需#)
- 3. router-link提供了声明式导航高亮的功能(自带类名)
App.vue
<template>
<div>
<div class="footer_wrap">
<router-link to="#/find">发现音乐</router-link>
<router-link to="#/my">我的音乐</router-link>
<router-link to="#/part">朋友</router-link>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
<script>
// 目标:声明式导航 - 基础使用
// 本质:vue-router提供的全局组件"router-link"替代a标签
// 1,router-link 替代a标签
// 2.to属性 替代herf属性
// 好处:router-link 自带高亮的类名(激活时类名)
// 3.对激活的类名做出样式的编写
export default {};
</script>
<style scoped>
.footer_wrap {
position: fixed;
left: 0;
top: 0;
display: flex;
width: 100%;
text-align: center;
background-color: #333;
color: #ccc;
}
.footer_wrap a {
flex: 1;
text-decoration: none;
padding: 20px 0;
line-height: 20px;
background-color: #333;
color: #ccc;
border: 1px solid black;
}
.footer_wrap a:hover {
background-color: #555;
}
.top {
padding-top: 62px;
}
.footer_wrap .router-link-active{
color: white;
background: black;
}
</style>
1. router-link是什么? VueRouter在全局注册的组件, 本质就是a标签
2. router-link怎么用? 当标签使用, 必须传入to属性, 指定路由路径值
3. router-link好处?自带激活时的类名, 可以做高亮
2.声明式导航 - 跳转传参
目标:在跳转路由时, 可以给路由对应的组件内传值
在router-link上的to属性传值, 语法格式如下
- /path?参数名=值
- /path/值 – 需要路由对象提前配置 path: “/path/参数名”
对应页面组件接收传递过来的值
- $route.query.参数名
- $route.params.参数名
第一种:
第二种:
App.vue
<template>
<div>
<div class="footer_wrap">
<router-link>发现音乐</router-link>
<router-link>我的音乐</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>
<script>
// 目标: 声明式导航 - 传值
// 方式1:
// to="/path?参数名=值"
// 接收: $route.query.参数名
// 方式2:
// (1): 路由规则path上 定义 /path/:参数名
// (2): to="/path/值"
// 接收: $route.params.参数名
export default {};
</script>
<style scoped>
.footer_wrap {
position: fixed;
left: 0;
top: 0;
display: flex;
width: 100%;
text-align: center;
background-color: #333;
color: #ccc;
}
.footer_wrap a {
flex: 1;
text-decoration: none;
padding: 20px 0;
line-height: 20px;
background-color: #333;
color: #ccc;
border: 1px solid black;
}
.footer_wrap a:hover {
background-color: #555;
}
.top {
padding-top: 62px;
}
/*激活时样式 */
.footer_wrap .router-link-active {
color: white;
background: black;
}</style>
Part.vue
<template>
<div>
<p>关注明星</p>
<p>发现精彩</p>
<p>寻找伙伴</p>
<p>加入我们</p>
<p>人名: {{ $route.query.name }}
--
{{ $route.params.username }}
</p>
</div>
</template>
<script>
export default {
name: 'PartDetail',
}
</script>
<style>
</style>
1. 声明式导航跳转时, 如何传值给路由页面? to="/path?参数名=值" to=“/path/值” (需在路由规则里配置/path/:参数名)
2. 如何接收路由传值? $route.query.参数名 $route.params.参数名
重定向和模式
1.路由 - 重定向
目标:匹配path后, 强制跳转path路径
- 网页打开url默认hash值是/路径
- redirect是设置要重定向到哪个路由路径
当我们打开页面路由得时候,页面没有任何显示,当使用重定向到/find得界面时,打开项目弹出得就是/find界面的内容
main.js
import Vue from 'vue'
import App from './App.vue'
import FindPage from '@/views/Find' // @是src的绝对地址
import MyProfile from '@/views/My'
import PartDetail from '@/views/Part'
// 目标: vue-router基础使用
// 1. 下载vue-router (yarn add vue-router)
// 2. 引入
import VueRouter from 'vue-router'
// 3. 注册全局组件
Vue.use(VueRouter)
// 4. 规则数组
const routes = [
{
path:"/", //默认hash值路径
redirect:"/find" //重定向到/find
// 浏览器url中#后得路径被改变后/find-重新匹配规则
},
{
path: "/find",
name: "Find",
component: FindPage,
},
{
path: "/my",
name: "My",
component: MyProfile
},
{
path: "/part",
name: "Part",
component: PartDetail
}
]
// 5. 生成路由对象
const router = new VueRouter({
routes,
// mode: "history" // 默认不写是"hash"
})
Vue.config.productionTip = false
// 6. 路由对象注入到vue实例中, this可以访问$route和$router
new Vue({
router,
render: h => h(App),
}).$mount('#app')
1. 如何监测默认路由? 规则里定义path: '/'
2. 如何重定向路由路径? redirect配置项, 值为要强制切换的路由路径
2.路由 - 404
目标:找不到路径给个提示页面
路由最后, path匹配*(任意路径) – 前面不匹配就命中最后这个
NotFound.vue
<template>
<img src="../assets/404.png" alt="">
</template>
<script>
export default {
}
</script>
<style scoped>
img {
width: 100%;
}
</style>
main.js
import Vue from 'vue'
import App from './App.vue'
import Find from '@/views/Find' // @是src的绝对地址
import My from '@/views/My'
import Part from '@/views/Part'
import NotFound from '@/views/NotFound'
// 目标: vue-router基础使用
// 1. 下载vue-router (yarn add vue-router)
// 2. 引入
import VueRouter from 'vue-router'
// 3. 注册全局组件
Vue.use(VueRouter)
// 4. 规则数组
const routes = [
{
path: "/", // 默认hash值路径
redirect: "/find" // 重定向到/find
// 浏览器url中#后的路径被改变成/find-重新匹配规则
},
{
path: "/find",
name: "Find",
component: Find
},
{
path: "/my",
name: "My",
component: My
},
{
path: "/part",
name: "Part",
component: Part
},
{
path: "/part/:username", // 有:的路径代表要接收具体的值
component: Part
},
// 404在最后(规则是从前往后逐个比较path)
{
path: "*",
component: NotFound
}
]
// 5. 生成路由对象
const router = new VueRouter({
routes,// routes是固定key(传入规则数组)
// mode: "history" // 默认不写是"hash"
})
Vue.config.productionTip = false
// 6. 路由对象注入到vue实例中, this可以访问$route和$router
new Vue({
router,
render: h => h(App),
}).$mount('#app')
3.路由 - 模式设置
目标:修改路由在地址栏的模式
- hash路由例如: http://localhost:8080/#/home
- history路由例如: http://localhost:8080/home (以后上线需要服务器端支持, 否则找的是文件夹)
main.js
import Vue from 'vue'
import App from './App.vue'
import Find from '@/views/Find' // @是src的绝对地址
import My from '@/views/My'
import Part from '@/views/Part'
import NotFound from '@/views/NotFound'
// 目标: vue-router基础使用
// 1. 下载vue-router (yarn add vue-router)
// 2. 引入
import VueRouter from 'vue-router'
// 3. 注册全局组件
Vue.use(VueRouter)
// 4. 规则数组
const routes = [
{
path: "/", // 默认hash值路径
redirect: "/find" // 重定向到/find
// 浏览器url中#后的路径被改变成/find-重新匹配规则
},
{
path: "/find",
name: "Find",
component: Find
},
{
path: "/my",
name: "My",
component: My
},
{
path: "/part",
name: "Part",
component: Part
},
{
path: "/part/:username", // 有:的路径代表要接收具体的值
component: Part
},
// 404在最后(规则是从前往后逐个比较path)
{
path: "*",
component: NotFound
}
]
// 5. 生成路由对象
const router = new VueRouter({
routes,// routes是固定key(传入规则数组)
mode: "history" // 默认不写是"hash"
})
Vue.config.productionTip = false
// 6. 路由对象注入到vue实例中, this可以访问$route和$router
new Vue({
router,
render: h => h(App),
}).$mount('#app')
编程式导航
1.编程式导航 - 基础使用
目标:用JS代码来进行跳转
语法: path或者name任选一个
App.vue
<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>
<script>
// 目标: 编程式导航 - js方式跳转路由
// 语法:
// this.$router.push({path: "路由路径"})
// this.$router.push({name: "路由名"})
// 注意:
// 虽然用name跳转, 但是url的hash值还是切换path路径值
// 场景:
// 方便修改: name路由名(在页面上看不见随便定义)
// path可以在url的hash值看到(尽量符合组内规范)
export default {
methods: {
btn(targetPath, targetName) {
// 方式1: path跳转
this.$router.push({
// path: targetPath,
name: targetName
})
}
}
};
</script>
<style scoped>
.footer_wrap {
position: fixed;
left: 0;
top: 0;
display: flex;
width: 100%;
text-align: center;
background-color: #333;
color: #ccc;
}
.footer_wrap span {
flex: 1;
text-decoration: none;
padding: 20px 0;
line-height: 20px;
background-color: #333;
color: #ccc;
border: 1px solid black;
}
.footer_wrap span:hover {
background-color: #555;
}
.top {
padding-top: 62px;
}
/*激活时样式 */
.footer_wrap .router-link-active {
color: white;
background: black;
}</style>
JS如何切换路由路径? this.$router.push()配置path/name
要和路由规则数组里对应
2.编程式导航 - 跳转传参
目标:JS跳转路由,传参
语法:query或者params任选一个
注意:使用path会忽略params
<template>
<div>
<div class="footer_wrap">
<span @click="btn('/find', 'Find')">发现音乐</span>
<span @click="btn('/my', 'My')">我的音乐</span>
<span @click="oneBtn">朋友-小传</span>
<span @click="twoBtn">朋友-小智</span>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
<script>
// 目标: 编程式导航 - 跳转路由传参
// 方式1:
// params => $route.params.参数名
// 方式2:
// query => $route.query.参数名
// 重要: path会自动忽略params
// 推荐: name+query方式传参
// 注意: 如果当前url上"hash值和?参数"与你要跳转到的"hash值和?参数"一致, 爆出冗余导航的问题, 不会跳转路由
export default {
methods: {
btn(targetPath, targetName) {
// 方式1: path跳转
this.$router.push({
// path: targetPath,
name: targetName
})
},
oneBtn() {
this.$router.push({
name: 'Part',
params: {
username: '小传'
}
})
},
twoBtn() {
this.$router.push({
name: 'Part',
query: {
name: '小智'
}
})
}
}
};
</script>
<style scoped>
.footer_wrap {
position: fixed;
left: 0;
top: 0;
display: flex;
width: 100%;
text-align: center;
background-color: #333;
color: #ccc;
}
.footer_wrap span {
flex: 1;
text-decoration: none;
padding: 20px 0;
line-height: 20px;
background-color: #333;
color: #ccc;
border: 1px solid black;
}
.footer_wrap span:hover {
background-color: #555;
}
.top {
padding-top: 62px;
}
/*激活时样式 */
.footer_wrap .router-link-active {
color: white;
background: black;
}</style>
嵌套和守卫
1.路由 - 路由嵌套
目标:在现有的一级路由下, 再嵌套二级路由
二级路由示例-网易云音乐-发现音乐下 https://music.163.com/
1. 创建需要用的所有组件
- src/views/Find.vue -- 发现音乐页
- src/views/My.vue -- 我的音乐页
- src/views/Second/Recommend.vue -- 发现音乐页 / 推荐页面
- src/views/Second/Ranking.vue -- 发现音乐页 / 排行榜页面
- src/views/Second/SongList.vue -- 发现音乐页 / 歌单页面
2. main.js– 继续配置2级路由
- 一级路由path从/开始定义
- 二级路由往后path直接写名字, 无需/开头
- 嵌套路由在上级路由的children数组里编写路由信息对象
3. 说明:
- App.vue的router-view负责发现音乐和我的音乐页面, 切换
- Find.vue的的router-view负责发现音乐下的, 三个页面, 切换
main.js
import Vue from 'vue'
import App from './App.vue'
import Find from '@/views/Find' // @是src的绝对地址
import My from '@/views/My'
import Part from '@/views/Part'
import NotFound from '@/views/NotFound'
import Recommend from '@/views/Second/Recommend'
import Ranking from '@/views/Second/Ranking'
import SongList from '@/views/Second/SongList'
// 目标: vue-router基础使用
// 1. 下载vue-router (yarn add vue-router)
// 2. 引入
import VueRouter from 'vue-router'
// 3. 注册全局组件
Vue.use(VueRouter)
// 4. 规则数组
const routes = [
{
path: "/", // 默认hash值路径
redirect: "/find" // 重定向到/find
// 浏览器url中#后的路径被改变成/find-重新匹配规则
},
{
path: "/find",
name: "Find",
component: Find,
children: [
{
path: "recommend",
component: Recommend
},
{
path: "ranking",
component: Ranking
},
{
path: "songlist",
component: SongList
}
]
},
{
path: "/my",
name: "My",
component: My
},
{
path: "/part",
name: "Part",
component: Part
},
{
path: "/part/:username", // 有:的路径代表要接收具体的值
component: Part
},
// 404在最后(规则是从前往后逐个比较path)
{
path: "*",
component: NotFound
}
]
// 5. 生成路由对象
const router = new VueRouter({
routes,// routes是固定key(传入规则数组)
// mode: "history" // 默认不写是"hash"
})
Vue.config.productionTip = false
// 6. 路由对象注入到vue实例中, this可以访问$route和$router
new Vue({
router,
render: h => h(App),
}).$mount('#app')
App.vue
<template>
<div>
<div class="footer_wrap">
<span @click="btn('/find', 'Find')">发现音乐</span>
<span @click="btn('/my', 'My')">我的音乐</span>
<span @click="oneBtn">朋友-小传</span>
<span @click="twoBtn">朋友-小智</span>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
<script>
// 目标: 编程式导航 - 跳转路由传参
// 方式1:
// params => $route.params.参数名
// 方式2:
// query => $route.query.参数名
// 重要: path会自动忽略params
// 推荐: name+query方式传参
// 注意: 如果当前url上"hash值和?参数"与你要跳转到的"hash值和?参数"一致, 爆出冗余导航的问题, 不会跳转路由
export default {
methods: {
btn(targetPath, targetName) {
// 方式1: path跳转
this.$router.push({
// path: targetPath,
name: targetName
})
},
oneBtn() {
this.$router.push({
name: 'Part',
params: {
username: '小传'
}
})
},
twoBtn() {
this.$router.push({
name: 'Part',
query: {
name: '小智'
}
})
}
}
};
</script>
<style scoped>
.footer_wrap {
position: fixed;
left: 0;
top: 0;
display: flex;
width: 100%;
text-align: center;
background-color: #333;
color: #ccc;
}
.footer_wrap span {
flex: 1;
text-decoration: none;
padding: 20px 0;
line-height: 20px;
background-color: #333;
color: #ccc;
border: 1px solid black;
}
.footer_wrap span:hover {
background-color: #555;
}
.top {
padding-top: 62px;
}
/*激活时样式 */
.footer_wrap .router-link-active {
color: white;
background: black;
}</style>
1. 二级路由如何配置? 创建需要的二级页面组件 路由规则里children中配置二级路由规则对象 一级页面中设置router-view显示二级路由页面
2. 二级路由注意什么? 二级路由path一般不写根路径/ 跳转时路径要从/开始写全
2.声明式导航 – 类名区别
观察路由嵌套导航的样式
- router-link-exact-active (精确匹配) url中hash值路径, 与href属性值完全相同, 设置此类名
- router-link-active (模糊匹配) url中hash值, 包含href属性值这个路径
<template>
<div>
<div class="footer_wrap">
<router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/part">朋友</router-link>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
<script>
// 目标: 声明式导航 - 激活类名区别
// 1. url上hash值(#/home/recommend) 包含 导航的href值(#/home) - 当前a就有 "router-link-active" (模糊)
// 2. url上hash值(#/home/recommend) 等于 导航的href值(#/home/recommend) - 当前a就有"router-link-exact-active" (精确)
export default {};
</script>
<style scoped>
.footer_wrap {
position: fixed;
left: 0;
top: 0;
display: flex;
width: 100%;
text-align: center;
background-color: #333;
color: #ccc;
}
.footer_wrap a {
flex: 1;
text-decoration: none;
padding: 20px 0;
line-height: 20px;
background-color: #333;
color: #ccc;
border: 1px solid black;
}
.footer_wrap a:hover {
background-color: #555;
}
.top {
padding-top: 62px;
}
/*激活时样式 */
.footer_wrap .router-link-active {
color: white;
background: black;
}</style>
3.全局前置守卫
目标:路由跳转之前, 会触发一个函数
例如: 登陆状态去页面, 未登录弹窗提示
语法: router.beforeEach((to, from, next) =>{})
- 一定调next(), 才会跳转下一页
main.js
import Vue from 'vue'
import App from './App.vue'
import Find from '@/views/Find' // @是src的绝对地址
import My from '@/views/My'
import Part from '@/views/Part'
import NotFound from '@/views/NotFound'
import Recommend from '@/views/Second/Recommend'
import Ranking from '@/views/Second/Ranking'
import SongList from '@/views/Second/SongList'
// 目标: vue-router基础使用
// 1. 下载vue-router (yarn add vue-router)
// 2. 引入
import VueRouter from 'vue-router'
// 3. 注册全局组件
Vue.use(VueRouter)
// 4. 规则数组
const routes = [
{
path: "/", // 默认hash值路径
redirect: "/find" // 重定向到/find
// 浏览器url中#后的路径被改变成/find-重新匹配规则
},
{
path: "/find",
name: "Find",
component: Find,
children: [
{
path: "recommend",
component: Recommend
},
{
path: "ranking",
component: Ranking
},
{
path: "songlist",
component: SongList
}
]
},
{
path: "/my",
name: "My",
component: My
},
{
path: "/part",
name: "Part",
component: Part
},
{
path: "/part/:username", // 有:的路径代表要接收具体的值
component: Part
},
// 404在最后(规则是从前往后逐个比较path)
{
path: "*",
component: NotFound
}
]
// 5. 生成路由对象
const router = new VueRouter({
routes,// routes是固定key(传入规则数组)
// mode: "history" // 默认不写是"hash"
})
// 目标: 路由守卫
// 场景: 当你要对路由权限判断时
// 语法: router.beforeEach((to, from, next)=>{//路由跳转"之前"先执行这里, 决定是否跳转})
// 参数1: 要跳转到的路由 (路由对象信息) 目标
// 参数2: 从哪里跳转的路由 (路由对象信息) 来源
// 参数3: 函数体 - next()才会让路由正常的跳转切换, next(false)在原地停留, next("强制修改到另一个路由路径上")
// 注意: 如果不调用next, 页面留在原地
// 例子: 判断用户是否登录, 是否决定去"我的音乐"/my
const isLogin = true; // 登录状态(未登录)
router.beforeEach((to, from, next) => {
if (to.path === "/my" && isLogin === false) {
alert("请登录")
next(false) // 阻止路由跳转
} else {
next() // 正常放行
}
})
Vue.config.productionTip = false
// 6. 路由对象注入到vue实例中, this可以访问$route和$router
new Vue({
router,
render: h => h(App),
}).$mount('#app')
什么是路由守卫? 路由在真正跳转前, 会执行一次beforeEach函数, next调用则跳转, 也可以强制修改要跳转的路由
Vant组件库
1.Vant组件库
目标: Vant是一个轻量、可靠的移动端 Vue 组件库, 开箱即用
Vant组件库: https://vant-contrib.gitee.io/vant/#/zh-CN/
特点
- 提供 60 多个高质量组件,覆盖移动端各类场景
- 性能极佳,组件平均体积不到 1kb
- 完善的中英文文档和示例
- 支持 Vue 2 & Vue 3
- 支持按需引入和主题定制
2.全部引入
目标:看官网文档, 下载, 引入Vant组件库
- 1. 全部引入, 快速开始: https://vant-contrib.gitee.io/vant/#/zh-CN/quickstart
- 2. 下载Vant组件库到当前项目中
- 3. 在main.js中全局导入所有组件,
- 4. 使用按钮组件 – 作为示范的例子
先创建一个vue组件项目
然后下载vant组件
main.js
import Vue from 'vue'
import App from './App.vue'
// 方式3: 引入所有vant组件
import Vant from 'vant';
import 'vant/lib/index.css'; // 引入vant所有组件样式
Vue.use(Vant); // 全局注册vant所有组件
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
App.vue
<template>
<div>
<van-button type="primary" @click="btn">主要按钮</van-button>
<van-button type="info">信息按钮</van-button>
<van-button type="default">默认按钮</van-button>
<van-button type="warning">警告按钮</van-button>
<van-button type="danger">危险按钮</van-button>
</div>
</template>
<script>
export default {
}
data() {
return {
};
},
methods: {
};
</script>
<style></style>
如何引入Vant组件库? 组件库是一个包, 先下载 按照文档指引, 在main.js全局注册 到某.vue内直接使用Vant组件名
3.按需引入
目标:手动引入使用的某个组件
1. 手动单独引入, 快速开始: https://vant-contrib.gitee.io/vant/#/zh-CN/quickstart
Vant组件库如何手动按需引入使用? import 从vant库里引出某个组件 import 单独引出样式 在当前页面注册此组件名即可
4.自动按需引入
目标:依赖插件自动按需引入
自动按需引入, 快速开始: https://vant-contrib.gitee.io/vant/#/zh-CN/quickstart
如何自动按需引入Vant组件库? webpack依赖babel-plugin-import的插件
把import按需引入方式, 自动转成只引入某个组件方式
5.弹出框使用
目标:完成效果
弹出框地址: https://vant-contrib.gitee.io/vant/#/zh-CN/dialog
main.js
import Vue from 'vue'
import App from './App.vue'
// 方式3: 引入所有vant组件
// import Vant from 'vant';
// import 'vant/lib/index.css'; // 引入vant所有组件样式
// Vue.use(Vant); // 全局注册vant所有组件
// 方式1: 全局 - 自动按需引入vant组件
// (1): 下载 babel-plugin-import
// (2): babel.config.js - 添加官网说的配置 (一定要重启服务器)
// (3): main.js 按需引入某个组件, Vue.use全局注册 - 某个.vue文件中直接使用vant组件
import { Button, Form, Field } from 'vant';
Vue.use(Button) // Button组件全局注册, 真正注册的组件名VanButton
Vue.use(Form);
Vue.use(Field);
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
App.vue
<template>
<div>
<van-button type="primary" @click="btn">主要按钮</van-button>
<van-button type="info">信息按钮</van-button>
<van-button type="default">默认按钮</van-button>
<van-button type="warning">警告按钮</van-button>
<van-button type="danger">危险按钮</van-button>
<hr />
<van-form @submit="onSubmit">
<van-field v-model="username" name="用户名" label="用户名" placeholder="用户名"
:rules="[{ required: true, message: '请填写用户名' }]" />
<van-field v-model="password" type="password" name="密码" label="密码" placeholder="密码"
:rules="[{ required: true, message: '请填写密码' }]" />
<div style="margin: 16px">
<van-button round block type="info" native-type="submit">提交</van-button>
</div>
</van-form>
</div>
</template>
<script>
// 方式2: 手动 按需引入
// import Button from 'vant/lib/button'; // button组件
// import 'vant/lib/button/style'; // button样式
// 目标: 使用弹出框
// 1. 找到vant文档
// 2. 引入
// 3. 在恰当时机, 调用此函数 (还可以用组件的用法)
import { Dialog } from "vant";
export default {
// components: { // 手动注册组件名
// // VanButton: Button
// // 等价的
// [Button.name]: Button
// }
data() {
return {
username: '',
password: '',
};
},
methods: {
onSubmit(values) { // 表单提交事件, values收集表单里的值
console.log('submit', values);
},
btn() {
Dialog({ message: "提示", showCancelButton: true }); // 调用执行时, 页面就会出弹出框
},
},
};
</script>
<style></style>
6.表单使用
目标: 使用Vant组件里的表单组件
具体 – 看表单组件地址: https://vant-contrib.gitee.io/vant/#/zh-CN/form
main.js
import Vue from 'vue'
import App from './App.vue'
// 方式3: 引入所有vant组件
// import Vant from 'vant';
// import 'vant/lib/index.css'; // 引入vant所有组件样式
// Vue.use(Vant); // 全局注册vant所有组件
// 方式1: 全局 - 自动按需引入vant组件
// (1): 下载 babel-plugin-import
// (2): babel.config.js - 添加官网说的配置 (一定要重启服务器)
// (3): main.js 按需引入某个组件, Vue.use全局注册 - 某个.vue文件中直接使用vant组件
import { Button, Form, Field } from 'vant';
Vue.use(Button) // Button组件全局注册, 真正注册的组件名VanButton
Vue.use(Form);
Vue.use(Field);
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
App.vue
<template>
<div>
<van-button type="primary" @click="btn">主要按钮</van-button>
<van-button type="info">信息按钮</van-button>
<van-button type="default">默认按钮</van-button>
<van-button type="warning">警告按钮</van-button>
<van-button type="danger">危险按钮</van-button>
<hr />
<van-form @submit="onSubmit">
<van-field v-model="username" name="用户名" label="用户名" placeholder="用户名"
:rules="[{ required: true, message: '请填写用户名' }]" />
<van-field v-model="password" type="password" name="密码" label="密码" placeholder="密码"
:rules="[{ required: true, message: '请填写密码' }]" />
<div style="margin: 16px">
<van-button round block type="info" native-type="submit">提交</van-button>
</div>
</van-form>
</div>
</template>
<script>
// 方式2: 手动 按需引入
// import Button from 'vant/lib/button'; // button组件
// import 'vant/lib/button/style'; // button样式
// 目标: 使用弹出框
// 1. 找到vant文档
// 2. 引入
// 3. 在恰当时机, 调用此函数 (还可以用组件的用法)
import { Dialog } from "vant";
export default {
// components: { // 手动注册组件名
// // VanButton: Button
// // 等价的
// [Button.name]: Button
// }
data() {
return {
username: '',
password: '',
};
},
methods: {
onSubmit(values) { // 表单提交事件, values收集表单里的值
console.log('submit', values);
},
btn() {
Dialog({ message: "提示", showCancelButton: true }); // 调用执行时, 页面就会出弹出框
},
},
};
</script>
<style></style>