目录
3、v-show 是display:none // display opacity visibility
15、浏览器存储方法 localstorage、sessionstorage、
1、vue router路由钩子
vue router路由钩子,导航守卫。vue-router
提供的导航守卫主要用来通过跳转或取消的方式守卫导航。
记住参数或查询的改变并不会触发进入/离开的导航守卫。你可以通过观察 $route
对象来应对这些变化,或使用 beforeRouteUpdate
的组件内守卫。
路由钩子函数有三种:
1:全局钩子: beforeEach、 afterEach
2:单个路由里面的钩子: beforeEnter、 beforeLeave
3:组件路由:beforeRouteEnter、 beforeRouteUpdate、 beforeRouteLeave
(1)全局前置守卫 router.beforeEach()
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。
每个守卫方法接收三个参数:
-
to: Route
: 即将要进入的目标 路由对象 -
from: Route
: 当前导航正要离开的路由 -
next: Function
: 一定要调用该方法来 resolve 这个钩子。执行效果依赖next
方法的调用参数。-
next()
: 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。 -
next(false)
: 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到from
路由对应的地址。 -
next('/')
或者next({ path: '/' })
: 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向next
传递任意位置对象,且允许设置诸如replace: true
、name: 'home'
之类的选项以及任何用在router-link
的to
prop 或router.push
中的选项。 -
next(error)
: (2.4.0+) 如果传入next
的参数是一个Error
实例,则导航会被终止且该错误会被传递给router.onError()
注册过的回调。
-
(2)全局解析守卫 router.beforeResolve
在 2.5.0+ 你可以用 router.beforeResolve
注册一个全局守卫。这和 router.beforeEach
类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
(3)全局后置钩子 router.afterEach
你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next
函数也不会改变导航本身:这些守卫与全局前置守卫的方法参数是一样的。
(4)组件内的守卫
beforeRouteEnter
beforeRouteUpdate
(2.2 新增)beforeRouteLeave
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
完整的导航解析流程
- 导航被触发。
- 在失活的组件里调用离开守卫。
- 调用全局的
beforeEach
守卫。 - 在重用的组件里调用
beforeRouteUpdate
守卫 (2.2+)。 - 在路由配置里调用
beforeEnter
。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter
。 - 调用全局的
beforeResolve
守卫 (2.5+)。 - 导航被确认。
- 调用全局的
afterEach
钩子。 - 触发 DOM 更新。
- 用创建好的实例调用
beforeRouteEnter
守卫中传给next
的回调函数。
2、浏览器强弱缓存
浏览器向服务器请求某一资源时,会先判断本地有无该资源缓存,如果已有缓存,则获取该资源缓存的 header 信息,根据 header 中的 Control 和 Expires (即强缓存)来判断是否过期。这一时刻是没有向服务器发出请求的。
若显示已过期,浏览器会向服务器发送请求,通过 header 中的 Etag 和 Last-Modified(协商缓存)让服务器验证。若不需更新资源,返回状态码 304;若需要更新,则返回最新资源和状态码 200
浏览器缓存主要分为强缓存(也称本地缓存)和协商缓存(也称弱缓存)。
强缓存
http1.1 | http1.0 | |
---|---|---|
强缓存 | Cache-Control 强缓存利用的是max-age的值来实现缓存资源的最大生命周期,单位是秒。 |
Expires 它的值是一个绝对时间的GMT格式的时间字符串,代表资源失效时间。 |
协商缓存 | Etag/If None Match 当资源被缓存时,服务器返回的 header 上有 Etag。 当资源文件向服务器确认缓存是否可用时,会向服务器发送一个 request header 带有 If-None-Match 字段,值为当前文件的 Etag。服务器根据浏览器上送的If-None-Match 值来判断是否命中缓存。 |
Last Modify/If Modify Since 浏览器第一次请求一个资源的时候,response header 会加上 Last-Modify,Last-modify 是一个时间标识该资源的最后修改时间。 当浏览器再次请求该资源时,request 的请求头中会包含 If-Modify-Since,该值为缓存之前返回的 Last-Modify。服务器收到If-Modify-Since 后,根据资源的最后修改时间判断是否命中缓存。 |
弱缓存
Last-Modify/If-Modify-Since
Last-Modify(实体首部)/If-Modify-Since(请求首部)是 http1.0 的规范,格式:Last-Modify: Fri, 19 Apr 2019 01:34:53 GMT
浏览器第一次请求一个资源的时候,response header 会加上 Last-Modify,Last-modify 是一个时间标识该资源的最后修改时间。
当浏览器再次请求该资源时,request 的请求头中会包含 If-Modify-Since,该值为缓存之前返回的 Last-Modify。服务器收到If-Modify-Since 后,根据资源的最后修改时间判断是否命中缓存。
如果命中缓存,返回304,则不会返回资源内容,并且不会返回 Last-Modify。
Etag和If-None-Match
Etag(响应首部)/If-None-Match(请求首部)是 http1.1 的规范,返回的是一个校验码,保证每一个资源是唯一的,格式: Etag:22FAA065-2664-4197-9C5E-C92EA03D0A16。
当资源被缓存时,服务器返回的 header 上有 Etag。当资源文件向服务器确认缓存是否可用时,会向服务器发送一个 request header 带有 If-None-Match 字段,值为当前文件的 Etag。服务器根据浏览器上送的If-None-Match 值来判断是否命中缓存。
与 Last-Modified 不一样的是,当命中缓存,服务器返回 304 Not Modified 的响应时,由于 ETag 重新生成过,response header 中还会把这个 ETag 返回,即使这个 ETag 跟之前的没有变化。
重点是,Etag 的优先级高于 Last-Modify,同时存在则优先判断 Etag,再判断 Last-Modify ,最后才决定是否返回304
3、v-show 是display:none // display opacity visibility
相同点:v-if与v-show都可以动态控制dom元素显示隐藏
不同点:v-if显示隐藏是将dom元素整个添加或删除(比如div会被删掉),而v-show隐藏则是为该元素添加css--display:none,dom元素还在。
需要注意的是,当一个元素默认在css中加了display:none属性,这时通过if-show修改为true是无法让元素显示的。原因是显示隐藏切换,只是会修改element style为display:""或者display:none,并不会覆盖掉或修改已存在的css属性。
详细区别:
1.手段:v-if是动态的向DOM树内添加或者删除DOM元素;v-show是通过设置DOM元素的display样式属性控制显隐;
2.编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;
3.编译条件:v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,然后再切换的时候进行局部卸载); v-show是在任何条件下(首次条件是否为真)都被编译,然后被缓存,而且DOM元素保留;
4.性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗;
5.使用场景:v-if适合运营条件不大可能改变;v-show适合频繁切换。
1.display:none是彻底消失,不在文档流中占位,浏览器也不会解析该元素;
visibility:hidden是视觉上消失了,可以理解为透明度为0的效果,在文档流中占位,浏览器会解析该元素;
2.使用visibility:hidden比display:none性能上要好,
display:none切换显示时,页面产生回流(当页面中的一部分元素需要改变规模尺寸、布局、显示隐藏等,页面重新构建,此时就是回流。所有页面第一次加载时需要产生一次回流),
而visibility切换是否显示时则不会引起回流。
3.opacity: 0 是透明度为0
具体来说应该是:
1 opacity=0,该元素隐藏起来了,但不会改变页面布局,并且,如果该元素已经绑定一些事件,如click事件,
那么点击该区域,也能触发点击事件的
2 visibility=hidden,该元素隐藏起来了,但不会改变页面布局