2024前端框架vue复习

159 阅读8分钟

Vue2

1. v-show 和 v-if的区别

  • v-show 通过CSS display控制显示和隐藏
  • v-if组件真正的渲染和销毁,而不是显示和隐藏
  • 频繁切换显示状态用v-show,否则用v-if

2. 为何v-for中要用key

  • 必须用key,且不能是index和random
  • diff算法中通过tag和key来判断,是否是sameNode
  • 减少渲染次数,提升渲染性能

3. 描述Vue组件生命周期(有父子组件的情况)

  • 单个组件

    • 挂载阶段
    • 更新阶段
    • 销毁阶段
  • 父子组件

    • 挂载阶段
        1. 父 beforeCreate
        1. 父 created
        1. 父 beforeMount
        1. 子 beforeCreate
        1. 子 created
        1. 子 beforeMount
        1. 子 mounted
        1. 父 mounted
    • 更新阶段
        1. 父 beforeUpdate
        1. 子 beforeUpdate
        1. 子 updated
        1. 父 updated
    • 销毁阶段
        1. 父 beforeDestroy
        1. 子 beforeDestroy
        1. 子 destroyed
        1. 父 destroyed

image.png

4. Vue组件如何通讯

  • props 和 this.$emit 父子组件(父传子->属性直接传值,子传父-> 自定义事件触发)
  • event.$on event.$emit event.$off 兄弟组件(event:Vue实例;beforeDestroy生命周期上进行销毁,否则可能造成内存泄漏)
  • vuex

5. 描述组件渲染和更新的过程

image.png

6. 双向数据绑定v-model的实现原理

  • input元素的value = this.name
  • 绑定input事件 this.name = $event.target.value
  • data 更新触发 re-render

image.png

7. 自定义v-model

image.png

8. $nextTick

  • Vue是异步渲染
  • data改变之后,DOM不会立刻渲染
  • $nextTick会在DOM渲染之后被触发,以获取最新DOM节点

9. slot

  • 父组件往子组件插入一段内容

  • 作用域插槽

    • 子组件<slot :xxx="yyy"></slot>向父组件传递一段内容 <template v-slot="xxx"></template>
  • 具名插槽

image.png

10. 动态组件

  • <component :is="component-name"></component>
  • 需要根据数据,动态渲染的场景。即组件类型不确定

image.png

11. 异步组件

  • import()函数
  • 按需加载,异步加载大组件

12. keep-alive

  • 缓存组件
  • 频繁切换,不需要重复渲染

image.png

13. mixin

  • 多个组件有相同的逻辑,抽离出来
  • mixin并不是完美的解决方案,会有一些问题
    • 变量来源不明确,不利于阅读
    • 多mixin 可能会造成命名冲突
    • mixin和组件可能会出现多对多的关系,复杂度较高
  • Vue3提出的Composition API旨在解决这些问题

image.png

image.png

14. vuex

  • state
  • action
  • mutation
  • getters

image.png

15. vue-router

  • 路由模式(hash、H5 history)
  • 路由配置(动态路由、懒加载)

image.png

image.png

vue原理

image.png

1. 组件化基础

  • 传统组件,只是静态渲染,更新还要依赖于操作DOM

  • 数据驱动视图 - Vue MVVM

image.png

image.png

2. Vue响应式

  • 组件data的数据一旦变化,立刻触发视图的更新

  • 核心API - Obejct.defineProperty

    • 监听对象,监听数组
    • 复杂对象,深度监听
  • Object.definePropery的一些缺点(Vue3 启用了 Proxy)

    • 深度监听,需要递归到底,一次性计算量大
    • 无法监听新增属性/删除属性(Vue.set Vue.delete)
    • 无法原生监听数组,需要特殊处理
  • 响应式:监听data属性 getter setter(包括数组)

image.png

