目录
二.transition组件和transition-group组件
一.路由
1.1 路由概念
-
路由的本质就是一种对应关系,比如说我们在url地址中输入我们要访问的url地址之后,浏览器要去请求这个url地址对应的资源。 那么url地址和真实的资源之间就有一种对应的关系(映射关系),就是路由,比如生活中的路由。
-
路由分为前端路由和后端路由
-
后端路由是由服务器端进行实现,并完成资源的分发。
-
前端路由是依靠hash值(锚链接)和通过history对象的变化进行实现。
问题: vue的路由是什么?
路径和组件的映射关系
-
1.2 为什么要学习路由?
在一个页面里, 切换业务场景
单页面应用(SPA): 所有功能在一个html页面上实现
前端路由作用: 实现业务场景切换
优点:
-
整体不刷新页面,用户体验更好
-
数据传递容易, 开发效率高
缺点:
-
开发成本高(需要学习专门知识)
-
首次加载会比较慢一点。不利于seo
1.3 相关知识
1.3.1 路由的三个对象
路由中有三个基本的概念 route, routes, router
-
route,它是一条路由,由这个英文单词也可以看出来,它是单数, Home按钮 => home内容, 这是一条route, about按钮 => about 内容, 这是另一条路由。
-
routes 是一组路由,把上面的每一条路由组合起来,形成一个数组。[{home 按钮 =>home内容 }, { about按钮 => about 内容}]
-
router 是一个机制,相当于一个管理者,它来管理路由。因为routes 只是定义了一组路由,它放在哪里是静止的,当真正来了请求,怎么办? 就是当用户点击home 按钮的时候,怎么办?这时router 就起作用了,它到routes 中去查找,去找到对应的 home 内容,所以页面中就显示了 home 内容。
-
客户端中的路由,实际上就是dom 元素的显示和隐藏。当页面中显示home 内容的时候,about 中的内容全部隐藏,反之也是一样。客户端路由有两种实现方式:基于hash 和基于html5 history api.
1.3.2 组件分类
-
.vue文件本质无区别, 方便大家学习和理解, 总结的一个经验
-
src/views文件夹:页面组件 - 页面展示 - 配合路由用
-
src/components文件夹:复用组件 - 展示数据/常用于复用
1.4 Vue Router简介
它是一个Vue.js官方提供的路由管理器。是一个功能更加强大的前端路由器,推荐使用。 Vue Router和Vue.js非常契合,可以一起方便的实现SPA(single page web application 单页应用程序)应用程序的开发。
Vue Router的特性: 支持H5历史(history)模式或者hash模式 支持路由参数 支持声明式(命名)路由 支持编程式路由 支持嵌套路由 支持路由导航守卫
什么是SPA(单页应用程序)?
单页Web应用(single page web application,SPA),就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序。
1.5 路由实现的本质
1.5.1 Hash 模式
URL中 # 后面的内容作为路径地址,可以通过location.url
直接切换路由地址,如果只改变了#后面的内容,浏览器不会向服务器请求这个地址,会把这个地址记录到浏览器的访问历史中,当hash发生改变之后会触发hashchange事件,在hashchange事件中记录当前的路由地址,并找到,该路径对应的组件并重新渲染。
1.5.2 History 模式
History模式就是一个普通的url,通过history.pushState()
方法仅仅改变地址栏,并把地址栏中的地址添加到访问历史中,通过监听popstate,事件可以监听浏览器数据的变化,此时不会向服务器发送请求,只有当刷新页面或者点击浏览器前进后退按钮的时候该事件才会被触发向浏览器发送请求。
1.6 Vue Router的使用步骤
-
安装
npm install vue-router@3
//注意:
//vue-router 目前有 3.x 的版本和 4.x 的版本。其中:
//vue-router 3.x 只能结合 vue2 进行使用
//vue-router 4.x 只能结合 vue3 进行使用
-
导入路由
import VueRouter from 'vue-router'
-
使用路由插件
// 在vue中,使用vue的插件,都需要调用Vue.use()
//vue-router 就是 vuejs 官方提供的路由插件
Vue.use(VueRouter)
Vue.use的作用:注册全局组件, 使用第三方插件时,在Vue原型上增加引入的第三方。
-
创建路由规则数组
const routes = [
{
path: "/aboutus",
component: AboutUs
},
{
path: "/news",
component: News
},
{
path: "/contact",
component: Contact
}
]
-
创建路由对象 - 传入规则
const router = new VueRouter({
routes
})
-
关联到vue实例
new Vue({
router
})
-
components换成router-view
<router-view></router-view>
总结:
下载vue-router模块到当前工程
在main.js中引入VueRouter函数
添加到Vue.use()身上 – 注册全局RouterLink和RouterView组件
创建路由规则数组 – 路径和组件名对应关系
用规则生成路由对象
把路由对象注入到new Vue实例中
用router-view作为挂载点, 切换不同的路由页面
1.7 vue路由 -导航
1.7.1 声明式导航 - 基础使用
链接导航, 用router-link配合to, 实现点击切换路由
-
vue-router提供了一个全局组件 router-link
-
router-link实质上最终会渲染成a链接 to属性等价于提供 href属性(to无需#)
-
router-link提供了声明式导航高亮的功能(自带类名)-
router-link-exact-active
router-link-active
1.7.2 声明式导航 - 跳转传参
在跳转路由时, 可以给路由对应的组件内传值
在router-link上的to属性传值, 语法格式如下
-
/path?参数名=值
-
/path/值 – 需要路由对象提前配置 path: “/path/参数名”
对应页面组件接收传递过来的值
-
$route.query.参数名
-
$route.params.参数名
总结:
1.?key=value 用$route.query.key 取值
2./值 提前在路由规则/path/:key 用$route.params.key取值
1.7.3 动态路由绑定:to
<router-link :to="{path: '路由名',query: {}">跳转路由</router-link>
<router-link :to="{name: '路由名',params: {}">跳转路由</router-link>
1.8 vue路由 - 重定向和模式
1.8.1 路由 - 重定向
-
网页打开url默认hash值是/路径
-
redirect是设置要重定向到哪个路由路径
例如: 网页默认打开, 匹配路由"/", 强制切换到"/aboutus"上
const routes = [
{
path: "/", // 默认hash值路径
redirect: "/aboutus" // 重定向到/aboutus
// 浏览器url中#后的路径被改变成/aboutus
}
]
1.8.2 路由 - 404页面
如果路由hash值, 没有和数组里规则匹配
默认给一个404页面
语法: 路由最后, path匹配*(任意路径) – 前面不匹配就命中最后这个, 显示对应组件页面
-
创建NotFound页面
-
在main.js - 修改路由配置
import NotFound from '@/views/NotFound' const routes = [ // ...省略了其他配置 // 404在最后(规则是从前往后逐个比较path) { path: "*", component: NotFound } ]
1.8.3 路由 - 模式设置
hash路由例如: http://localhost:8080/#/home
history路由例如: http://localhost:8080/home (以后上线需要服务器端支持, 否则找的是文件夹)
router/index.js
const router = new VueRouter({
routes,
mode: "history"
})
1.9 vue路由 - 编程式导航
用JS代码跳转, 声明式导航用a标签
当你点击 <router-link>
时,内部会调用这个方法,所以点击 <router-link to="...">
相当于调用 router.push(...)
:
声明式 | 编程式 |
---|---|
<router-link to="..."> <router-link :to="..."> | router.push(...) |
1.9.1 编程式导航 - 基础使用
语法:
this.$router.push({
path: "路由路径",
name: "路由名"
})
main.js - 路由数组里, 给路由起名字
{
path: "",
name: "",
component:
},
1.9.2 编程式导航 - 跳转传参
传参2种方式query方式 ,params方式 ,任选 一个,注意: 使用path会自动忽略params
this.$router.push({
path: "路由路径"
name: "路由名",
query: {
"参数名": 值
}
params: {
"参数名": 值
}
})
// 对应路由接收 $route.params.参数名 取值
// 对应路由接收 $route.query.参数名 取值
1.9.3 多次点同一个路由出现错误及解决方案
vue-router
在3.1.0版本之后,vue-router的push和replace方法会返回一个promise对象,如果跳转到相同的路由,就报promise uncaught
异常。
解决方案:
在导入VueRouter的时候,进行全局的处理
const originalPush = VueRouter.prototype.push
// 重写原型上的push方法,统一处理错误信息
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
1.10. vue嵌套路由
1.10.1 嵌套路由
嵌套路由, 找准在哪个页面里写router-view和对应规则里写children
var routes = [{
path: "/aboutus",
component: AboutUs,
name: 'aboutus',
children: [{
path: 'child1',
component: Child1
}, {
path: 'child2',
component: Child2
}]
}]
1.10.2 路由中类名区别
router-link自带的2个类名的区别是什么
观察路由嵌套导航的样式
-
router-link-exact-active (精确匹配规则,即只有当前点击router被匹配)
-
router-link-active(包含匹配规则)
1.11. 路由守卫
1.11.1 路由钩子函数
路由钩子函数有三种分别是:
-
全局钩子: beforeEach(全局前置守卫)、 afterEach(全局后置钩子)
-
路由独享的守卫(在路由内配置时进行设置): beforeEnter
-
组件内路由:beforeRouteEnter、 beforeRouteUpdate、 beforeRouteLeave
1.11.2 路由全局前置守卫
路由跳转之前, 先执行一次前置守卫函数, 判断是否可以正常跳转
-
在路由对象上使用固定方法beforeEach
// 目标: 路由守卫
// 场景: 当你要对路由权限判断时
// 语法: router.beforeEach((to, from, next)=>{//路由跳转"之前"先执行这里, 决定是否跳转})
// 例子: 判断用户是否登录
const isLogin = true; // 登录状态(未登录)
router.beforeEach((to, from, next) => {
//添加守卫的条件
if (isLogin === false) {
alert("请登录")
next(false) // 阻止路由跳转
} else {
next() // 正常放行
}
})
总结: next()放行, next(false)留在原地不跳转路由
二.transition组件和transition-group组件
Vue 提供了 transition
的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡
-
条件渲染 (使用
v-if
) -
条件展示 (使用
v-show
) -
动态组件
-
组件根节点
那么怎么同时渲染整个列表,比如使用 v-for?在这种场景中,使用 <transition-group> 组件。
例如:
<div id="list-demo" class="demo">
<button v-on:click="add">Add</button>
<button v-on:click="remove">Remove</button>
<transition-group name="list" tag="p">
<span v-for="item in items" v-bind:key="item" class="list-item">
{{ item }}
</span>
</transition-group>
</div>