Vue也用这么久了,原理之类的文章也看了不少。今天又精读了一篇头条上的文章,自己也总结记录一下。虽然吧,该学vue3了,不过想转React了哈哈。不扯了,还是先总结下Vue这个框架吧。

官方介绍: Vue是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。其架构模式为MVVM。

渐进式框架:主张最少,可以将其他模块逐步接入。其核心库只关注视图层(声明式渲染和组件系统),可以在项目中只引入vue.js就可开发。同时你也可以引入vue-router作为客户端路由管理,vuex作为全局的状态管理等。

自底向上逐层应用:将基础做好,打牢再逐层往上添加效果和功能的设计。

ef0106f575610bdcdf2c96e72081c13a.png

vue

架构模式MVC:Model-View-Controller。MVC的流程大概就是,html(View)操作,告知js(Controller)要更新数据(Model),js(Controller)更新了数据(Model),然后再更新html(View)。

e8788ac97a97329b969f7fdfb0197f9f.png

MVC

架构模式MVP:Model-View-Presenter。Presenter层既能将页面操作告知Model进行数据更新,又能在数据更新时负责通知View进行更新视图,使的View层与Model层解耦。(React)

9d4d22e9d5b803b03533c1ef15bcefed.png

MVP

架构模式MVVM:Model-View-View-Model,实现了数据绑定的MVP,使得Model状态的改变会直接导致视图的更新(数据驱动视图)。(Vue)

0407ba4fda47afc687bffe8c0378d6d0.png

MVVM

Vue模板渲染:vue的核心之一声明式渲染,具有自身的模板语法,允许在html中嵌入js代码,并可结合强大的指定机制。实现声明式地将数据渲染出视图。
实现模板渲染的前提是进行模板编译。模板编译分为三个阶段,parse、optimize、generate最终生成render函数。

aeee49fa9be95b77fc17cfcb6feefabc.png

模板编译

parse阶段:使用正则表达式对template内容进行字符串解析,得到指令、class、style等数据,生成抽象语法树AST(Abstract Syntax Tree)。
optimize阶段:寻找AST中的静态节点进行标记,为后面VNode的patch过程中对比做优化。被标记为static的节点在之后的diff算法中会被直接忽略。
generate阶段:根据AST结构拼接生成render函数的字符串。
在项目开发中,可以通过预编译进行一定的优化。即将template转化为render function,可在项目的构建中完成,无需等到runtime阶段。比如webpack中vue-loader依赖的vue-template-compiler模块。当然也可以直接在vue组建中编写render函数(可结合jsx)。

声明式渲染:只告诉程序想要什么结果,如何达成由程序保证,开发者不用关心。(不直接操作dom,结合模板语法)
命令式渲染:一步一步告诉程序如何去做,能否达成结果取决于开发者的设计。(找到这个元素,直接操作dom。)

组件机制:Vue的组件拥有自己的状态(data),外部传入的属性(prop)和事件,通过数据和状态计算出来的计算属性(computed),监听属性(watch),自身方法(methods)及生命周期函数等,各个维度组合起来决定组件最终呈现的样子与交互的逻辑。

Vue组件间通信:

  1. 父子组件通信props / $emit$parent / $children
  2. 隔代组件通信$attrs / $listenersprovide / inject
  3. 通用EventBus($emit / $on / $once / $off),中央事件总线系统。Vuex

Vue插槽slot:组件的一块HTML模块,由父组件决定。分默认插槽(name=default)和具名插槽。

slot实现原理:当子组件vm实例化时,获取父组件传入的slot标签内容,存放在vm.$slot中,当组件执行渲染函数时,遇到标签,则使用$slot中的内容进行替换,此时也可以向插槽传递数据,称之为作用域插槽。

这是父组件

这是子组件

3fd3b0629ae69f94c21369204d114431.png

父子组件

组件:对特定功能和样式进行独立的封装,使得HTML元素得到扩展,代码得到复用。开发灵活,高效。
模块:对特定功能进行抽离封装,提高程序耦合度,结构更加清晰,便于维护扩展。

响应式系统:Vue.js是一款MVVM的JS框架,当对数据模型data进行修改时,视图会自动得到更新。

响应式原理:响应式的核心机制是观察者模式,三个重要概念,Observer,Dep,Wathcher。

发布者-Observer:主要作用是在组件vm初始化时,调用defineReactive函数,使用Object.defineProperty方法对对象的每个子属性进行数据劫持/监听,为每个属性添加getter和setter,对应的属性值变成响应式。在组件初始化时,调用initState函数,执行initState、initProps、initComputed方法,分别对data、prop、computed进行初始化。

调度中心-Dep:主要作用是对观察者进行管理,收集观察者dep.depend和通知观察者更新dep.notify。

观察者-Watcher:主要作用是为观察属性提供回调函数以及收集依赖,接收调度中心的通知。分为normal-watcher、computed-watcher(只有当其他地方需要读取计算属性时才会重新计算)、render-watcher。执行顺序computed–>normal–>render。

39990627f69f17a82ddde5497e6acf12.png

响应式系统

虚拟DOM:为了解决频繁更新DOM产生的性能问题。使用JS对象对浏览器的DOM进行抽象。Virtual DOM的每个节点被定义为VNode。视图更新时,会将更新前后的VNode进行Diff对比,实现最小DOM更新操作。

render: function (createElement) {    // 使用 this.$createElement 创建 VNode    return createElement('div', 'hellow world');}

Diff:实现最小单位地修改视图。Vue内部的diff成为patch。通过同层的树节点进行比较,时间复杂度为O(n)

当然,这只是总结了其中的一部分,其他生命周期函数、指令、过滤器、全局API等尚待总结。

Logo

前往低代码交流专区

更多推荐