基础使用
可以理解为 div之间的切换
//路由的使用
//1. 安装 npm i vue-router
//2. 使用 a. 使用 vue.use(路由) 将路由添加成整个项目的全局功能
import Vue from 'vue'
import VueRouter from 'vue-router'
//b.定义路由组件,也就是将需要当作页面的组件导入
import Home from './components/Home.vue'
import About from './components/About.vue'
Vue.use(VueRouter)//Vue.use()主要实现了将路由组件注册成全局组件,给Vue 构造函数原型(Vue.prototype) 添加了一些路由相关属性:
// Vue.use({
// install:(vue)=>{
// vue.component(...)
// vue.prototype.$..
// }
// })
//c.定义路由, 就是定义页面 ,有哪些页面,哪个组件表示哪个页面
const routes = [
//路由对象
// component 属性 ,属性值是组件,
// path 属性,属性值是页面地址
{
component: Home,
//比如网站的网址 首页 https://juejin.cn 关于 https://juejin.cn/About
path: '/' // '/'表示跟地址: 协议+域名+端口号 没有路径(详见原生location)
}, {
component: About,
path: '/About'
}
]
//d.创建路由实例 将所定义好的路由数组制作成路由实例,
const router = new VueRouter({
routes: routes,//路由对象
mode: 'history' //路由模式 就是单页面模拟多页的方式 history 和 hash, hash是使用锚点模拟的,history 模式是使用浏览器历史记录实现的 和真正的多页是一个效果(但是 history需要后台服务器支持才能使用,非首页刷新的话会白屏404)
})
//e. 将创建好的路由实例 挂载到项目 Vue的根实例上(就是New Vue的时候)
export default router
//在main.js 中
//import router from './router'
//然后
// new Vue({
// render: h => h(App),
// router: router,
// }).$mount('#app')
//创建好路由之后,使用路由其实就是跳转和展示对应的页面,分别用路由自带的组件来实现,
//router-link 组件实现跳转,
//router-view 实现展示,会根据页面地址i耳环不容页面的展示,就是用页面给地址和对象的path
router-link 标签当做a来使用,a标签用href跳转, router-link 用to来跳转
<ul>
<li>
<router-link to="/">跳转到Home</router-link>
</li>
<li>
<router-link to="/About">跳转到About</router-link>
</li>
</ul>
效果如下,点击切换的时候并不会刷新页面,而是直接跳转
动态路由
//动态路由
//当很多页样式相同,只有数据不同的时候,比如文章详情页等,我们使用动态路由实现,也就是很多页展示一个组件。
//PostList 组件就是列表页,多个页面表示,那么他就不是一个path,path需要用变量,:type就是一个变量,当/后面跟任意值的时候,path都会匹配
{
component: PostList,
path: '/:type'
}
/后可写任意值,都会跳到对应的页面
<ul>
<li>
<router-link to="/">跳转到Home</router-link>
</li>
<li>
<router-link to="/frontend">跳转到前端</router-link>
</li>
<li>
<router-link to="/backend">跳转到后端</router-link>
</li>
</ul>
因为PostList组件被制作成了动态路由,那么在组件内就要根据不同页面更改展示内容,我们可以通过路由提供的全局路由数据,来获取路由的动态参数(也就是路由动态地址的变量)
全局路由1. $route 当前路由信息 2. $router 全部路由信息
$route 内
params属性,动态路由信息
query 属性 ,路由的查询部分
- type 动态路由信息的值
通常在生命周期中我们不好拿route的值,所以我们选择监听,在监听的时候修改数据达到页面修改效果
watch: {
//当监听一个数据的时候,这个数据可以是data、prop、路由相关数据,而且监听的数据不需要this,可以直接监听对象下的某一属性,用引号'对象.属性即可'
"$route.params.type": {
handler(newValue) {
console.log(newValue);
},
immediate: true,
},
},
嵌套路由
在定义路由的时候定义全部路由
路由的path 匹配机制是完全相等
要写嵌套子路由的话,需要给父路由添加 children 属性,属性值是数组
{
component: Home,
//比如网站的网址 首页 https://juejin.cn 关于 https://juejin.cn/About
path: '/',// '/'表示跟地址: 协议+域名+端口号 没有路径(详见原生location)
children: [
{
component: PostList,
//子页面的path是有限制的,比如父路由地址是'https://juejin.cn' 子路由地址是 'https://juejin.cn/About' 子路由地址写'About'即可
path: ':type'
}
]
}
router-view 默认展示最外层路由,想要展示子页面,需要在父组件Home中使用router-view
<div class="home">
<h3>Home</h3>
<ul>
<li>
<router-link to="/frontend">跳转到前端</router-link>
</li>
<li>
<router-link to="/backend">跳转到后端</router-link>
</li>
</ul>
<router-view></router-view>
</div>
路由的匹配机制是从上向下的
编程式导航
编程式导航的方式实现路由的一些广告功能
r
o
u
t
e
r
是
整
个
路
由
实
例
,
里
面
有
一
些
方
法
,
比
如
p
u
s
h
(
)
p
u
s
h
(
)
里
面
写
网
址
用
来
跳
转
b
a
c
k
(
)
后
退
g
o
(
)
前
进
‘
<
i
m
g
@
c
l
i
c
k
=
"
router 是整个路由实例,里面有一些方法,比如push() push()里面写网址用来跳转 back()后退 go()前进 ` <img @click="
router是整个路由实例,里面有一些方法,比如push()push()里面写网址用来跳转back()后退go()前进‘<img@click="router.push(’/’)" src="…/src/assets/logo.png" alt="" />`
这样可以实现点击图片回到首页功能
命名路由
-
在创建路由的时候,给路由一个name属性给路由命名.作用是当你想要跳转到这个路由的时候,不一定需要地址跳转,可以直接使用name跳转
<router-link :to="{ name: 'about' }">About</router-link>
-
当父级有默认子路由的时候,要给父级路由命名的话,不能直接写在父级路由对象内,要写在默认子集路由内
-
动态路由使用 命名路由跳转的时候,动态路由参数需要使用 params 传递type:
<router-link :to="{ name: 'postList', params: { type: 'frontend' } }" >前端</router-link >
路由组件传参
当我们的组件被制作成路由组件的时候,那么给组件传递参数就不能向之前一样使用 prop 以及自定义事件和插槽了
在路由组件中也可以传递参数,组件内页可以使用props 接收
在定义组件的时候,加一个props属性,值为true的时候能接收到动态路由参数,
props: {
type: {
type: String,
default: "recommended",
},
},
这时候我们只需要监听type即可,不用$route.params.type
props属性设置成对象的话,会将对象下的所有属性当作prop,但是只能在静态路由中使用
props设置为函数,该函数默认接收route作为参数,该函数的返回值需要写成对象,这个对象下的所有属性会被当作prop传为组件
props: (route) => (
{
type: route.params.type
})
route-link 属性
- v-slot
- to 域名
- replace 清楚历史记录
- tag 渲染成标签默认 a
- active-class 设置链接激活时的 css 类名,默认 router-link-active
- exact 修改route-link 的匹配规则
进阶使用
路由守卫
- 路由全局前置守卫(创建路由后挂载之前)
任何跳转都会触发
全局前置守卫默认传递一个函数作为参数,函数可以接收三个参数 - to 从哪来
- from 去哪里
- next 是一个方法,该方法必须在函数内执行,用于放行
router.beforeEach((to, from, next) => {
console.log(from)
console.log(to)
if (to.path === '/about') {
next('/')
}
console.log('全局前置触发')
next()
})
- 全局解析守卫
类似全局前置守卫 稍微比全局前置守卫往后一点(已经开始解析路由组件了),一般不选择该守卫
router.beforeResolve((to, from, next) => {
console.log(from)
console.log(to)
if (to.path === '/about') {
next('/')
}
next()
})
- 全局后置钩子
- 路由独享前置守卫
- 组件内的路由守卫
- 跳转之前
beforeRouteEnter
- 跳转更新(组件的复用)
beforeRouteUpdate
- 跳转离开
beforeRouteLeave
- 跳转之前
路由元信息
- 路由对象中的 meta 字段,一般 meta 字段内写的是权限相关属性可以自定义,一个页面地址可能匹配多个路由对象
- 我们使用
$toute.matched
,循环找到所有的 meta 字段 - 一般在路由独享前置守卫获取,
Vue动画和过度
用 transition 组件给它添加一些过渡效果
<button @click="show = !show">Toggle</button>
<transition name="fade">
<p v-show="show">Hello</p>
</transition>
动画过程可以看作
xx-enter 到 xx-enter-active 到xx-leave-active 到xx-leave-to
给对应类名加对应效果就行 active一般用来监听
/* p元素由两个过程 */
/*
1.消失到出现,添加对应的类名(xx指的是transition标签添加的name名) 开始效果xx-enter 到结束效果 xx-enter-active
xx-enter:在元素插入之前生效,将类名添加给元素,在元素被插入之后的下一帧消失
xx-enter-active:在整个进入过度的阶段生效
xx-to:2.1.8版本以上 定义进入过度的结束状态(用的不多)
***只需要设置开始的状态 以及过度的效果,因为元素默认展示出来的样式就是最后一帧
2. 出现到消失
xx-leave xx-leave-active xx-leave-to
***只需要设置消失结束(xx-leave-to)的状态 以及过度的效果,因为元素默认展示出来的样式就是第一帧
*/
.fade-enter-active,
.fade-leave-active {
transition: all 1s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.fade-leave-to {
transform: translateX(100px);
}
当实现效果使用的不是transiton 是 css animation的时候,就不用设置第一帧和最后一帧了,但是注意,动画结束的时候要和元素原来的效果一致才好看
@keyframes bounce-in {
0% {
transform: scale(1);
}
25% {
transform: scale(1.25);
}
50% {
transform: scale(1.5);
}
75% {
transform: scale(1.3);
}
100% {
transform: scale(1);
}
}
@keyframes jump {
0% {
transform: translateY(0);
opacity: 1;
}
25% {
transform: translateY(-20px);
opacity: 0.8;
}
50% {
transform: translateY(0px);
opacity: 0.5;
}
75% {
transform: translateY(20px);
opacity: 0.3;
}
100% {
transform: translateY(50px);
opacity: 0;
}
}
.fade-enter-active {
animation: bounce-in 1s linear;
}
.fade-leave-active {
animation: jump 1s linear;
}
我们想使用 animate.css 的动画
先在html中引入cdn ,然后直接修改进入离开时的类名
如果animate版本改变我们我需要改变,详看animate官网
<transition
name="fade"
enter-active-class="animated bounceInLeft"
leave-active-class="animated bounceOutRight"
>
<p v-show="show">Hello</p>
</transition>
当想要使用js 实现一些复杂动画效果,可以选择给transition 绑定一些钩子事件,在钩子事件中使用js动画
<transition name="fade" @enter="enter" :appear="true" mode="out-in">
@enter 是声明 JavaScript 钩子,appear 是刷新页面自动执行一次动画 mode是多个动画执行过度顺序,登上一个执行完再执行下一个
methods: {
enter(el, done) {
done();
},
},
列表动画
我们可以用 transition-group
<button @click="lists.push(10)">添加</button>
<button @click="lists.splice(1, 1)">删除</button>
<button @click="lists.reverse()">移动</button>
<transition-group tag="ul" name="list">
<li v-for="num in lists" :key="num">{{ num }}</li>
</transition-group>
.list-enter {
opacity: 0;
transform: translateX(-100px);
}
.list-enter-active,
.list-leave-active {
transition: all 1s;
}
.list-leave-to {
opacity: 0;
transform: translateX(100px);
}
列表移动动画
给xx-move类名添加监听即可
.list-move {
transition: all 1s;
}