面试官:Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?
面试官:Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?
开始之前Composition API 可以说是Vue3的最大特点,那么为什么要推出Composition Api,解决了什么问题?
通常使用Vue2开发的项目,普遍会存在以下问题:
代码的可读性随着组件变大而变差
每一种代码复用的方式,都存在缺点
TypeScript支持有限
以上通过使用Composition Api都能迎刃而解
正文一、Options ApiOptions API,即大家常说的选项API,即以vue为后缀的文件,通过定义methods,computed,watch,data等属性与方法,共同处理页面逻辑
如下图:
可以看到Options代码编写方式,如果是组件状态,则写在data属性上,如果是方法,则写在methods属性上…
用组件的选项 (data、computed、methods、watch) 组织逻辑在大多数情况下都有效
然而,当组件变得复杂,导致对应属性的列表也会增长,这可能会导致组件难以阅读和理解
二、Composi ...
Vue3.0的设计目标是什么?做了哪些优化
面试官:Vue3.0的设计目标是什么?做了哪些优化
一、设计目标不以解决实际业务痛点的更新都是耍流氓,下面我们来列举一下Vue3之前我们或许会面临的问题
随着功能的增长,复杂组件的代码变得越来越难以维护
缺少一种比较「干净」的在多个组件之间提取和复用逻辑的机制
类型推断不够友好
bundle的时间太久了
而 Vue3 经过长达两三年时间的筹备,做了哪些事情?
我们从结果反推
更小
更快
TypeScript支持
API设计一致性
提高自身可维护性
开放更多底层功能
一句话概述,就是更小更快更友好了
更小Vue3移除一些不常用的 API
引入tree-shaking,可以将无用模块“剪辑”,仅打包需要的,使打包的整体体积变小了
更快主要体现在编译方面:
diff算法优化
静态提升
事件监听缓存
SSR优化
下篇文章我们会进一步介绍
更友好vue3在兼顾vue2的options API的同时还推出了composition API,大大增加了代码的逻辑组织和代码复用能力
这里代码简单演示下:
存在一个获取鼠标位置的函数
12345678910111213141516imp ...
用Vue3.0 写过组件吗?如果想实现一个 Modal你会怎么设计?
面试官:用Vue3.0 写过组件吗?如果想实现一个 Modal你会怎么设计?
一、组件设计组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式
现在有一个场景,点击新增与编辑都弹框出来进行填写,功能上大同小异,可能只是标题内容或者是显示的主体内容稍微不同
这时候就没必要写两个组件,只需要根据传入的参数不同,组件显示不同内容即可
这样,下次开发相同界面程序时就可以写更少的代码,意义着更高的开发效率,更少的 Bug 和更少的程序体积
二、需求分析实现一个Modal组件,首先确定需要完成的内容:
遮罩层
标题内容
主体内容
确定和取消按钮
主体内容需要灵活,所以可以是字符串,也可以是一段 html 代码
特点是它们在当前vue实例之外独立存在,通常挂载于body之上
除了通过引入import的形式,我们还可通过API的形式进行组件的调用
还可以包括配置全局样式、国际化、与typeScript结合
三、实现流程首先看看大致流程:
目录结构
组件内容
实现 API 形式
事件处理
其他完善
目录结构Modal组件相关的目录结构
1234567 ...
面试官:Vue3.0里为什么要用 Proxy API 替代 defineProperty API ?
面试官:Vue3.0里为什么要用 Proxy API 替代 defineProperty API ?
一、Object.defineProperty定义:Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象
为什么能实现响应式通过defineProperty 两个属性,get及set
get
属性的 getter 函数,当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值
set
属性的 setter 函数,当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。默认为 undefined
下面通过代码展示:
定义一个响应式函数defineReactive
123456789101112131415161718function update() { app.innerText = obj.foo}function ...
Vue3.0性能提升主要是通过哪几方面体现的?
面试官:Vue3.0性能提升主要是通过哪几方面体现的?
一、编译阶段回顾Vue2,我们知道每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把用到的数据property记录为依赖,当依赖发生改变,触发setter,则会通知watcher,从而使关联的组件重新渲染
试想一下,一个组件结构如下图
12345678910<template> <div id="content"> <p class="text">静态文本</p> <p class="text">静态文本</p> <p class="text">{{ message }}</p> <p class="text">静态文本</p> ... <p class= ...
面试官:说说Vue 3.0中Treeshaking特性?举例说明一下?
面试官:说说Vue 3.0中Treeshaking特性?举例说明一下?
一、是什么Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫 Dead code elimination
简单来讲,就是在保持代码运行结果不变的前提下,去除无用的代码
如果把代码打包比作制作蛋糕,传统的方式是把鸡蛋(带壳)全部丢进去搅拌,然后放入烤箱,最后把(没有用的)蛋壳全部挑选并剔除出去
而treeshaking则是一开始就把有用的蛋白蛋黄(import)放入搅拌,最后直接作出蛋糕
也就是说 ,tree shaking 其实是找出使用的代码
在Vue2中,无论我们使用什么功能,它们最终都会出现在生产代码中。主要原因是Vue实例在项目中是单例的,捆绑程序无法检测到该对象的哪些属性在代码中被使用到
123import Vue from 'vue' Vue.nextTick(() => {})
而Vue3源码引入tree shaking特性,将全局 API 进行分块。如果您不使用其某些功能,它们将不会包含在您的基础包中
123im ...
面试官:说说webpack的热更新是如何做到的?原理是什么?
面试官:说说webpack的热更新是如何做到的?原理是什么?
一、是什么HMR 全称 Hot Module Replacement,可以理解为模块热替换,指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个应用
例如,我们在应用运行过程中修改了某个模块,通过自动刷新会导致整个应用的整体刷新,那页面中的状态信息都会丢失
如果使用的是 HMR,就可以实现只将修改的模块实时替换至应用中,不必完全刷新整个应用
在webpack中配置开启热模块也非常的简单,如下代码:
123456789const webpack = require('webpack')module.exports = { // ... devServer: { // 开启 HMR 特性 hot: true // hotOnly: true }}
通过上述这种配置,如果我们修改并保存css文件,确实能够以不刷新的形式更新到页面中
但是,当我们修改并保存js文件之后,页面依旧自动刷新了,这里并没有触发热模块
所以,HMR 并不像 W ...
面试官:说说webpack中常见的Loader?解决了什么问题?
面试官:说说webpack中常见的Loader?解决了什么问题?
一、是什么loader 用于对模块的”源代码”进行转换,在 import 或”加载”模块时预处理文件
webpack做的事情,仅仅是分析出各种模块的依赖关系,然后形成资源列表,最终打包生成到指定的文件中。如下图所示:
在webpack内部中,任何文件都是模块,不仅仅只是js文件
默认情况下,在遇到import或者require加载模块的时候,webpack只支持对js 和 json 文件打包
像css、sass、png等这些类型的文件的时候,webpack则无能为力,这时候就需要配置对应的loader进行文件内容的解析
在加载模块的时候,执行顺序如下:
当 webpack 碰到不识别的模块的时候,webpack 会在配置的中查找该文件解析规则
关于配置loader的方式有三种:
配置方式(推荐):在 webpack.config.js文件中指定 loader
内联方式:在每个 import 语句中显式指定 loader
CLI 方式:在 shell 命令中指定它们
配置方式关于loader的配置,我们是写在 ...
面试官:说说Loader和Plugin的区别?编写Loader,Plugin的思路?
面试官:说说Loader和Plugin的区别?编写Loader,Plugin的思路?
一、区别前面两节我们有提到Loader与Plugin对应的概念,先来回顾下
loader 是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中
plugin 赋予了 webpack 各种灵活的功能,例如打包优化、资源管理、环境变量注入等,目的是解决 loader 无法实现的其他事
从整个运行时机上来看,如下图所示:
可以看到,两者在运行时机上的区别:
loader 运行在打包文件之前
plugins 在整个编译周期都起作用
在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过Webpack提供的 API 改变输出结果
对于loader,实质是一个转换器,将A文件进行编译形成B文件,操作的是文件,比如将A.scss或A.less转变为B.css,单纯的文件转换过程
二、编写loader在编写 loader 前,我们首先需要了解 loader 的本质
其本质为函数,函数中的 this 作为上下文会 ...
面试官:说说webpack中常见的Plugin?解决了什么问题?
面试官:说说webpack中常见的Plugin?解决了什么问题?
一、是什么Plugin(Plug-in)是一种计算机应用程序,它和主应用程序互相交互,以提供特定的功能
是一种遵循一定规范的应用程序接口编写出来的程序,只能运行在程序规定的系统下,因为其需要调用原纯净系统提供的函数库或者数据
webpack中的plugin也是如此,plugin赋予其各种灵活的功能,例如打包优化、资源管理、环境变量注入等,它们会运行在 webpack 的不同阶段(钩子 / 生命周期),贯穿了webpack整个编译周期
目的在于解决loader 无法实现的其他事
配置方式这里讲述文件的配置方式,一般情况,通过配置文件导出对象中plugins属性传入new实例对象。如下所示:
123456789const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装const webpack = require('webpack'); // 访问内置的插件module.exports = ...