前端面试笔记-Vue篇

目录

  • Vue3与Vue2的区别
  • MVVM
  • Vue生命周期
  • Vue组件通信
  • Vue diff策略
  • Vue 虚拟DOM
  • Vue计算属性
  • vue-router实现懒加载
  • vue loader的工作原理
  • 如果你自己设置vue loader该怎么做
  • vue的响应式怎么实现的
  • Vue好处的理解
  • 对vue源码的学习情况
  • Vue的特性
    • Key的作用
  • VueX

Vue3与Vue2的区别

vue2与vue3的区别

  • vue2 的双向数据绑定是利用ES5 的一个 API Object.definePropert()对数据进行劫持 结合 发布订阅模式的方式来实现的。

  • VUE实现双向数据绑定的原理就是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的。

  • set 与 get函数中使用了全局变量Dep,更新时通知watcher,watcher调用update函数执行compiler中的回调;设值时在dep中注册一个观察者。

    • Vue双向数据绑定原理解析及代码实现
    • 要点:数据劫持+观察者(发布者-订阅者)模式
    • 核心:Object.defineProperty()
      • 语法:Object.defineProperty(obj, prop, descriptor)
        • obj:要在其上定义属性的对象。
        • prop:要定义或修改的属性的名称。
        • descriptor:将被定义或修改的属性描述符。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NIgoGMfD-1646398631114)(/Users/wangke/Desktop/收集/图片/发布者-订阅者模式.png)]
    • 碎片化文档:DOM节点的容器,例如把创建的节点放容器中再插入DOM树可以只回流一次减少资源损耗
    • 数据劫持:如果使用appendChid方法将原dom树中的节点添加到DocumentFragment中时,会删除原来的节点
    • Vue的双向数据绑定在底层运用到了三大模块:Observer数据监听器,Compiler指令解析器和Watcher订阅者。
      • 理解:vue如何实现observer和watcher源码解析
      • Observer负责对所有的数据对象里面所有的属性进行监听,也就是对data里面所有的属性进行监听。监听就是进行数据劫持,一旦监听到了数据的变化,它就会通知订阅者。
      • Compiler是指令解析器,用来扫描实例关联的模板,在扫描的过程中,它会对模板里面的指令进行解析,然后绑定指定的事件,它也会订阅模板里面的数据变化,绑定一个更新函数给到Watcher
      • Watcher 订阅者,watch用来关联observer以及compiler, 能够订阅并且收到所有属性变化的通知,然后同时他一旦订阅到了,就会执行指令绑定的相应的操作,然后通过它来更新对应的视图,通过调用update()方法来更新视图。update是watcher自身的一个方法,主要用于执行compiler里面的一些回调,因为compiler主要是用来扫描模板的,同时对里面的一些指令进行解析,绑定事件,绑定的事件有回调,也就是说 触发compiler里面的回调,从而更新界面。

前端面试笔记-Vue篇_第1张图片

  • vue3 中使用了 es6 的 ProxyAPI 对数据代理。

    • 使用Object.defineProperty()的缺点:

      • Object.defineProperty无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实时响应
      • Object.defineProperty只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历
    • Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。

    • 相比于vue2.x,使用proxy的优势如下

      • defineProperty只能监听某个属性,不能对全对象监听

      • 可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可)

      • 可以监听数组,不用再去单独的对数组做特异性操作 vue3.x可以检测到数组内部数据的变化

  • 其他区别

    • Vue2使用选项类型API(Options API)对比Vue3合成型API(Composition API),旧的选项型API在代码里分割了不同的属性: data,computed属性,methods,等等。新的合成型API能让我们用方法(function)来分割,相比于旧的API使用属性来分组,这样代码会更加简便和整洁
    • 生命周期钩子变化 setup() onBeforedMounted()
    • data变成setup+reactive来响应

MVVM

MVC:Vue双向数据绑定

  • M是指业务模型,V是指用户界面,C则是控制器:

    • Model层用来存储业务的数据,一旦数据发生变化,模型将通知有关的视图。

      Model和View之间使用了观察者模式,View事先在此Model上注册,进而观察Model,以便更新在Model上发生改变的数据。

    • V即View视图, 视图层。

      view和controller之间使用了策略模式,View引入了Controller的实例来实现特定的响应策略。如果要实现不同的响应策略只要用不同的Controller实例替换即可。

    • 控制器是模型和视图之间的纽带。
      MVC将响应机制封装在controller对象中,当用户和你的应用产生交互时,控制器中的事件触发器就开始工作了。

