vue源码实现的整体流程解析「建议收藏」

vue源码实现的整体流程解析「建议收藏」一、前言最近一直在使用vue做项目,闲暇之余查阅了一些关于vue实现原理的资料,一方面对所了解到的知识做个总结,另外一方面希望能对看到此文章的同学有所帮助。本文如有不足之处,还请过往的大佬批评指正。

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一、前言

最近一直在使用vue做项目,闲暇之余查阅了一些关于vue实现原理的资料,一方面对所了解到的知识做个总结,另外一方面希望能对看到此文章的同学有所帮助。本文如有不足之处,还请过往的大佬批评指正。

二、vue实现原理概述

vue作为一个前端渐进式的MVVM开发库,将广大的前端劳苦大众从DOM操作中解放出来;说到vue的实现原理,大体可分为三个要素

1、数据的响应式,即vue可以监听到数据的变化

2、模板引擎,模板引擎大家都应该不陌生,同之前使用的handlebars、artTemplate相似,都类似于Html语法,不过可以写一些逻辑在上面(数据绑定和事件绑定)

3、Html的渲染,即通过模板引擎将数据渲染到页面过程

 这三点为理论上的实现原理,不过使用vue写项目的时候,从数据变化到页面展示的变化大体可分为一下一个步骤

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

第二步:响应式开始监听数据的变化

第三步:首次渲染页面,显示页面,并绑定数据依赖和和事件

第四步:data的变化,触发rerender,更新视图的显示

一下将通过解释vue监听数据的变化、模板绑定数据、数据渲染至页面、实现只渲染数据改变部分DOM这几个部分进行讲解

三、vue实现整体解析

1、vue如何实现对数据的监听的?

说到vue对数据的监听,不得不提到Object.defineProperty,当前主流浏览器均支持此属性,vue的数据双向绑定及数据的监听都是基于此实现的;请看下面代码:

 1 var obj = {};
 2 var name = "MrGao"
 3 Object.defineProperty(obj, "name", { 4 get: function() { // 获取属性值 5 return name; // name的初始值为"MrGao" 6  }, 7 set: function(newval) { // set新的值给属性 8 name = newval 9  } 10 }) 11 console.log(obj.name) // MrGao 12 obj.name = "MrBone"; 13 console.log(obj.name) // MrBone

可以看到Object.defineProperty传了三个参数进去

第一个参数为目标对象

第二个参数为要定义的属性或方法名称,(如果对象中不包含此属性将此属性添加到目标对象里,vue中将data数据指向vm就是用的这里,下面将详细讲解)

第三个参数为目标属性的所拥有的特性

这三个参数为必填参数,另外对于第三个参数除get和set之外还有一些其它的属性,在这里提一下

value: 属性的值

writable:属性的值是否能被重写,当设置为false的时候为只读,不能通过set进行重新赋值

configurable:是否可以设置他的其他属性(value,writable)

enumerable:是否可以在Object.keys或for…in中列举出来

get和set上面例子已经提到

Object.defineProperty在vue中的实现

我们知道在写vue的时候都是可以通过this.*来读取改变在data中定义的属性,那么这是怎么实现的呢?这就是通过Object.defineProperty将data中的属性指向到vm中,即this就是之vm实例,参考一下实现代码:

 1 var data = {
 2     name: "MrGao", 3 age: 22, 4 address: "HangZhou" 5 }; 6 var vm = {}; 7 8 for(key in data) { 9 (function(key){ // 采用闭包,保证key的独立作用域 10  Object.defineProperty(vm, key, { 11 get: function() { 12 return data[key] 13  }, 14 set: function(newval) { 15 data[key] = newval 16  } 17  }) 18  })(key) 19 } 20 21 console.log(vm.name); 22 vm.name = "MrBone"; 23 console.log(vm.name);

通过分析上面代码可以看出vue通过Object.defineProperty将data中的属性指向vm实例,即this可以获取data中的属性

以上为vue数据响应式监听的原理,接下来我们来看一下模板引擎的实现

2、vue模板引擎

说模板之前先来看下模板是什么:

本质:字符串

带逻辑: 如v-if、v-for、v-model

特点:最终要通过js转换成html代码来显示在页面上

所以如果要让有逻辑的模板显示在页面上,就需要通过js声明一个函数来处理这件事情,我们给它起个名字叫做render

通过都vue源码,可获取关于render函数中的一些核心函数,下面通过一个简单的例子来做下介绍:

vue源码实现的整体流程解析「建议收藏」 vue源码实现的整体流程解析「建议收藏」

 

通过以上代码可看出vue中render函数有两个特点,一是使用了with函数,二是模板中所有的信息都包含在render函数中;其中函数中的this指的就是vm,所以_c、_v、_s、tittle分别指的是vm._c、vm._v、vm._s、vm.tittle。这里重点说下_c,这里的_c和snabbdom.js中的h()函数相似,下面还会说到vdom中的patch()函数,要了解虚拟DOM相关细节我将在下一篇博客中介绍。

此处render函数将返回一个虚拟DOM,即vnode,并将vnode传到patch()函数中;参考下面代码:

vm._updata(vnode) {
    const prevVnode = vm._vnode; vm._vnode = vnode; // 将新的vnode赋值给旧的_vnode if (!prevVnode) { // 如果旧的_vnode不存在则将dom挂载在vm.$el vm.$el = vm.__patch__(vm.$el, vnode); } else { vm.$el = vm.__patch__(prevVnode, vnode); } } function updateComponent() { // vm._render为返回的虚拟DOM  vm._update(vm._render()); }

 

 3、数据渲染至页面

将数据渲染进页面,通过patch函数将虚拟DOM转换为真实DOM结构页面进行展示,渲染页面的函数调用如下:

初次渲染

1、执行updateComponent,执行vm._render()

2、执行render函数,会访问到数据源

3、相应式get方法监听到访问的数据源执行updateComponent,到patch()方法中的 vm.$el = vm.__patch__(vm.$el, vnode);

4、patch()将虚拟DOM渲染成DOM,初次渲染完成

修改属性渲染

1、修改属性,被响应式set监听到

2、set中执行updateComponent

3、updateComponent重新执行vm._render()

4、生成vnode和旧的prevVnode,通过patch进行比较  vm.$el = vm.__patch__(prevVnode, vnode);

5、DOM更新

四、小节

以上为今天所讲的内容,对vue的实现原理进行了一个简单剖析,至于vue中实现的DOM的差量更新,vue2.0之后引入的虚拟DOM,是基于vdom的diff算法原理,通过patch函数比较vdom更新前后的数据差异进行DOM的更新,篇幅有限,这里就不在对虚拟DOM进行赘述,如有兴趣,欢迎阅读我下一篇关于虚拟DOM的文章。

什么是虚拟DOM

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/167717.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • snmptrap怎么发送_cmd运行nmap

    snmptrap怎么发送_cmd运行nmapSNMP简单网络管理协议,其中其支持的一个命令snmptrap命令,用于模拟向管理机发送trap消息。启动陷阱方法:snmptrapd-C-c/etc/snmp/snmptrapd.conf-Lf/var/log/net-snmptrap.log例如:snmptrap-v1-cpublic192.168.2.124.1.3.6.1.4.1.1192.168.2.12561…

    2022年8月20日
    21
  • 牛客网–合唱队形

    牛客网–合唱队形

    2021年5月19日
    131
  • 抖音python真的那么好吗_python看抖音用户画像,摩羯天蝎居然刷得最多?

    抖音python真的那么好吗_python看抖音用户画像,摩羯天蝎居然刷得最多?python看抖音用户画像,摩羯天蝎居然刷得最多?

    2022年6月3日
    38
  • VS PDB文件详解

    VS PDB文件详解转自https://blog.csdn.net/feihe0755/article/details/54233714PDB文件的介绍PDB(ProgramDataBase),意即程序的基本数据,是VS编译链接时生成的文件。PDB文件主要存储了VS调试程序时所需要的基本信息,主要包括源文件名、变量名、函数名、FPO(帧指针)、对应的行号等等。因为存储的是调试信息,所以一般情况下PDB…

    2022年5月5日
    140
  • NeoKylin(中标麒麟)6.5 更新yum源「建议收藏」

    NeoKylin(中标麒麟)6.5 更新yum源「建议收藏」1.进入/etc/yum.repo.d目录:cd/etc/yum.repo.d2.将原来源文件重命名,例如:mvns6-adv-x86_64.repons6-adv-x86_64.repo.bak3.使用vim新编辑文件mirrors.163.com.repo:vimmirrors.163.com.repo,内容如下:[mirrors.163.com]name=mi…

    2022年8月10日
    39
  • Oracle 11g安装图文攻略「建议收藏」

    Oracle 11g安装图文攻略「建议收藏」Oracle11g****安装图文攻略一、Oracle下载注意Oracle分成两个文件,下载完后,将两个文件解压到同一目录下即可。路径名称中,最好不要出现中文,也不要出现空格等不规则字符。官方下地址:http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html以下两网址来源此官方下载页网。win32位操作系统下载地址:http://download.oracle.com/otn/nt

    2022年9月21日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号