3. 虚拟DOM(vdom) 和 diff算法

  • vdom是实现Vue的重要基石
  • diff算法是vdom中最核心、最关键的部分
  • DOM操作非常耗费性能
  • 以前用jQuery,可以自定控制DOM操作的时机,手动调整
  • Vue是数据驱动视图,如何有效控制DOM操作?
    • 解决方案 - vdom
      • 有了一定复杂度,想减少计算次数比较难
      • 能不能把计算,更多的转移为JS计算?因为JS执行速度很快(比起操作DOM)
      • vdom - 用JS模拟DOM结构,计算出最小的变更,操作DOM
        • 用JS模拟DOM结构(vnode)
        • 新旧vnode对比,得出最小的更新范围,最后更新DOM
        • 数据驱动视图的模式下,有效控制DOM操作
        • vdom:patch(elem, vnode) 和 patch(vnode, newVnode)

image.png

  • diff算法
    • 日常使用vue中的体现(如key)

image.png

3. 模板编辑

  • 模板到render函数,再到vnode

4. 渲染和更新

image.png

image.png

image.png

image.png

5. 异步渲染

image.png

image.png

6. computed有何特点

  • 缓存,data不变不会重新计算
  • 提高性能

7. 为何组件data必须是一个函数?

image.png

  • 每一个vue文件实例化后,函数内形成一个闭包,各个vue文件之间的变量不会相互影响

8. ajax请求放在哪个生命周期?

  • mounted
  • JS是单线程的,ajax异步获取数据
  • 放在mounted之前没有用,只会让逻辑更加混乱

9. 如何将组件所有的props传递给子组件

  • $props
  • <User v-bind='$props' />

10. 多个组件有相同的逻辑,如何抽离?

  • mixin
  • mixin的一些缺点

11. 何时使用异步组件?

  • 加载大组件
  • 路由异步加载
  • 优化性能

12. 何时使用keep-alive?

  • 缓存组件,不需要重复渲染
  • 如多个静态tab页的切换
  • 优化性能
  • 有自己独立的生命周期钩子 activited(组件被激活时调用)、deactivited(组件被销毁时调用);同时,beforeDestroy和destroyed不会触发了,因为组件不会真正销毁
  • 当组件被换掉时,会被缓存到内存中,触发deactivate钩子;当组件被切回来时,再去缓存里找这个组件,触发特定钩子

13. 何时需要使用beforeDestroy?

  • 解除自定义事件 event.$off
  • 清除定时器
  • 解绑自定义的DOM事件,如window scroll等,否则可能会造成内存泄漏

14. 什么是作用域插槽?

image.png

15. vuex中action和mutation有何区别?

  • action中处理异步,mutation不可以
  • mutation中做单个操作
  • action可以整合多个mutation

16. Vue-router常用的路由模式

  • hash 默认
  • H5 history(需要服务端支持)

17. 如何配置vue-router 异步加载?

image.png

18. 请用vnode描述一个DOM结构

image.png

19. 监听data变化的核心API是什么?

  • Object.defineProperty
  • 深度监听、监听数组
  • 有何缺点?

20. Vue如何监听数组变化?

  • Object.defineProperty 不能监听数组变化
  • 重新定义,重写push pop等方法,实现监听
  • vue3 Proxy可以原生支持监听数组的变化

21. 请描述响应式原理

  • 监听data变化
  • 组件渲染和更新的流程

22. 简述diff算法过程

image.png

23. Vue为何是异步渲染,$nextTick有何用?

  • 异步渲染(以及合并data修改),以提高渲染性能
  • $nextTick在DOM更新完之后,触发回调

24. Vue常见性能优化方式?

  • 合理使用v-show和v-if
  • 合理使用computed
  • v-for时加key,以及避免和v-if同时使用(v-for优先级大于v-if,每次遍历时,做v-if,消耗性能)
  • 自定义事件(eventBus)、自定义DOM事件及时销毁(会造成内存泄漏,页面越来越卡)
  • 合理使用异步组件
  • 合理使用keep-alive
  • data层级不要太深(数据设计尽量扁平化)
  • 前端通用的性能优化,如图片懒加载、使用CDN等
  • webpack层面的优化
  • 使用SSR

Vue3

1. Vue3比Vue2有什么优势?

  • 性能更好
  • 体积更小
  • 更好的ts支持
  • 更好的代码组织
  • 更好的逻辑抽离
  • 更多新功能

2. Vue3的生命周期

  • Options API生命周期

    • beforeDestroy 改为 beforeUnmount
    • destroyed 改为 unMounted
    • 其他沿用Vue2的生命周期
  • Composition API 声明周期

    • vue2生命周期前加on
    • beforeCreate created整合到setup中

3.Composition API 对比 Options API

  • Compositon API 带来了什么
    • 更好的代码组织

image.png - 更好的逻辑复用 - 更好的类型推导(没有this了)

image.png

  • 如何选择?
    • 不建议共用,会引起混乱
    • 小型项目、业务逻辑简单,用Options API
    • 中大型项目、业务逻辑复杂,用Composition API

4. 如何理解ref toRef toRefs?

  • ref reactive使用原则
    • 若需要一个基本类型的响应式数据,必须使用ref
    • 若需要一个响应式对象,层级不深,ref、reactive都可以
    • 若需要一个响应式对象,且层级较深,推荐使用reactive
  • reactive
    • 一般用来做对象的响应式
    • hook函数返回响应式对象式,可以使用toRefs进行包裹,如toRefs(state)
  • ref
    • 一般用来做基本类型的响应式

    • 生成值类型的响应式数据

    • 可用于模板和reactive

    • 通过.value修改值

    • 为何需要ref?

      • 直接返回值类型,会丢失响应式
      • 在setup、computed、hook函数,都有可能返回值类型
      • Vue如果不定义ref,用户将自造ref,反而混乱
    • 为何需要.value?

      • ref是一个对象(不丢失响应式),value存储值
      • 通过.value属性的get和set实现响应式
      • computed 返回一个类似于ref的对象,也需要.value
      • 用于模板、reactive时,不需要.value,其他情况都需要
  • toRefs
    • 通过toRefs将reactive对象中的n个属性批量取出,且依然保持响应式的能力
    • 用于对reactive的解构
    • 为何需要toRef和toRefs?
      • 初衷:不丢失响应式的情况下,把对象数据 解构
      • 前提:针对的是响应式对象(reactive封装的)非普通对象
      • 注意: 不创造响应式,而是延续响应式

image.png

5. Vue3升级了哪些重要功能?

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

6. Composition API 事项逻辑复用(hook)

  • 抽离逻辑代码到一个函数
  • 函数命名约定为useXxx格式
  • 在setup函数中引用useXxx函数

image.png

  • 组件中使用: const {x, y} = useMousePosition()

7. Vue3如何实现响应式?

  • 回顾 vue2 Object.defineProperty

image.png

image.png

  • vue3 Proxy 实现响应式
    • 基本使用

    • Reflect

      • 和Proxy能一一对应
      • 标准化、规范化、函数式
      • 替代掉Object上的工具函数
    • 实现响应式

    • 优点(Proxy能规避Object.defineProperty的问题)

      • 深度监听,性能更好(类似按需递归,需要哪个数据时,递归哪一个)
      • 可监听 新增/删除 属性
      • 可监听 数组变化
    • 缺点

      • Proxy无法兼容所有浏览器,无法polyfill

image.png

8. watch和watchEffect的区别

  • 两者都可以监听data属性变化
  • watch需要明确监听哪个属性
  • watchEffect会根据其中的属性,自动监听其变化。初始化时,一定会执行一次(收集要监听的数据)

9. setup中如何获取组件实例?

image.png

10. Vue3 为什么比 Vue2 快?

image.png

  • Proxy响应式
  • PatchFlag
    • 编译模版时,动态节点做标记
    • 标记,分为不同的类型,如TEXT PROPS CLASS
    • diff算法时,可以区分静态节点,以及不同类型的动态节点

image.png

  • hoistStatic

image.png

  • cacheHandler

    • 缓存事件
  • SSR优化

    • 静态节点直接输出,绕过了vdom
    • 动态节点,还是需要动态渲染
  • tree shaking

    • 按需引入
    • 编译时,根据不同的情况,引入不同的API

11. Vite为何启动快?

  • 开发环境使用ES6 Module,无需打包 —— 非常快
  • 生产环境使用rollup,并不会快很多

12. Composition API 和 React Hooks 有什么区别?

  • 前者setup只会被调用1次,而后者函数会多次调用
  • 前者无需useMemo useCallback,因为setup只调用1次
  • 前者无需考虑调用顺序,而后者需要保证hooks的顺序一致
  • 前者 reactive + ref比后者 useState,要难理解

13. Vue3 script setup语法糖

  • 基本使用

    • 顶级变量、自定义组件,可以直接用于模板
    • 可正常使用ref reactive computed 等
  • 属性和事件

    • 定义属性defineProps
    • 定义事件defineEmits
  • 暴露数据给父组件

    • defineExpose

14. 前端为什么要进行打包和构建?

  • 体积更小(Tree-Shaking、压缩、合并),加载更快
  • 编译高级语言或语法(TS、ES6+、模块化、scss)
  • 兼容性和错误检查(Polyfill、postcss、eslint)
  • 统一、高效的开发环境
  • 统一的构建流程和产出标准
  • 集成公司构建规范(提测、上线等)

15. webpack优化构建速度

image.png

image.png

image.png

image.png

16. vue3和vue2有什么区别?

  • 用组合式api替换选项式api,方便逻辑更加的聚合

  • 一些细节使用点改变

    • 组合式api,没有this
    • 生命周期没有create,setup等同于create,卸载改成unmount
    • vue3中v-if优先级高于v-for
    • 根实例的创建从new app 变成了createApp方法
    • 一些全局注册,比如mixin、注册全局组件、use改成了用app实例调用,而不是vue类调用
    • 新增了传送门teleport组件
    • template模板可以不包在一个根div里
  • 原理方面

    • 响应式原理改成了用proxy,解决了数组无法通过下标修改,无法监听到对象的属性的新增和删除的问题。也提升了响应式的效率。
    • 可以额外叙述vue3并不是完全抛弃了defineProperty,通过reactive定义的响应式数据使用proxy包装出来,而ref还是用defineProperty去给一个空对象,定义了一个value属性来做的响应式
    • 组合式api的写法下,源码改成了函数式编程,方便按需引入,因为tree-shaking功能必须配合按需引入写法。所以vue3更好地配合tree-shaking能让打包体积更小
    • 性能优化,增加了静态节点标记。会标记静态节点,不对静态节点进行比对。从而增加效率
  • 进阶操作方面

    • vue3不推荐使用mixin进行复用逻辑提取,而是推荐使用hook
    • v-model应用于组件时,监听的事件和传递的值改变
      • vue2 value 监听 change/input事件
      • vue3 modelValue 监听update:modelValue
    • ts更好地配合

17. axios封装

  • 基本封装部分
    • 基本全局配置 如baseUrl,超时时间等
    • Token,秘钥等 出于权限和安全考虑的秘钥设置到请求头
    • 响应的统一基本处理 主要针对于错误的情况进行全局统一处理
    • 封装请求方法 把对接口的请求封装为一个方法

前端组件和状态设计

1. 考察重点

image.png

2. Vue实现购物车

image.png

  • data 数据结构设计
    • 用数据描述所有的内容
    • 数据要结构化,易于程序操作(遍历、查找)
    • 数据要可扩展,以便增加新的功能

image.png

  • 组件设计和组件通讯
    • 从功能上拆分层次
    • 尽量让组件原子化
    • 容器组件(只管理数据)& UI组件(只显示视图)

image.png

image.png