【interview】2020.07.21 map、set 数据结构、cookie封装、首屏优化方案、定时器延时器、vue路由钩子、calc
一、css3 新增: 使用calc()计算宽高(vw/vh)
简单来说就是CSS3中新增的一个函数,calculate(计算)的缩写。
用于动态计算宽/高,你可以使用 calc() 给元素的各个属性设置值【margin、border、padding、font-size】等
- 主要用于计算不确定值,例如一个外边距为 10px, 宽度为 100% 的元素,这种情况我们怎么设置呢?如果设置了
.box { width: 100%; margin: 10px; }你可以看出这个box已经溢出了
- 那么怎么解决呢?就可以用calc函数了:
.box { width: calc(100% - (10 *2)px); margin: 10px; }父元素宽度的 100% - 左右的 10px
(1)calc() 语法
就是简单的四则运算
- 使用“+”、“-”、“*” 和 “/”四则运算;
- 可以使用百分比、px、em、rem等单位;
- 可以混合使用各种单位进行计算;
- 表达式中有 “+” 和 “-” 时,其前后必须要有空格,如"width: calc(12%+5em)" 这种没有空格的写法是错误的;
- 表达式中有 “*” 和 “/” 时,其前后可以没有空格,但建议留有空格。
(2)vw 和 vh是什么?
- vw:视窗宽度的百分比(1vw 代表视窗的宽度为 1%)
- vh:视窗高度的百分比
- vmin:取当前Vw和Vh中较小的那一个值
- vmax:取当前Vw和Vh中较大的那一个值
vw、vh、vmin、vmax是一种视窗单位,也是相对单位。
它相对的不是父节点或者页面的根节点。
而是由视窗(Viewport)大小来决定的,单位 1,代表类似于 1%。
- 视窗(Viewport)是你的浏览器实际显示内容的区域
- 换句话说是你的不包括工具栏和按钮的网页浏览器
(3)vw、vh 与 % 百分比的区别
- % 是相对于父元素的大小设定的比率
- vw、vh 是视窗大小决定的。
- vw、vh 优势在于能够直接获取高度
- % 在没有设置 body 高度的情况下,是无法正确获得可视区域的高度的
面试注意:
- ajax 请求最好放在 created 里面,因为此时已经可以访问 this 了,请求到数据就可以直接放在 data 里面。
- 关于 dom 的操作要放在 mounted 里面,在 mounted 前面访问 dom 会是 undefined
- beforeDestory 可以访问this,destroyed 不可以访问 this,因为组件已经被销毁了。特殊情况:
keep-alive 缓存了的组件:
- 缓存了组件之后,再次进入组件不会触发 beforeCreate、created 、beforeMount、 mounted,
如果你想每次进入组件都做一些事情的话,你可以放在 activated 进入缓存组件的钩子中。
- 同理:离开缓存组件的时候,beforeDestroy和destroyed并不会触发,
可以使用 deactivated 离开缓存组件的钩子来代替。 =
二、生命周期函数钩子(触发钩子的完整顺序:)
将路由导航、keep-alive、和组件生命周期钩子结合起来的
beforeEach
: 路由全局前置守卫,可用于登录验证、全局路由loading等。
beforeEnter
: 路由独享守卫
beforeRouteEnter
: 路由组件的组件进入路由前钩子。
beforeResolve
: 路由全局解析守卫
afterEach
: 路由全局后置钩子
beforeCreate
: 不能访问this
。created
: 可以访问this
,不能访问 dom。beforeMount
:
mounted
: 访问/操作domactivated
: 进入缓存组件,进入a的嵌套子组件(如果有的话)。beforeRouteLeave
: 路由组件的组件离开路由前钩子,可取消路由离开。
deactivated
: 离开缓存组件a ---- 或者 ---- 触发 a 的beforeDestroy
和destroyed
组件销毁钩子。
- 在被 keep-alive 包含的组件/路由中,会多出两个生命周期的钩子: activated 与 deactivated
<keep-alive>
<router-view></router-view>
</keep-alive>
使用keep-alive可以将所有路径匹配到的路由组件都缓存起来,包括路由组件里面的组件,keep-alive大多数使用场景就是这种
- activated 在组件第一次渲染时会被调用,之后在每次缓存组件被激活时调用。
(1)调用时机(第一次进入缓存 路由/组件):
在mounted后面,beforeRouteEnter 守卫传给 next 的回调函数之前调用
-
beforeMount => 如果你是从别的 路由/组件 进来(组件销毁 destroyed/ 或离开缓存deactivated) => mounted => activated 进入缓存组件 => 执行 beforeRouteEnter 回调
因为组件被缓存了,再次进入缓存路由/组件时,不会触发这些钩子:
// beforeCreate
// created
// beforeMount
// mounted
(2)之后的调用时机是:
-
组件销毁 destroyed /或 离开缓存 deactivated => activated 进入当前缓存组件 => 执行 beforeRouteEnter回调 // 组件缓存或销毁,嵌套组件的销毁和缓存也在这里触发
- deactivated:组件被停用(离开路由)时调用
使用了 keep-alive 就不会调用 beforeDestroy(组件销毁前钩子) 和 destroyed(组件销毁),因为组件没被销毁,被缓存起来了。
- 这个钩子可以看作 beforeDestroy 的替代,如果你缓存了组件,要在组件销毁的的时候做一些事情,你可以放在这个钩子里
- 如果你离开了路由,会依次触发:
-
组件内的离开当前路由钩子beforeRouteLeave => 路由前置守卫 beforeEach => 全局后置钩子afterEach => deactivated 离开缓存组件 => activated 进入缓存组件(如果你进入的也是缓存路由) // 如果离开的组件没有缓存的话 beforeDestroy会替换deactivated // 如果进入的路由也没有缓存的话 全局后置钩子afterEach =>销毁 destroyed
=> beforeCreate 等 - 全局导航守卫(三个守卫):
- router.beforeEach 全局前置守卫 进入路由之前
- router.beforeResolve 全局解析守卫(2.5.0+) 在 beforeRouteEnter 调用之后调用
- router.afterEach 全局后置钩子 进入路由之后
使用方法:
-
// main.js 入口文件 import router from './router'; // 引入路由 router.beforeEach((to, from, next) => { next(); }); router.beforeResolve((to, from, next) => { next(); }); router.afterEach((to, from) => { console.log('afterEach 全局后置钩子'); });
- 路由对象
指的是平时通过 this.$route 获取到的路由对象
- 参数解析:
- to
将要进入的路由对象
- from
将要离开的路由对象
- next
:Function 这个参数是个函数,且必须调用,否则不能进入路由(页面空白)
- next() 进入该路由
- next(false): 取消进入路由,url地址重置为from路由地址(也就是将要离开的路由地址)
- next 跳转新路由,当前的导航被中断,重新开始一个新的导航
-
// 我们可以这样跳转: next('path地址') // 或者 next({path:''}) // 或者 next({name:''}) // 且允许设置诸如 replace: true、name: 'home' 之类的选项 // 以及你用在router-link或router.push的对象选项。
- 路由独享守卫
-
const router = new VueRouter({ routes: [ { path: '/home', component: Hom e, beforeEnter: (to, from, next) => { // 参数用法什么的都一样,调用顺序在全局前置守卫后面,所以不会被全局守卫覆盖 // ... } } ] });
- 组件内导航守卫:
- beforeRouteEnter 进入路由前
- beforeRouteUpdate (2.2) 路由复用同一个组件时
- beforeRouteLeave 离开当前路由时
作用: 导航离开该组件的对应路由时调用,我们用它来
- 禁止用户离开,比如还未保存草稿
-
beforeRouteLeave (to, from , next) { if (文章保存) { next(); // 允许离开或者可以跳到别的路由 上面讲过了 } else { next(false); // 取消离开 } }
- 在用户离开前,将 setInterval 销毁,防止离开之后,定时器还在调用
介绍:
-
beforeRouteEnter (to, from, next) { // 在路由独享守卫后调用 不!能!获取组件实例 `this`,组件实例还没被创建 },
beforeRouteUpdate (to, from, next) { // 在当前路由改变,但是该组件被复用时调用 可以访问组件实例 `this` // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候, // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。 },
beforeRouteLeave (to, from, next) { // 导航离开该组件的对应路由时调用,可以访问组件实例 `this` }
1
1
四、定时器、延时器
d
五、首屏优化方案
- 减少请求数量:合并资源,减少HTTP请求,懒加载,内联资源等
- 减少请求资源大小:压缩资源,gzip,webp图片,减少cookie等
- 提高请求速度:DNS预解析,资源预加载,CDN加速等
- 缓存:浏览器缓存,manifest缓存等
分成 HTML 的缓存,JS/CSS/image 资源的缓存,以及 json 数据的缓存
- 渲染:css、js加载顺序,服务端渲染
六、cookie 的封装
c
七、es6 的数据结构 Set
s
八、es6 的数据结构 Map
m
九、数组的方法(作用及其返回值)
1