什么是MVVM

  • 定义:Model-View-ViewModel的简写。它本质上就是MVC 的改进版。

    • M是逻辑方法加上数据,V就是用户看到的界面,VM就是逻辑方法加上界面渲染的代码,例如HTML。
    • 视图:就像在MVC和MVP模式中一样,视图是用户在屏幕上看到的结构、布局和外观(UI)。
    • 视图模型:视图模型是暴露公共属性和命令的视图的抽象。MVVM没有MVC模式的控制器,也没有MVP模式的presenter,有的是一个绑定器。在视图模型中,绑定器在视图和数据绑定器之间进行通信。
    • 模型:模型是指代表真实状态内容的领域模型(面向对象),或指代表内容的数据访问层(以数据为中心)。
  • 优点:

    • 低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
    • 可重用性:你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
    • 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,使用Expression Blend可以很容易设计界面并生成xaml代码。
    • 可测试:界面素来是比较难于测试的,测试可以针对ViewModel来写。
    • 比MVC/MVP精简了很多,不仅仅简化了业务与界面的依赖,还解决了数据频繁更新(以前用jQuery操作DOM很繁琐)的问题。
    • 在MVVM中,View不知道Model的存在,ViewModel和Model也察觉不到View,这种低耦合模式可以使开发过程更加容易,提高应用的可重用性。

Vue生命周期

  • 定义:Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。

  • 生命周期函数:

    1、beforeCreate(创建前)

    表示实例完全被创建出来之前,vue 实例的挂载元素$el和数据对象 data 都为 undefined,还未初始化。

    2、created(创建后)

    数据对象 data 已存在,可以调用 methods 中的方法,操作 data 中的数据,但 dom 未生成,$el 未存在 。

    3、beforeMount(挂载前)

    vue 实例的 $el 和 data 都已初始化,挂载之前为虚拟的 dom节点,模板已经在内存中编辑完成了,但是尚未把模板渲染到页面中。data.message 未替换。

    4、mounted(挂载后)

    vue 实例挂载完成,data.message 成功渲染。内存中的模板,已经真实的挂载到了页面中,用户已经可以看到渲染好的页面了。实例创建期间的最后一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了,DOM 渲染在 mounted 中就已经完成了。

    5、beforeUpdate(更新前)

    当 data 变化时,会触发beforeUpdate方法 。data 数据尚未和最新的数据保持同步。

    6、updated(更新后)

    当 data 变化时,会触发 updated 方法。页面和 data 数据已经保持同步了。

    7、beforeDestory(销毁前)

    组件销毁之前调用 ,在这一步,实例仍然完全可用。

    8、destoryed(销毁后)

  • nextTick原理:vue的nextTick原理

    • 定义:根据官方文档的解释,它可以在DOM更新完毕之后执行一个回调

    • nextTick是全局vue的一个函数,在vue系统中,用于处理dom更新的操作。vue里面有一个watcher,用于观察数据的变化,然后更新dom,vue里面并不是每次数据改变都会触发更新dom,而是将这些操作都缓存在一个队列,在一个事件循环结束之后,刷新队列,统一执行dom更新操作。

      在vue生命周期的created()钩子函数进行的DOM操作要放在Vue.nextTick()的回调函数中,因为created()钩子函数执行的时候DOM并未进行任何渲染,而此时进行DOM操作是徒劳的,所以此处一定要将DOM操作的JS代码放进Vue.nextTick()的回调函数中。

      而与之对应的mounted钩子函数,该钩子函数执行时所有的DOM挂载和渲染都已完成,此时该钩子函数进行任何DOM操作都不会有个问题。

Vue组件通信

Vue组件间的通信

  • 使用props属性。
    • props主要用于父组件传递数据给子组件,是你可以在组件上注册一些自定义特性。当一个值传递给一个prop特性的时候,它就变成了那个组件实例的一个属性。这样在子组件就可以使用该该值。请注意:所有的prop都使得期父子prop之间形成了一个单向下行绑定,即父级prop的更新会向下流动到子组件,但是反过来就不行,子组件不能改变父组件的状态。
    • 每次父组件发生更新时,子组件中所有的prop都会被刷新为最新的值。
  • 使用Vue自定义事件。
    • 父组件可以在使用子组件的地方直接用 v-on来监听子组件触发的事件 。即父组件中使用 v-on绑定自定义事件,然后在子组件中使用 $emit(eventName,data)触发事件。
    • 每个Vue对象实例都实现了事件接口,所以可以使用 o n ( e v e n t N a m e ) 监 听 事 件 , 使 用 on(eventName)监听事件,使用 on(eventName)使emit 来触发事件.
  • 消息订阅与发布(PubSubJS库)
  • 组件间通信:Slot
  • vuex通信

Vue diff策略

Vue中的Diff算法

  • 为什么要用Diff算法

    • 由于在浏览器中操作DOM的代价是非常“昂贵”的,所以才在Vue引入了Virtual DOM
    • Virtual DOM是对真实DOM的一种抽象描述。
    • 即使使用了Virtual DOM来进行真实DOM的渲染,在页面更新的时候,也不能全量地将整颗Virtual DOM进行渲染,而是去渲染改变的部分,这时候就需要一个计算Virtual DOM树改变部分的算法了,这个算法就是Diff算法。
  • 传统的diff算法

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2xZRhzgT-1646398631116)(/Users/wangke/Desktop/收集/图片/传统diff算法.png)]

  • React的开发者结合Web界面的特点做出了两个大胆的假设,使得Diff算法复杂度直接从O(n^3)降低到O(n),假设如下:

    • 两个相同组件产生类似的DOM结构,不同的组件产生不同的DOM结构;
    • 对于同一层次的一组子节点,它们可以通过唯一的id进行区分。
    • diff思路
      • 同层比较:新的Diff算法是逐层进行比较,只比较同一层次的节点,大大降低了复杂度。
      • 不同类型节点的比较:如果发现新旧两个节点类型不同时,Diff算法会直接删除旧的节点及其子节点并插入新的节点,这是由于前面提出的不同组件产生的DOM结构一般是不同的,所以可以不用浪费时间去比较。注意的是,删除节点意味着彻底销毁该节点,并不会将该节点去与后面的节点相比较。
      • 相同类型节点的比较:若是两个节点类型相同时,Diff算法会更新节点的属性实现转换。
      • 列表节点的比较:列表节点的操作一般包括添加、删除和排序,列表节点需要我们给它一个key才能进行高效的比较。
  • Vue的Diff算法与上面的思路大体相似,只比较同级的节点,若找不到与新节点类型相同的节点,则插入一个新节点,若有相同类型的节点则进行节点属性的更新,最后删除新节点列表中不包含的旧节点。

