42

前端面试之MVVM浅析

 5 years ago
source link: http://blog.poetries.top/2018/10/20/fe-interview-mvvm/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

EbmuIbJ.png!web

UzEBviM.png!web

1.2 vue 实现 todo-list

uMRRrii.png!web

1.3 jQuery 和框架的区别

  • 数据和视图的分离,解耦(开放封闭原则)
  • 以数据驱动视图,只关心数据变化,DOM 操作被封装

二、说一下对 MVVM 的理解

2.1 MVC

M - Model
V - View
C - Controller

uy2ERzy.png!webbmmiYbJ.png!web

2.2 MVVM

  • Model - 模型、数据
  • View - 视图、模板(视图和模型是分离的)
  • ViewModel - 连接 ModelView

QBveYnN.png!web

2.3 关于 ViewModel

MVVM
ViewModel

3QvmQj6.png!web

a6FjqaN.png!web

2.4 MVVM 框架的三大要素

  • 响应式: vue 如何监听到 data 的每个属性变化?
  • 模板引擎: vue 的模板如何被解析,指令如何处理?
  • 渲染: vue 的模板如何被渲染成 html ?以及渲染过程

三、vue 中如何实现响应式

3.1 什么是响应式

  • 修改 data 属性之后,vue 立刻监听到
  • data 属性被代理到 vm 上

ra6JbyN.png!web

3.2 Object.defineProperty

J7VVVny.png!web

3.3 模拟实现

2I7B32a.png!web

eiENfif.png!web

四、vue 中如何解析模板

4.1 模板是什么

  • 本质:字符串
  • 有逻辑,如 v-if v-for
  • html 格式很像,但有很大区别
  • 最终还要转换为 html 来显示

模板最终必须转换成 JS 代码,因为

  • 有逻辑( v-if v-for ),必须用 JS 才能实现
  • 转换为 html 渲染页面,必须用 JS 才能实现
  • 因此,模板最重要转换成一个 JS 函数( render 函数)

Yf6Bj2r.png!web

4.2 render 函数

  • 模板中所有信息都包含在了 render 函数中
  • thisvm
  • pricethis.pricevm.price ,即 data 中的 price
  • _cthis._cvm._c

JZ3qm2N.png!web

f2auQbj.png!web6NRFJrB.png!web

4.3 render 函数与 vdom

  • vm._c 其实就相当于 snabbdom 中的 h 函数
  • render 函数执行之后,返回的是 vnode

26VjIzM.png!web

VzMFFnA.png!web

  • updateComponent 中实现了 vdompatch
  • 页面首次渲染执行 updateComponent
  • data 中每次修改属性,执行 updateComponent

五、vue 的整个实现流程

  • 第一步:解析模板成 render 函数
  • 第二步:响应式开始监听
  • 第三步:首次渲染,显示页面,且绑定依赖
  • 第四步: data 属性变化,触发 rerender

7vQfUrn.png!web

5.1 第一步:解析模板成 render 函数

uAF3qmy.png!web

RBRFZnr.png!webqqyYZrU.png!webJvMNfm3.png!web

  • 模板中的所有信息都被 render 函数包含
  • 模板中用到的 data 中的属性,都变成了 JS 变量
  • 模板中的 v-model v-for v-on 都变成了 JS 逻辑
  • render 函数返回 vnode

5.2 第二步:响应式开始监听

  • Object.defineProperty
  • data 的属性代理到 vm

yaEz6zF.png!web

5.3 第三步:首次渲染,显示页面,且绑定依赖

  • 初次渲染,执行 updateComponent ,执行 vm._render()
  • 执行 render 函数,会访问到 vm.list vm.title
  • 会被响应式的 get 方法监听到
  • 执行 updateComponent ,会走到 vdompatch 方法
  • patchvnode 渲染成 DOM ,初次渲染完成

bqAveyV.png!web

aQVvYf7.png!web

为何要监听 get ,直接监听 set 不行吗?

  • data 中有很多属性,有些被用到,有些可能不被用到
  • 被用到的会走到 get ,不被用到的不会走到 get
  • 未走到 get 中的属性, set 的时候我们也无需关心
  • 避免不必要的重复渲染

VrIJ7bn.png!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK