vue|面试中会被问到的场景题🏆🏆

512 阅读6分钟

前端性能优化

从输入url到页面呈现经历的步骤:

DNS解析--->TCP建立连接--->http请求--->http响应--->渲染

DNS解析

可以设置DNS预解析;通过keep-alive建立长连接

涉及网络的有3个部分,dns解析,tcp建立连接,http请求/响应 前2个能做的优化非常有限,所以重点放在http请求和响应,主要包括2个方面:减少请求的次数,减少单次请求花费的时间

减少http请求的次数

(1)通过合并文件,将多个css,js文件合并成一个

(2) html、css、js文件的压缩,以及js代码的混乱,起到保护作用

(3)将多个小图片合并成雪碧图;使用图标字体文件

(4)浏览器缓存: 通过设置http header的expires和cache-control完成强缓存,当命中缓存,请求不会发送到服务器端,直接从缓存中读取,当没有命中缓存,会判断有没有协商缓存 通过设置http header的Etag和last-modified完成协商缓存,当命中缓存,服务器端返回304,资源从缓存中换取,当没有命中,服务器端直接返回资源内容

image.png

减少单次请求的花费的时间

主要是使用gzip

HTTP协议上的gzip编码是一种用来改进web应用程序性能的技术,web服务器和客户端(浏览器)必须共同支持gzip。目前主流的浏览器,Chrome,firefox,IE等都支持该协议。常见的服务器如Apache,Nginx,IIS同样支持gzip。

gzip压缩比率在3到10倍左右,可以大大节省服务器的网络带宽。而在实际应用中,并不是对所有文件进行压缩,通常只是压缩静态文件。

图片优化

(1)jpg、jpeg 有损压缩,体积小,加载快,不支持透明,适合背景图,轮播图,banner图

(2)png 无损压缩,体积大,加载慢,支持透明,适合logo,图标

(3)svg 文本文件,体积小,不失真, 可以写入html中

(4)Base64 文本文件,体积小,依赖编码

(5)webp google提供的,集中jpeg、png的优点,但是兼容性差

本地存储

(1)cookie 每次请求头都会携带cookie,所以cookie一定不会很大

(2)localstorage、sessionstorage, localstorage:持久化存储,一定存在,除非手动删除sessionstorage:会话存储,当前窗口关闭,就消失

CDN 内容分发网络

重点就是缓存和回流 ,缓存就是把根服务器的资源copy一份到当前服务器 ,回流就是没有资源就去根服务器请求

渲染

(1)将css放在顶部,js放下body的最后,html没有加载完所有css是不会渲染的,所以先加载css,js有阻塞性质,碰到script时,会立即执行,如果程序逻辑比较复杂且庞大就会耗费大量时间,阻塞下一步的执行

(2)减少重绘和回流

(3)能使用css实现的操作,不使用js

(4)减少操作DOM

1、如何保持页面当前的状态

  1. 将状态存储在LocalStorage / SessionStorage
  2. 通过路由传值
  3. 使用keep-alive

2、v-if、v-show、v-html的原理

  1. v-if会调用addIfCondition方法,生成VNode的时候会忽略对应节点,render的时候就不会渲染了
  2. v-show会生成真实的VNode,也会进行render,但是在render的过程中,会给节点添加show属性,也就是display
  3. v-html会先移除节点下的所有节点,调用html方法,通过addProps添加innerHTML属性,本质上还是设置innerHTML是v-html的值

3、v-if和v-show区别

手段

v-for是对DOM节点的操作,删除或者新增 v-if是控制display:none

编译条件

v-if是惰性的,如果初始条件为假,则不会进行编译,只有在第一次初始值为true的时候,才会进行局部编译,v-show在任何条件下,无论真假,首次都会进行编译,然后缓存,DOM元素也会保留

性能

v-if有更高的切换消耗,v-show有更高的渲染消耗

使用场景

v-if适合不经常改变的,v-show适合频繁的切换

4、初始化页面闪动问题

当网页还在加载vue.js,导致vue页面还来不及渲染,就会出现显示vue源代码的情况,我们可以利用v-cloak解决

html:
<div id="app" v-cloak>
{{context}}
</div>
css:
[v-cloak]{
display: none;
}

5、v-for和v-if的问题

1.优先级

v-for的优先级高于v-if的优先级

2.缺点

如果v-for和v-if同时使用,每次渲染都会先进行循环在进行条件判断,无论如何循环都不可避免,会带来性能问题

3.解决方案

(1)在外层增加template,在这一层进行v-if判断,然后在内部进行v-for

(2)如果条件出现在循环内部,可以使用计算属性提前过滤掉那些条件

6、权限控制

1.对权限管理的理解

具体来说就是控制用户能够使用系统的哪些功能,具体到页面,模块和按钮。

2.页面访问权限的实现

(1) 直接将路由表保存在服务器端,通过登录返回对应的路由表

(2) 设置路由守卫,通过用户的权限将对应的路由添加到路由表中

3.登录时

当用户填写完账号和密码后向服务器端验证是否正确,验证通过后,服务器端会返回一个token,拿到token后,会保存在cookie中,防止刷新页面,用户信息丢失。 根据token,去拉取user_info接口的数据,获取用户的信息,角色等。

权限验证:通过token获取用户对应的role,动态根据用户的role算出其对应有权限的路由,通过router.addRoutes动态挂载这些路由

4.页面级别权限控制

创建vue实例的时候,将vue-router挂载,但是这个时候,vue-router挂载是一些登录、404这些不需要权限的公共页面。

image (33).png

当用户登录的时候,获取用户的role,根据角色判断用户对哪些页面有权限,生成对应的路由表

image (34).png

调用router.addRoutes(store.getters.addRoutes)添加用户可以访问的路由

image (35).png

使用vuex管理路由表,根据vuex渲染侧边栏组件

image (37).png

image (36).png

5.属性级别的权限控制

如果是控制某个按钮管理员能够看到,普通用户看不到,那我们就拿到用户的roles,然后使用v-if控制

// html
<button v-if="role=='superAdmin'">权限按钮</button>
// js
export default{
computed:{
//当然实际工作中这里一般都使用mapState
role:this.$store.state.role
}
}

第二种思路:定义自定义指令

全局定义一个自定义指令

Vue.directive('per', {
bind: (el, binding, vnode) => {
//roles是我们的权限数组,binding.value是我们传入自定义指令的值
//如果找不到,那证明没有权限,把当前元素节点移除掉
if (roles.indexOf(binding.value)==-1) {
    el.parentNode.removeChild(el);
}
}
//这个传入的admin是对应上面binding.value
<div v-per="[admin]">
admin 可见
</div>

参考👀

www.jianshu.com/p/f56cde007…