Vue 虚拟DOM

vue中的虚拟dom

  • 虚拟DOM就是使用js的object模拟真实的dom,当状态发生变化,更新之前做diff,达到最少操作dom的效果
  • 访问DOM是非常昂贵的,会造成相当多得性能浪费,所以我们试想,当某个状态发生变化时,只更新与这个状态相关联的DOM节点。虚拟DOM就是解决方案之一。所以虚拟DOM旨在避免不必要的DOM操作
  • vue为什么引入虚拟DOM?
    • vue1.0响应式粒度太细,Object.defineProperty()每个数据的修改都会通知watcher,进而通知dom去改变,对大型项目来说是一个噩梦!内存开销非常大。
    • vue2.0引入虚拟dom,通过diff之后再通知dom去改变,相对于1.0响应式的级别修改了,watcher只到组件,组件内部使用虚拟dom
  • vue中虚拟DOM干了啥?
    • 提供与真实dom节点对应的虚拟节点vnode
    • 状态发生变化时,对比新旧两个vnode,更新视图。
  • vue中的虚拟DOM如何创建?
    • vue-loader 允许我们直接在template中编写模板字符串,将内容提取出来给vue-template-compiler,Vue.js通过编译器将模板转换成渲染函数中的内容,执行这个函数可以得到一个vnode树,使用这个虚拟节点树就可以渲染页面了。

Vue计算属性

计算属性只在相关响应式依赖发生改变时它们才会重新求值

vue-router实现懒加载

vue-router路由懒加载及实现的方式

定义:延迟加载,即在需要的时候进行加载,随用随载。

场景:项目打包时所有Component都会打包到一个js中,项目打开时加载很慢

使用:

​ 语法:component:() => import(’./About.vue’);

//主要这句话
const router = new VueRouter({  
  routes: [   
   	  { path: '/about', 
   	  component:  () => import('./About.vue') }]
   })

vue loader的工作原理

webpack 是只识别 js 代码的。但是我们写的代码中有很多类型的文件,比如:.vue、.yaml、.json、.css、.tsx 等等这些后缀文件,这些文件都是不被 webpack 所识别的,因此需要在webapck 打包前进行“翻译”。loader 的作用就是“翻译”的作用,将非 js 文件进行转义成 js 代码,然后 webpack 才会识别。

将.vue文件转换为js代码以被webpack识别,用一个Parse函数将vue文件中js、html、css代码分离,然后包装一下给webpack

vue-loader 源码分析

如果你自己设置vue loader该怎么做

  1. 检索所有vue文件,拿到路径、名字和内容
  2. 找到Template标签,拿正则表达式匹配,把里面的内容拿出来就是html代码
  3. 同理可以拿到js代码和css代码,然后存起来

vue的响应式怎么实现的

vue的响应式

创建vue实例的时候,vue会将data中的成员代理给vue实例,目的是为了实现响应式

Vue好处的理解

  • 视图,数据,结构分离
  • 双向数据绑定
  • 组件化
  • 虚拟DOM

vue的优点?

对vue源码的学习情况

Vue的特性

Key的作用

Vue的特性(一):key的作用

  • key是为每个vnode指定唯一的id,在同级vnode的Diff过程中,可以根据key快速的进行对比,来判断是否为相同节点,利用 key 的唯一性生成 map 对象来获取对应节点,比遍历方式更快,指定key后,可以保证渲染的准确性(尽可能的复用 DOM 元素。)

  • key的特殊属性主要用在Vue的虚拟Dom算法中,在新旧nodes(元素节点)对比时辨识VNodes

    • 如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用 key,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。
    • 有相同父元素的子元素必须有独特的 key,重复的 key 会造成渲染错误。

VueX

入门Vuex你需要知道这些!

  • 定义:

    • 官方的解释是: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

    • 简而言之就是:让数据管理变得更清晰。

    • 这个状态自管理应用包含以下几个部分:

      • state,驱动应用的数据源;

      • view,以声明方式将 state 映射到视图;

      • actions,响应在 view 上的用户输入导致的状态变化。

  • vuex实现组件通信

    • vue如何监听vuex里面的属性

你可能感兴趣的:(前端面试八股,前端笔记,Vue)