首页 > 作文

Vue 2.0 深入源码分析(一) 代码结构

更新时间:2023-04-06 06:30:29 阅读: 评论:0

关于vue

vue是一个兴起的前端js库,是一个精简的mvvm。mvvm模式是由经典的软件架构mvc衍生来的,当view(视图层)变化时,会自动更新到viewmodel(视图模型),反之亦然,view和viewmodel之间通过双向绑定(data-binding)建立联系。

前言

花了一个月时间撸了vue2.0的源码,最近空了一点,今天开始记录一下学习心得,本人按照自己理解的代码的结构,分为三部分来讲

  基础篇    ;比如全局配置、模板渲染、data、method、computed、watch、生命周期、ref、组件原理、组件-props、组件自定义事件

  指令篇    ;比如v-bind、v-on、v-if、v-el、v-el-if、v-for、v-html、v-text、v-once、v-pre、v-model、v-show

  高级篇    ;过滤器、自定义指令、插槽、作用域插槽、异步组件、transition内置组件、transition-group内置组件、keep-alive内置组件

每一个知识点都会讲得比较详细,理解源码需要有较强的js知识。最后如果有遗漏的,最后再做一下补充,如果有问题,欢迎留言指出,非常感谢!

vue和jquery从源码看是差不多,都只是一个前端框架, 区别是一个是mvc模式,一个是mvvc模式。vue是把es5的defineproperty函数用到了极致,而jquery为了兼容低版本ie是没有封装这个api的,就像搭积木(对应的浏览器接口和ecmascript接口),vue用到了几个新的积木,而jquery没有用到而已。

vue实例化时会把模板(挂载到vue上的el元素对应的dom节点,或者template属性)转换成一个虚拟的vnode,并在更新dom时采用diff算法对dom树进行检测,只更新需要更新的dom节点,对于一些静态节点则不进行变更,以达到最快的速度。

本人采用的是v2.5.16这个版本的vue.js,本节先讲解vue源码的大致结构,

代码结构

vue.js源码就是一个立即执行匿名函数表达式,内部定义了一个vue函数对象,组后返回挂载到window的vue属性上,先复习一下立即执行匿名函数表达式,如下:

<!doctype html><html lang="en"><head>    <meta chart="utf-8">    <title>document</title></head><body>    <script>        (function(global,msg){                  global.alert(msg)    //运行时会弹出一个窗口,内容为:hello world        })(this,'hello world')    </script></body></html>

知道了匿名函数后,我们来看看在vue内部的样式,如下:

(function (global, factory) {         //在浏览器环境下global等于全局window    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.vue = factory()); //执行factory()函数,将返回值vue传递给window.vue}(this, (function () {           function vue(options) {               //内部定义的vue函数                               if ("development" !== 'production' && !(this instanceof vue)) {            warn('vue is a constructor and should be called with the `new` keyword');        }        this._init(options);                              }    return vue;                 //返回vue什么向荣这个函数对象})));

这样执行完这个匿名函数后就可以通过window.vue访问到匿名函数内的vue函数对象了。

这个匿名函数内部会在vue的原型对象上挂载很多方法幼幼性和属性以供我们使用,大致的主线流程如下(为了更好理解,去掉了所有分支)

(function (global, factory) {       typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.vue = factory()); //执行factory()函数,将返回值vue传递给window.vue}(this, (function () {    'u strict';    function vue(options) {                                     //vue的构造函数        if ("development" !== 'production' && !(this instanceof vue)) {            warn('vue is a constructor and should be called with the `new` keyword');        }        this._init(options);                                    //1.实例化时,先执行到这里进行初始化    }    function initmixin(vue) {              vue.prototype._init = function (options) {              //2.再执行到这里             /**/            if (vm.$options.el) {                               //如果有传入了挂载点的el节点                vm.$mount(vm.$options.el);                          //通过$mount函数把组件挂载到dom上面            }        }    }    function lifecyclemixin(vue) {          vue.prototype._update = function (vnode, hydrating) {   //7.更新操作,把vnode渲染成真实dom            /**/            if (!prevvnode) {                                       //如果prevvnode为空,即初始化时                vm.$el = vm.__patch__(vm.$el, vnode, hydrating, fal, vm.$options._parentelm, vm.$options._refelm);    //执行vm.__patch__方法渲染成真实的dom节点                vm.$options._parentelm = vm.$options._refelm = null;            } el {                                                //如果prevvnode不为空,即更新操作时                vm.$el = vm.__patch__(prevvnode, vnode);                //调用vm.__patch__进行更新操作            }        }    }    function rendermixin(vue) {         /**/        vue.prototype._render = function () {                   //6.把rener渲染成vnode        }    }    function mountcomponent(vm, el, hydrating) {                //5.挂载组件 vm:vue实例  el:真实的dom节点对象         /**/        var updatecomponent;        if ("development" !== 'production' && config.performance && mark) {                 /**/        } el {            updatecomponent = function () {vm._update(vm._1千瓦时是多少度电render(), hydrating);};   //渲染成vnode并转换为真实dom        }      惠普笔记本bios设置  new watcher(vm, updatecomponent, noop, null, true);                 //watcher实例创建后会通过get()方法执行updatecomponent()方法的        /**/    }    vue.prototype.__patch__ = inbrowr ? patch : noop;    vue.prototype.$mount = function (el, hydrating) {           //4.原型上的挂载(runtime-only版本)        el = el && inbrowr ? query(el) : undefined;               //进行一些修正,因为runtime-only版本是从这里开始执行的        return mountcomponent(this, el, 相信用英语怎么说hydrating)                  ////再调用mountcomponent方法    };    var mount = vue.prototype.$mount;                           //保存原型上的$mount函数    vue.prototype.$mount = function (el, hydrating) {           //3.解析源码(runtime+compiler版本用的)        /*中间进行模板的解析*/        return mount.call(this, el, hydrating)                      //最后执行mount    };    return vue;                             //最后返回vue函数对象,会作为一个vue属性挂载到window上})));

、后面源码讲解时会仔细讲每个细节的

本文发布于:2023-04-06 06:30:28,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/e4b2daf6593c805ec8fd48fbf92a4a1a.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:Vue 2.0 深入源码分析(一) 代码结构.doc

本文 PDF 下载地址:Vue 2.0 深入源码分析(一) 代码结构.pdf

下一篇:返回列表
标签:函数   组件   是一个   节点
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图