Vue面试题-02
前言
马上要秋招了,搜集整理了一些Vue面试题,包括组件、指令、API等相关内容,巩固基础😎秋招冲冲冲!!!本篇包括:
✅计算属性和侦听器的区别
✅事件修饰符
✅单页应用(SPA) VS 多页应用(MPA)
✅如何解决SPA首屏加载速度慢
✅v-if和v-for的优先级
计算属性和侦听器的区别
计算属性(computed
)是自动监听依赖值的变化,从而动态返回内容(动态显示新的计算结果)。
监听(watch
)是一个过程,在监听的值变化时,可以触发一个回调,并做一些事情。回调函数有两个参数,一个 val
(修改后的 data
数据),一个 oldVal
(原来的 data 数据)。Vue 实例将会在实例化时调用$watch()
,遍历 watch
对象的每一个属性。
两者用于不同情况下完成计算,显示数据的操作。它们的区别主要来源于用法,只是需要动态值,那就用计算属性;需要知道值的改变后执行业务逻辑,才用 watch
,用反或混用虽然可行,但都是不正确的用法。
下面给出这两个特性的基本用法:
计算属性
1 | <div id="app"> {{total}} </div> |
侦听器
1 | <div id="app"> {{total}} </div> |
结合代码进行说明:
-
计算属性的应用场景是计算的内容需要依赖多个属性(num、price)的情况;侦听器的应用场景是计算的内容依赖一个属性(仅num发生变化、仅price发生变化)的情况
-
计算属性缓存结果时每次都会重新创建变量,而侦听器是直接计算,不会创建变量保存结果。也就意味着,数据如果会反复的发生变化,计算很多次的情况下,计算属性的开销将会更大,也就意味着这种情况不适合使用计算属性,适合使用侦听器。如果一个数据反复会被使用,但是它计算依赖的内容很少发生变化的情况下,计算属性会缓存结果,就更加适合这种情况。
如果 this.num 或者 this.price 没有发生变化,直接获取缓存的总结88作为计算属性的结果。
如果 this.num 或者 this.price 任何一项发生了变化,那么就会重新计算并得到一个总结结果,并重新将结果进行缓存。
-
computed
的结果是通过return返回的,而watch
不需要return。 -
watch
中的参数可以得到侦听属性改变的最新结果,而computed
函数没有这种参数。
补充:
computed
是一个对象时,有 get 和 set 两个选项。computed
与methods
相比:methods
是一个方法,它可以接受参数,而computed
不能;computed
是可以缓存的,methods
不会;一般在v-for
里,需要根据当前项动态绑定值时,只能用methods
而不能用computed
,因为computed
不能传参。computed
可以依赖其它computed
,甚至是其它组件的数据(data)。watch
是一个对象时,常用的配置有:handler
(执行的函数)、deep
(是否深度)、immediate
(是否立即执行)computed
默认深度依赖,watch
默认浅度观测
参考链接:
事件修饰符
常见的事件修饰符: .stop
、.prevent
、.capture
、.self
、.once
、.passive
举例提问:如何给下面这个自定义组件绑定一个原生的click
事件
1 | <custom-component>内容</custom-component> |
注意: @click
是自定义事件 click,并不是原生事件 click。绑定原生的 click 是 @click.native="xxx"
,同时补充说明 .exact
会有加分。
.exact
修饰符允许你控制由精确的系统修饰符组合触发的事件。
1 | <!-- 即使 Alt 或 Shift 被一同按下时也会触发 --> |
参考链接:
单页应用(SPA) VS 多页应用(MPA)
SPA(single-page application),翻译过来就是单页应用SPA
,是一种网络应用程序或网站的模型。
它通过动态重写当前页面来与用户交互,这种方法避免了页面之间切换时,打断用户体验。在单页应用中,所有必要的代码(HTML
、JavaScript
和CSS
)都通过单个页面的加载而检索,或者根据需要(通常是为响应用户操作)动态装载适当的资源,并添加到页面。
页面在任何时间点都不会重新加载,也不会将控制转移到其他页面。举个例子来讲,一个杯子,早上装的牛奶,中午装的是开水,晚上装的是茶,我们发现,变的始终是杯子里的内容,而杯子始终是那个杯子。再通俗一点,就是局部刷新。我们熟知的JS框架如react
,vue
,angular
,ember
都属于SPA
MPA(MultiPage-page application),翻译过来就是多页应用。在MPA
中,每个页面都是一个独立的主页面。当我们在访问另一个页面的时候,都需要重新加载html
、css
、js
文件,公共文件则根据需求按需加载。
单页应用和多页应用的区别
单页应用(SPA) | 多页应用(MPA) | |
---|---|---|
组成 | 一个主页面和多个页面片段 | 多个主页面 |
刷新方式 | 局部刷新 | 整页刷新 |
url模式 | 哈希模式 | 历史模式 |
SEO搜索引擎优化 | 难实现,可使用SSR方式改善 | 容易实现 |
数据传递 | 容易 | 通过url、cookie、localStorage等传递 |
页面切换 | 速度快,用户体验良好 | 切换加载资源,速度慢,用户体验差 |
维护成本 | 相对容易 | 相对复杂 |
优点 | 具有桌面应用的即时性、网站的可移植性和可访问性; 内容的改变不需要重新加载整个页面; 良好的前后端分离,分工更明确 |
首屏加载较快,SEO优化较好。 |
缺点 | 不利于搜索引擎的抓取; 首次渲染速度相对较慢(加载整个项目使用的css、js) |
页面跳转较慢 |
参考链接:
如何解决SPA首屏加载速度慢
首屏时间(First Contentful Paint),指的是浏览器从响应用户输入网址地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但需要展示当前视窗需要的内容。首屏加载可以说是用户体验中最重要的环节。
在页面渲染的过程,导致加载速度慢的原因是:网络延时问题、资源文件体积过大、重复发送请求以加载资源、加载脚本的时候,渲染内容堵塞了。
常见的几种SPA首屏优化方式
- 减小入口文件体积
- 静态资源本地缓存
- UI框架按需加载
- 图片资源的压缩
- 组件重复打包
- 开启GZip压缩
- 使用SSR
参考链接:
v-if和v-for的优先级
为什么不建议v-if和v-for一起使用?
vue在官方文档中明确指出,永远不要把 v-if
和 v-for
同时用在同一个元素上
在 Vue 2
中,v-for
优先于 v-if
被解析,即先执行循环,后判断条件。
举例说明
编写一个p
标签,同时使用v-if
与 v-for
1 | <div id="app"> |
创建vue
实例,存放isShow
与items
数据
1 | const app = new Vue({ |
模板指令的代码都会生成在render
函数中,通过app.$options.render
就能得到渲染函数
1 | ƒ anonymous() { |
_l
是vue
的列表渲染函数,函数内部都会进行一次if
判断
初步得到结论:v-for
优先级是比v-if
高
再将v-for
与v-if
置于不同标签
1 | <div id="app"> |
再输出下render
函数
1 | ƒ anonymous() { |
这时候我们可以看到,v-for
与v-if
作用在不同标签时候,是先进行判断,再进行列表的渲染
注意
- 永远不要把
v-if
和v-for
同时用在同一个元素上,带来性能方面的浪费(每次渲染都会先循环再进行条件判断) - 如果避免出现这种情况,则在外层嵌套
template
(页面渲染不生成dom
节点),在这一层进行v-if判断,然后在内部进行v-for循环
1 | <template v-if="isShow"> |
- 如果条件出现在循环内部,可通过计算属性
computed
提前过滤掉那些不需要显示的项
1 | computed: { |
参考链接: