![e1c4d1e7da899366dbada9b3c881a9b9.gif](https://i-blog.csdnimg.cn/blog_migrate/cf2712fee84b7361ea3bd4ee3bf5bbe0.gif)
Young村长来给大家上课啦!有没有想念和蔼可亲才高八斗的村长呢?
今天村长继续来跟大家谈一谈:
面对面试官的“陷阱提问”,怎么回答才能做到鹤立鸡群,在求职者中脱颖而出?
【上一期的文章链接戳这里】
话不多说,直接开讲!
![d4a01a16c617e79bcaeef3c279e13c00.png](https://i-blog.csdnimg.cn/blog_migrate/0d42506a8e8e129d4b07c4493b335ad6.jpeg)
谈一谈对vue组件化的理解?
听到“理解”两个字我们就要注意了,看似一道开放性的问题,实际是要考察我们对VUE组件化的认知基础。
我们可以从定义、优点、使用场景和注意事项等方面展开陈述,同时要强调vue中组件化的一些特点。
始终不变的是“从源码深入解决问题,最终达到深入浅出的效果。”
源码分析1:组件定义
src\core\global-api\assets.js
(☝文件中的位置)
// 组件定义
Vue.component('comp', {
template: '
})
vue-loader会编译template为render函数,最终导出的依然是组件配置对象。☟
this is a component
源码分析2:组件化优点
lifecycle.js - mountComponent()
☝组件、Watcher、渲染函数和更新函数之间的关系
源码分析3:组件化实现
构造函数,
src\core\global-api\extend.js
实例化及挂载,
src\core\vdom\patch.js - createElm()
正确解答:
1、组件是独立和可复用的代码组织单元。组件系统是 Vue 核心特性之一,它使开发者使用小型、独立和通常可复用的组件构建大型应用;
2、组件化开发能大幅提高应用开发效率、测试性、复用性等;
3、组件使用按分类有:页面组件、业务组件、通用组件;
4、vue的组件是基于配置的,我们通常编写的组件是组件配置而非组件,框架后续会生成其构造函数,它们基于VueComponent,扩展于Vue;
5、vue中常见组件化技术有:属性prop,自定义事件,插槽等,它们主要用于组件通信、扩展等;
6、合理的划分组件,有助于提升应用性能;
7、组件应该是高内聚、低耦合的;
8、遵循单向数据流的原则。
![02c7b96a2d855e91ce9390d9f2053b90.png](https://i-blog.csdnimg.cn/blog_migrate/c83c6d3bcea1145fabed9cb13449c93c.jpeg)
谈一谈对vue设计原则的理解?
和上一题的思路一样,我们首先要明确:关于VUE设计原则,我们要从哪几个方面入手进行详细解答?
而在vue的官网上,就写着大大的定义和特点:
渐进式JavaScript框架
易用、灵活和高效
所以阐述此题的整体思路按照这个展开即可。
正确解答:
首先就是渐进式JavaScript框架:
与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。
Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
![1550320064159eda7464ecd25a0da066.png](https://i-blog.csdnimg.cn/blog_migrate/e81cf5af92e812fcc45bbbc50a31961e.jpeg)
易用性
vue提供数据响应式、声明式模板语法和基于配置的组件系统等核心特性。
这些使我们只需要关注应用的核心业务即可,只要会写js、html和css就能轻松编写vue应用。
灵活性
渐进式框架的最大优点就是灵活性,如果应用足够小,我们可能仅需要vue核心特性即可完成功能;
随着应用规模不断扩大,我们才可能逐渐引入路由、状态管理、vue-cli等库和工具;
不管是应用体积还是学习难度都是一个逐渐增加的平和曲线。
高效性
超快的虚拟 DOM 和 diff 算法使我们的应用拥有最佳的性能表现。
追求高效的过程还在继续,vue3中引入Proxy对数据响应式改进以及编译器中对于静态内容编译的改进都会让vue更加高效。
![301069b1dbdb0784ec8e150d7d54cc72.png](https://i-blog.csdnimg.cn/blog_migrate/990fd168d4e0d6d067d133aff81ed938.jpeg)
对MVC、MVP和MVVM的理解
当我们面对这道考题时,往往有些摸不着头脑,因为MVC、MVP和MVVM的知识点非常广泛,很难做到说清、说透。
那要怎么才能回答的简洁有条理?让面试官眼前一亮呢?
来听村长给你清晰解读一下这道题的正确思路吧!
其实在日常工作中,类似MVP、MVC这类前端程序,我们程序员甚至自己都没用过,这恰恰就反映了:
前端这些年从无到有,从有到优的变迁过程。
想到这里,我们的解题思路便慢慢浮出水面了,那就是:
按时间顺序,浅谈MVC、MVP、MVVM等系列产品的更新迭代。
Web1.0时代
在web1.0时代,并没有前端的概念。
开发一个web应用多数采用:
ASP.NET/Java/PHP编写,
项目通常由多个aspx/jsp/php文件构成。
每个文件中同时包含了HTML、CSS、JavaScript、C#/Java/PHP代码。
系统整体架构可能是这样子的☟:
![2c3c9352e6b85860737d845541752782.png](https://i-blog.csdnimg.cn/blog_migrate/d7205aec4d21f544aeb359e109e016a4.jpeg)
这种架构的好处是简单快捷,但是,缺点也非常明显:JSP代码难以维护
为了让开发更加便捷,代码更易维护,前后端职责更清晰。便衍生出MVC开发模式和框架,前端展示以模板的形式出现。
典型的框架就是:
Spring、Structs、Hibernate。
整体框架如图所示☟:
![d78c35a1e65b7ca25c11499409bfc870.png](https://i-blog.csdnimg.cn/blog_migrate/5cda5754442a62d9c3bad9972dfadbe6.jpeg)
使用这种分层架构,职责清晰,代码易维护。
但这里的MVC仅限于后端,前后端形成了一定的分离,前端只完成了后端开发中的view层。
但是,同样的这种模式存在着一些问题:
1、前端页面开发效率不高
2、前后端职责不清
web 2.0时代
自从Gmail的出现,ajax技术开始风靡全球。有了ajax之后,前后端的职责就更加清晰了。
因为前端可以通过Ajax与后端进行数据交互,因此,整体的架构图也变化成了下面这幅图☟:
![85fac81ed016ba1fc44ae98a7e926267.png](https://i-blog.csdnimg.cn/blog_migrate/d5e122071f0667b05e229174c1821de0.jpeg)
通过ajax与后台服务器进行数据交换,前端开发人员,只需要开发页面这部分内容,数据可由后台进行提供。
而且ajax可以使得页面实现部分刷新,减少了服务端负载和流量消耗,用户体验也更佳。
这时,才开始有专职的前端工程师。同时前端的类库也慢慢的开始发展,最著名的就是jQuery了。
当然,此架构也存在问题:缺乏可行的开发模式承载更复杂的业务需求,页面内容都杂糅在一起,一旦应用规模增大,就会导致难以维护了。
因此,前端的MVC也随之而来。
前后端分离后的架构演变——MVC、MVP和MVVM
MVC
前端的MVC与后端类似,具备着View、Controller和Model。
Model:负责保存应用数据,与后端数据进行同步
Controller:负责业务逻辑,根据用户行为对Model数据进行修改
View:负责视图展示,将model中的数据可视化出来。
三者形成了一个如图所示的模型:
![f8cd441fe13f68ec5a307bafdfb197b0.png](https://i-blog.csdnimg.cn/blog_migrate/8a8acc23f2292a068ae3509a42957e00.jpeg)
这样的模型,在理论上是可行的。但往往在实际开发中,并不会这样操作。因为开发过程并不灵活。
例如,一个小小的事件操作,都必须经过这样的一个流程,那么开发就不再便捷了。
在实际场景中,我们往往会看到另一种模式,
如图所示☟:
![769c812ceac0a715a03c71106df8396e.png](https://i-blog.csdnimg.cn/blog_migrate/688f0cccd77c91e0989cc83cbe30e68c.jpeg)
这种模式在开发中更加的灵活,backbone.js框架就是这种的模式。
但是,这种灵活可能导致严重的问题:
1、数据流混乱:如下图☟
![5b4b355f9db9e1b2e174d89e42074a0e.png](https://i-blog.csdnimg.cn/blog_migrate/398f85e856530af783e5787a56e92dfd.jpeg)
![059f2ed873a0ffda8d051c3126358265.png](https://i-blog.csdnimg.cn/blog_migrate/b97fd3e58b521a64969bdbc47f6c012d.jpeg)
2、View比较庞大,而Controller比较单薄:
由于很多的开发者都会在view中写一些逻辑代码,逐渐的就导致view中的内容越来越庞大,而controller变得越来越单薄。
既然有缺陷,就会有变革。
前端的变化中,似乎少了MVP的这种模式,是因为AngularJS早早地将MVVM框架模式带入了前端。
MVP模式虽然前端开发并不常见,但是在安卓等原生开发中,开发者还是会考虑到它。
MVP
MVP与MVC很接近,P指的是Presenter,presenter可以理解为一个中间人。
它负责着View和Model之间的数据流动,防止View和Model之间直接交流。
我们可以看一下图示☟
![ae7ef03cb4bc2d4e96694d9711f2c611.png](https://i-blog.csdnimg.cn/blog_migrate/c269e31235a535dd8e7bbc32f9ec9795.jpeg)
我们可以通过看到,presenter负责和Model进行双向交互,还和View进行双向交互。
这种交互方式,相对于MVC来说少了一些灵活,VIew变成了被动视图,并且本身变得很小。虽然它分离了View和Model。
但是应用逐渐变大之后,导致presenter的体积增大,难以维护。
要解决这个问题,或许可以从MVVM的思想中找到答案。
MVVM
首先,何为MVVM呢?MVVM可以分解成(Model-View-VIewModel)。
ViewModel可以理解为在presenter基础上的进阶版。如图所示☟☟:
![ef0f04c6f1cfce68982829b26eed211c.png](https://i-blog.csdnimg.cn/blog_migrate/8a094a25e5aa82f711dfc098e6f453bc.png)
ViewModel通过实现一套数据响应式机制自动响应Model中数据变化;
同时Viewmodel会实现一套更新策略自动将数据变化转换为视图更新;
通过事件监听响应View中用户交互修改Model中数据。
这样在ViewModel中就减少了大量DOM操作代码。
MVVM在保持View和Model松耦合的同时,还减少了维护它们关系的代码,使用户专注于业务逻辑,兼顾开发效率和可维护性。
总结:
这三者都是框架模式,它们设计的目标都是为了解决Model和View的耦合问题。
MVC模式出现较早主要应用在后端,如Spring MVC、ASP.NET MVC等,在前端领域的早期也有应用,如Backbone.js。
它的优点是分层清晰,缺点是数据流混乱,灵活性带来的维护性问题。
MVP模式在是MVC的进化形式,Presenter作为中间层负责MV通信,解决了两者耦合问题,但P层过于臃肿会导致维护问题。
MVVM模式在前端领域有广泛应用,它不仅解决MV耦合问题,还同时解决了维护两者映射关系的大量繁杂代码和DOM操作代码,在提高开发效率、可读性同时还保持了优越的性能表现。
![325840a292c59e5459103074cc0175e0.png](https://i-blog.csdnimg.cn/blog_migrate/4ae10ffc749b4e3eaaab5413d76c61ab.jpeg)
你了解哪些Vue性能优化方法?
相对其他的“陷阱面试题”,这个问题就显得友善了很多,只要我们基础功底扎实,回答得井井有条并不是难事。
首先,我们要找到VUE性能的现存问题,大部分都是代码层面的,然后具体的提出代码层优化意见就可以了。
目前我们所知的VUE代码层优化大致为一下11点,村长已经都帮大家整理好了,请大家随意消化一下:
●路由懒加载
●keep-alive缓存页面
●使用v-show复用DOM
●v-for 遍历避免同时使用 v-if
●长列表性能优化
●事件的销毁
●图片懒加载
●第三方插件按需引入
●无状态的组件标记为函数式组件
●子组件分割
●变量本地化
●SSR
下面是针对这11个优化点给出的具体优化方案:
●路由懒加载☟
const router = new VueRouter({
routes: [
{ path: '/foo', component: () => import('./Foo.vue') }
]
})
●keep-alive缓存页面☟
●使用v-show复用DOM☟
![adfcaa8bd98d058604ee054e8c22321a.png](https://i-blog.csdnimg.cn/blog_migrate/d8fbc2d988ae90ccd03de23d69cdc794.png)
●v-for 遍历避免同时使用 v-if☟
![36e4753a90b3b9bb8322c219113ee1b7.png](https://i-blog.csdnimg.cn/blog_migrate/2b1df536e9256b13cb09a55e2a74d227.png)
●长列表性能优化:
如果列表是纯粹的数据展示,不会有任何改变,就不需要做响应化☟
![8de66d9813d8bfe7db67cd58491dff57.png](https://i-blog.csdnimg.cn/blog_migrate/0d064b530937c88e7c6662281d893879.png)
如果是大数据长列表,可采用虚拟滚动,只渲染少部分区域的内容☟
![703d250080e41db6421caf845624e7d9.png](https://i-blog.csdnimg.cn/blog_migrate/a57decacbd72285d3b55054fd6322d6a.png)
参考:
vue-virtual-scroller☟
https://github.com/Akryum/vue-virtual-scroller
vue-virtual-scroll-list☟
https://github.com/tangbc/vue-virtual-scroll-list
●事件的销毁:
Vue 组件销毁时,会自动解绑它的全部指令及事件监听器,但是仅限于组件本身的事件。
created() {
this.timer = setInterval(this.refresh, 2000)
},
beforeDestroy() {
clearInterval(this.timer)
}
●图片懒加载:
对于图片过多的页面,为了加速页面加载速度。
所以很多时候我们需要将页面内未出现在可视区域内的图片先不做加载, 等到滚动到可视区域后再去加载。
参考项目:
vue-lazyload☟
https://github.com/hilongjw/vue-lazyload
●第三方插件按需引入:
像element-ui这样的第三方组件库可以按需引入,避免体积太大。
import Vue from 'vue';
import { Button, Select } from 'element-ui';
Vue.use(Button)
Vue.use(Select)
●无状态的组件标记为函数式组件☟
![0972d332eb601da0b4fed84faeb07182.png](https://i-blog.csdnimg.cn/blog_migrate/8f93bcc8d8e7e4a1e76faa8b485a1162.png)
●子组件分割
![5a125236ab4cad4c2ffea4ee6c0d0406.png](https://i-blog.csdnimg.cn/blog_migrate/cdc9b4c6c0a6f5ca81c548e6bea4ed62.png)
●变量本地化
![95f4ce0a704fcf792433a9556677140a.png](https://i-blog.csdnimg.cn/blog_migrate/b11b9934fd741079340476ab1cf5ad7f.png)
●服务端渲染 - SSR
![98f06f74d0e714a8ef8840d6e4675a88.png](https://i-blog.csdnimg.cn/blog_migrate/d9538273fa2fc83085af0af9e7c40507.png)
你对Vue3.0的新特性有没有了解?
young村长帮大家总结了Vue3.0改进方向,主要在以下几点:
●更快
○虚拟DOM重写
○优化slots的生成
○静态树提升
○静态属性提升
○基于Proxy的响应式系统
●更小:
○通过摇树优化核心库体积
●更容易维护:
○TypeScript + 模块化
●更加友好
○跨平台:编译器核心和运行时核心与平台无关,使得Vue更容易与任何平台(Web、Android、iOS)一起使用
●更容易使用
○改进的TypeScript支持,编辑器能提供强有力的类型检查和错误及警告
●更好的调试支持
●独立的响应化模块
●Composition API
虚拟 DOM 重写
期待更多的编译时提示来减少运行时开销,使用更有效的代码来创建虚拟节点。
组件快速路径+单个调用+子节点类型检测
▷跳过不必要的条件分支
▷JS引擎更容易优化
详情见下图☟
![011b1a46db9a6c03b57e490b4dcc4c35.png](https://i-blog.csdnimg.cn/blog_migrate/576f1e1bb43219a10e254b1e41716d27.jpeg)
![95dec785a79cc9da1b329d64ed122ecf.png](https://i-blog.csdnimg.cn/blog_migrate/152b1fa8d6377383c04ce2990a1c0b9f.png)
优化slots生成
vue3中可以单独重新渲染父级和子级:
▷确保实例正确的跟踪依赖关系
▷避免不必要的父子组件重新渲染
详情见下图☟
![2e30f4d410311f678d745f0a07134ddd.png](https://i-blog.csdnimg.cn/blog_migrate/b9f66a57fe7c38fc46aedde2f360e745.jpeg)
![95dec785a79cc9da1b329d64ed122ecf.png](https://i-blog.csdnimg.cn/blog_migrate/152b1fa8d6377383c04ce2990a1c0b9f.png)
静态树提升(Static Tree Hoisting)
使用静态树提升,这意味着 Vue 3 的编译器将能够检测到什么是静态的,然后将其提升,从而降低了渲染成本。
▷跳过修补整棵树,从而降低渲染成本
▷即使多次出现也能正常工作
详情见下图☟
![94d30b5110e655c8d62de67d966e321b.png](https://i-blog.csdnimg.cn/blog_migrate/8f3f862f225840389d51fc8b753bf7fa.jpeg)
![95dec785a79cc9da1b329d64ed122ecf.png](https://i-blog.csdnimg.cn/blog_migrate/152b1fa8d6377383c04ce2990a1c0b9f.png)
静态属性提升
使用静态属性提升,Vue 3打补丁时将跳过这些属性不会改变的节点。☟
![0237ef3c1ec886ccbf3286a098aa4303.png](https://i-blog.csdnimg.cn/blog_migrate/5d608be1710fb0ab03fb6e4db2e2f30f.jpeg)
![95dec785a79cc9da1b329d64ed122ecf.png](https://i-blog.csdnimg.cn/blog_migrate/152b1fa8d6377383c04ce2990a1c0b9f.png)
基于 Proxy 的数据响应式
Vue 2的响应式系统使用:
Object.defineProperty 的getter 和 setter。
Vue 3 将使用 ES2015 Proxy 作为其观察机制,这将会带来如下变化:
●组件实例初始化的速度提高100%
●使用Proxy节省以前一半的内存开销,加快速度,但是存在低浏览器版本的不兼容
●为了继续支持 IE11,Vue 3 将发布一个支持旧观察者机制和新 Proxy 版本的构建
![bbb7fd5a70512298b69329d104b2639e.png](https://i-blog.csdnimg.cn/blog_migrate/ca6cbd70f2736d881f66cefd5cc5a598.jpeg)
![95dec785a79cc9da1b329d64ed122ecf.png](https://i-blog.csdnimg.cn/blog_migrate/152b1fa8d6377383c04ce2990a1c0b9f.png)
高可维护性
Vue 3 将带来更可维护的源代码。它不仅会使用 TypeScript,而且许多包被解耦,更加模块化。
![4c87cb214797a3df933176b185ee4f35.png](https://i-blog.csdnimg.cn/blog_migrate/bd559a759c7032e2d194ebfa6d5a17c8.png)
看了上面面试题解答,不知道大家有没有一些收获。
村长这里还要多啰嗦两句,大家千万不要只背答案,更要学会答题思路和学习方法,这样不管将来遇上什么问题,大家都能做到举一反三。
往大了说,提升内力才是最重要的目标,将来不管使用什么语言、框架,你都将轻松驾驭、信手拈来。
![be51f98e6b08d66c78303cf0e8deac1e.png](https://i-blog.csdnimg.cn/blog_migrate/035516b974cfe5d5b89d400258808a7e.jpeg)
机会永远只留给全力以赴的人,村长祝大家早日拿到高薪Offer,走上人生巅峰!
关注“开课吧前端团队”,获取更多优质内容,更有机会与互联网大咖交流学习。
![ad455031c55b1ffbcda010e159c91db2.png](https://i-blog.csdnimg.cn/blog_migrate/4b231762b3a5cb97becc2d3a73b69647.jpeg)
这么好的文章,确定不收藏一下下嘛~~
你“在看”我吗?
![e6a53c3ff24a7c6fb193ba817c210e42.png](https://i-blog.csdnimg.cn/blog_migrate/682bef076217745938508f52159c2828.png)