这几天面试总结

94 阅读6分钟

Vue双向绑定的原理

Vue 数据双向绑定原理是通过 数据劫持 + 发布者-订阅者模式 的方式来实现的,首先是通过 ES5 提供的 Object.defineProperty() 方法来劫持(监听)各属性的 getter、setter,并在当监听的属性发生变动时通知订阅者,是否需要更新,若更新就会执行对应的更新函数。

什么是数据劫持

数据劫持比较好理解,通常我们利用Object.defineProperty劫持对象的访问器,在属性值发生变化时我们可以获取变化,从而进行进一步操作。

发布者模式 / 订阅者模式

在软件架构中,发布订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者(如果有的话)存在。

这里很明显了,区别就在于,不同于观察者和被观察者,发布者和订阅者是互相不知道对方的存在的,发布者只需要把消息发送到订阅器里面,订阅者只管接受自己需要订阅的内容

Object.defineProperty

Object.defineProperty( obj, prop, descriptor )

三个参数:

obj 要定义的对象

prop 要定义或修改的属性名称或 Symbol

descriptor 要定义或修改的属性描述符

属性描述符

get 属性的 getter 函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。 默认为 [undefined] set 属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。 默认为 [undefined]

v-model在vue2和vue3中的区别

v-model十个语法糖,它是通过自定义函数@input和自定义属性value进行组件之间的传值, 在vue2中v-model只能使用一次,若想使用多次,需要使用.sync修饰符通过$emit("update:value",@input)来实现 但是在vue3中v-model可以进行多次传值, 写法上也有所差别 父组件绑定v-model:name="name" 子组件利用props接收modelValue,

.sync:

1.父组件 :my-prop-name.sync 子组件@update:my-prop-name 的模式来替代事件触发,实现父子组件间的双向绑定。

2.一个组件可以多个属性用.sync修饰符,可以同时"双向绑定多个“prop”

3..sync针对更多的是各种各样的状态,是状态的互相传递,是status,是一种update操作

函数式组件

一般的组件是声明式组件,是不受控制的 函数式组件 是命令式组件 更加灵活

vue暴露的api h: 把一个组件变成一个VNode(虚拟dom) render : 将VNode渲染成一个真实Dom

函数式组件使用流程

  1. 把已经写好的组件通过 h 函数变成 VNode
  2. 准备一个渲染挂载的节点
  3. 调用render api 把VNode 挂载到准备好的节点上 完成渲染

脚手架配置流程

第一个版本 V1

第一个版本的功能比较简单,大致为:

  1. 用户输入命令,准备创建项目。
  2. 脚手架解析用户命令,并弹出交互语句,询问用户创建项目需要哪些功能。
  3. 用户选择自己需要的功能。
  4. 脚手架根据用户的选择创建 package.json 文件,并添加对应的依赖项。
  5. 脚手架根据用户的选择渲染项目模板,生成文件(例如 index.htmlmain.jsApp.vue 等文件)。
  6. 执行 npm install 命令安装依赖。

第二个版本 v2

第二个版本在 v1 的基础上添加了一些辅助功能:

  1. 创建项目时判断该项目是否已存在,支持覆盖和合并创建。
  2. 选择功能时提供默认配置和手动选择两种模式。
  3. 如果用户的环境同时存在 yarn 和 npm,则会提示用户要使用哪个包管理器。
  4. 如果 npm 的默认源速度比较慢,则提示用户是否要切换到淘宝源。
  5. 如果用户是手动选择功能,在结束后会询问用户是否要将这次的选择保存为默认配置。

webpack优化

构建时间优化

thread-loader

多进程打包,可以大大提高构建的速度,使用方法是将thread-loader放在比较费时间的loader之前,比如babel-loader

由于启动项目和打包项目都需要加速,所以配置在webpack.base.js

开启热更新

比如你修改了项目中某一个文件,会导致整个项目刷新,这非常耗时间。如果只刷新修改的这个模块,其他保持原状,那将大大提高修改代码的重新构建时间

只用于开发中,所以配置在webpack.dev.js

exclude & include

  • exclude`:不需要处理的文件
  • include:需要处理的文件

合理设置这两个属性,可以大大提高构建速度

webpack.base.js中配置

提升webpack版本

webpack版本越新,打包的效果肯定更好

打包体积优化

构建区分环境

区分环境去构建是非常重要的,我们要明确知道,开发环境时我们需要哪些配置,不需要哪些配置;而最终打包生产环境时又需要哪些配置,不需要哪些配置:

  • 开发环境:去除代码压缩、gzip、体积分析等优化的配置,大大提高构建速度
  • 生产环境:需要代码压缩、gzip、体积分析等优化的配置,大大降低最终项目打包体积

CSS代码压缩JS代码压缩

CSS代码压缩使用css-minimizer-webpack-plugin,效果包括压缩、去重

JS代码压缩使用terser-webpack-plugin,实现打包后JS代码的压缩

用户体验优化

路由懒加载

如果不进行路由懒加载,当用户进入页面会请求所有的ajax , 导致页面加载速度慢,用户体验差.

Gzip

开启Gzip后,大大提高用户的页面加载速度,因为gzip的体积比原文件小很多,当然需要后端的配合

小图片转base64

对于一些小图片,可以转base64,这样可以减少用户的http网络请求次数,提高用户的体验。