备战-Vue篇

2020/4/20 11:18:02

本文主要是介绍备战-Vue篇,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

前言

小编所分享整理的备战系列文章里面不会是一个完全完整且系统的一个内容,主要是针对所描述的相关知识自己觉得的重点,所以有时候可能整体文章逻辑上会不是很好,55555最近要备战面试了,文章整理就压缩了一下,但还是会用心滴。以下很多东西涉及到Vue源码,小编还是简单描述一下,整理源码到文章太麻烦也不方便查看。

MVC、MVVM架构模式

说到Vue那么最开始我想说到的一个点就是他俩,用了这么久的Vue那么应该要知道他是MVVM软件架构设计模式。

  • MVC
    从前端到后端交互,前端请求通过路由找到对应控制器拿到数据,数据交替是单向的。简单来讲就是前端负责页面后端负责数据。
  • MVVM
    细化了MVC的前端部分,数据直接挂到框架上面直接渲染更新。前端数据需求量的增加使其成为了一个必然的趋势,MVVM可以说是MVC前端部分的一个抽离。

Vue中模板的编译原理

编译原理

我们先从Vue是怎么从一个个组件变成了一个页面来说,怎么从组件代码变成了一个render函数,我们先说三大步

  • 将模板转换成ast树(虚拟DOM对象,vnode树),主要是正则实现解析代码然后在提取相关数据放入对象树中
  • 优化树
  • 将ast树生成js代码

渲染及更新

我们从组件如何渲染到真实DOM

  • 通过CreateElement方法将我们的组件对象生成虚拟DOM对象

  • 拿到虚拟DOM,Vue通过vue.extend()方法构建子組件的枸造凾数,到这里我们虚拟DOM操作就结束了接下来是实例化

  • updata方法执行,我们先执行CreateComponent方法去new一个我们传过来的虚拟DOM对象,实例化后Vue就会给这个组件以内部watcher去渲染,整个粗略的就是这样的一个渲染过程

那么更新内部就是依赖于patchvnode流程核心diff算法去做比较然后更新界面。

Vue采用异步渲染

既然上面提及到了渲染那么这边说一下异步渲染,Vue是组件级别更新。为啥异步打个很简单的比方

this.a = 1
this.b =2
复制代码

我们上面所改变的两个值对应同一watcher的话按照同步流程那我们就得更新两次了。

那么我们的实际流程是刷新界面数据改变的时候回通知notify方法进行更新视图,然后我们会将对应watcher附一个id标记存到一个队列之中,这样我们就可以清除掉相同的watcher只保留最新的,然后渲染页面,最后通过nextTick方法异步清空这个存放watcher的队列然后进行下一个组件渲染。

响应式数据原理

这一部分小编认为是Vue最核心的部分也叫做数据双向绑定原理,稍微概述一下:

核心方法就是Object.defineProperty(),通过他给data里面属性重新定义一下,当页面取到相关属性时Vue内部会查看他的watcher,也就是之前所收集的依赖内容,然后通知响应更新。具体有几步

  • 初始化用户传入的数据initData
  • 对数据进行观测
  • 进行对象处理
  • Object.defineProperty的get、set方法时间检测,set方法收集数据对象的watcher、get方法内部做一个判定如果数据改变则更新响应视图(通过notify方法)

但是最新发布的Vue.3上好像是已经用到了Proxy去实现。这边小编后续在补上

Vue生命周期

生命周期概述

  • beforeCreate在实例初始化之后,数据观测(dataobserver)之前被调用。

  • created实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(dataobserver).属性和方法的运算,watch/event 事件回调。这里没有$el

  • beforeMount在挂载开始之前被调用:相关的rended函数首次被调用。

  • mounted el 被新创建的vm.Se1替换,并挂载到实例上去之后调用该钩子。

  • beforeUpdate数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前。

  • updated由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。

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

  • destroyed Vue 实例销毁后调用。调用后,Vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务 器端渲染期间不被调用。

常用的生命周期能做什么事情

  • created实例已经创建完成,因为它是最早触发的原因可以进行一些数据 ,资源的请求。

  • mounted实例已经挂载完成,可以进行一些DOM操作

  • beforeUpdate可以在这个钩子中进一步地更改状态 ,这不会触发附加的重渲染过程。

  • updated可以执行依赖于DOM的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能 会导致更新无限循环。该钩子在服务器端渲染期间不被调用。

  • destroyed可以执行一些优化操作,清空定时器 ,解除绑定事件

Vue常见问题

Vue中如何检测数组变化?

使用函数劫持的方式,Vue内部重写了数组的方法,Vue将data中的数组操作时指向自己的数组原型方法,重写的方法里面就通知对依赖的更新。

Vue中Computed(计算属性)的特点

从两个问题出发:

建立与其他属性(如:data、 Store)的联系; 属性改变后,通知计算属性重新计算。

实现时,主要如下

  • 初始化 data, 使用Object.defineProperty把这些属性全部转为 getter/setter。
  • 初始化computed, 遍历 computed 里的每个属性,每个 computed 属性都是一个 watch实例。每个属性提供的函数作为属性的 getter,使用 Object.defineProperty 转化。
  • Object.defineProperty getter依赖收集。用于依赖发生变化时,触发属性重新计算。
  • 若出现当前 computed 计算属性嵌套其他computed计算属性时,先进行其他的依赖收集。

计算属性与watcher的区别,计算属性时候缓存的,每次更新视图方法就要重新执行。

Vue中v-if和v-show的区别

v-if如果条件不成立不会渲染当前当前指令所在的节点的DOM元素 v-show值切换当前DOM显示或者隐藏(display属性的改变)。

说到这个点这里提及一下v-if和v-for不能连用,因为v-for优先级大于v-if,然后我们可以在外层加一个<template></template>去判定v-if就ok了

v-for为啥要用key

不用key值的话是数组会复用空间,那么修改数组对象时会产生问题。

data为啥要是一个方法

很简单的一个理解当data是一个对象时我们内部去创建组件实例的时候调用data那么这个data对象会在原型上,后续在创建就是与之前用的是一个data对象值,避免组件间的数据互相影响,用方法每一次new一个实例组件那么会返回一个新的data对象去供其调用。

Vue组件如何通信

父到子通过props通过属性传递、子到父$on、$emit,父亲传给儿子一个方法,让儿子去调用(简易的发布订阅)。

总结

当然相关Vue的问题肯定是不止这么多的,后续小编在看到的话会增加一下内容的。后续一篇备战篇小编会总结一下vue-router的两种模式和路由懒加载。



这篇关于备战-Vue篇的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程