vue源码分析

双向数据绑定

1. js的eventloop

micro 微队列,promise的then,async await,observer, 优先级高于宏队列。window.MutationObserver属于observer

macro 宏队列,setTimeout,setInterval, click,event事件,ajax,

    var MutationObserver = window.MutationObserver;
        var target = document.querySelector(‘#some-id‘);
        var observer = new MutationObserver(function(mutations){
            mutations.forEach(function(mutation){
                console.log(mutation.type);
            })
        })
        var config = {
            attributes: true
        };
        observer.observe(target, config);
setTimeout(function(){
            console.log(15);
        },0)
        document.querySelector(‘#some-id‘).setAttribute(‘data-test‘,‘6‘);
        new Promise(function(resolve){
            console.log(1);
            resolve();
            console.log(2);
        }).then(function(){
            console.log(9);
        });

        new Promise(function(resolve){
            console.log(3);
            resolve();
            console.log(4);
        }).then(function(){
            console.log(10);
        });

        function fn(){
            return new Promise((resolve,reject)=>{
                resolve(12);
            })
        }

        function fn1(){
            return new Promise((resolve,reject)=>{
                resolve(14);
            })
        }
        //async 是等待的,promise是顺序执行的,然后then最后执行,类似setTimeout 0,但是要比setTimeout 0先执行
        (async function(){
            console.log(5);
            console.log(await fn()); //这里的微队列将后面的代码都压入队列中,是这么理解的,或者说后面是同步的了,执行完了才执行微队列
            console.log(13);
        })();

        (async function(){
            console.log(await fn1()); //这里等待fn执行完成,才执行下一行
        })();

        //微队列是先进先出的,符合队列的规则,但是如果await 后面不是promise对象的话会有区别,会将后面的语句压入微队列中
        (async function(){
            console.log(6);
            await console.log(7); //这里这么写会有问题,打乱了微队列的队形,11是所有的await中的前面,其他异步微队列的后面
            console.log(11);
        })();

2. nextTick就是使用微队列或是宏队列来实现的dom元素的异步更新,那为什么显示的内容改变了呢

这里使用$refs获取元素的innerHtml或value值,this.$refs是vue的一个属性,并不直接对应dom结构,可以理解为虚拟dom,但是,dom的更新不是根据虚拟dom的更新来的吗,为什么显示变了,虚拟dom反而没有变呢。

也就是说vue在创建的时候会生成vdom,和watcher,当有属性变化时,对比该dom节点和虚拟dom,不同的话直接更新dom,然后在微队列中更新vdom,也就是refs的值,所以直接使用是没有的?这里需要看下virtual dom是怎么更新的,dom diff是怎么比较的

新版本的vue的实现原理

proxy, reflect

vdom,dom遍历慢的原因是因为dom对象的属性和方法太多了,

dom diff

比较两颗dom树的差异,两个树完全的diff算法是一个时间复杂度为o(n^3)的问题,但是当在前端当中,你很少会跨越层级的移动dom,所以virtual dom只会对统一层级的元素进行对比,这样的算法复杂度就可以达到o(n)。

节点的拆一指的是什么呢,

a。替换原来的节点,例如把div换成section

b。移动、删除、新增子节点,例如,把子节点的p和ul的顺序互换

c。修改了节点的属性

d。对于文本节点,文本内容可能会改变

最好使用key标记dom,提高效率

专业版 patch和diff  https://github.com/snabbdom/sanbbdom

简陋版的diff和patch,https://github.com/livoras/simple-virtual-dom/blob/master/lib/diff.js  ,    https://github.com/livoras/simple-virtual-dom/blob/master/lib/patch.js

双向数据绑定的库   hyperapp, kbrsh/moon

2. vuex

view 驱动actions 然后驱动state,state再驱动view

核心模块

state,

Getters:纯操作,对state里的属性进行的操作,没有传进数据,

Mutations:和外部的交互方法,用store.commit(‘name‘)调用,

Actions:可以操作Mutations,可以实现异步调用,使用dispatch调用,可以设置调用次数,还可以使用async和await

Modules(合并用的)

vuex-router-sync

https://vuex.vuejs.org/guide/plugins.html

3. vue运行时的优化

静态的优化,循环优化,ssr的输出,ssr的优化(preload,prefetch)

增加新的优化,

css的抽象原子css

Prepack

4. 路由的实现,或者说spa的实现

三种模式,我们用到的是两种hash和history,history在h5中新增加了 pushState和repalceState方法,

window.history.pushState(stateObject,title,url)
window.history,replaceState(stateObject,title,url)

2个方法有个共同的特点:当调用他们修改浏览器历史栈后,虽然当前url改变了,但浏览器不会立即发送请求该url,这就为单页应用前端路由,更新视图但不重新请求页面提供了基础。

修改之后监听修改就可实现视图的修改,在HTML5History中添加对修改浏览器地址栏URL的监听popstate是直接在构造函数中执行的

https://segmentfault.com/a/1190000014822765

原文地址:https://www.cnblogs.com/wenwenli/p/9184297.html

时间: 2024-10-04 12:39:05

vue源码分析的相关文章

[Vue源码分析] v-model实现原理

最近小组有个关于vue源码分析的分享会,提前准备一下- 前言:我们都知道使用v-model可以实现数据的双向绑定,及实现数据的变化驱动dom的更新,dom的更新影响数据的变化.那么v-model是怎么实现这一原理的呢?接下来探索一下这部分的源码. 前期准备①:vue2.5.2源码(用于阅读.查看关联等)②:建立vue demo,创建包含v-model指令的实例(用于debugger)以下为demo: genDirectives在模板的编译阶段, v-model跟其他指令一样,会被解析到 el.d

vue源码分析:响应式之依赖收集

今天记录下vue源码的响应式的源码学习,第一步,我们想下,为什么为们写一个data.然后里边的数据变化就能映射到dom的变化上.这里用到了Object.defineProperty(obj,key, {}),如果你还不了解建议去jsmdn上仔细了解下,这个函数的目的就是检测你得赋值和取值的过程用来定义自己的行为,比如obj[key]会拿到配置里边的get函数定义,obj[key] = 'xxx'会调用配置中的set.那么vue也是一样的,在get中做了依赖收集(也就是说哪些dom用到了我定义的这

vue 源码分析之如何实现 observer 和 watcher

https://segmentfault.com/a/1190000004384515 本文能帮你做什么? ..好奇vue双向绑定的同学, 可以部分缓解好奇心 还可以帮你了解如何实现$watch 前情回顾 我之前写了一篇没什么干货的文章..并且刨了一个大坑.. 今天..打算来填一天..并再刨一个..哈哈 不过话说说回来了.看本文之前,, 如果不知道Object.defineProperty,还必须看看解析神奇的 Object.defineProperty 不得不感慨vue的作者,人长得帅,码写的

Vue源码分析(二) : Vue实例挂载

author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-with-compiler.js & src/platforms/web/runtime/index.js 等文件中都有对Vue.prototype.$mount的定义: // vue/platforms/web/entry-runtime-with-compiler.js Vue.prototype.$mount = function ( e

vue源码分析之目录架构(一)

compiler compiler 目录包含 Vue.js 所有编译相关的代码.它包括把模板解析成 ast 语法树,ast 语法树优化,代码生成等功能 core core 目录包含了 Vue.js 的核心代码,包括内置组件.全局 API 封装,Vue 实例化.观察者.虚拟 DOM.工具函数等等. platform Vue.js 是一个跨平台的 MVVM 框架,它可以跑在 web 上,也可以配合 weex 跑在 native 客户端上.platform 是 Vue.js 的入口,2 个目录代表 2

vue2.0源码分析之理解响应式架构

https://segmentfault.com/a/1190000007334535 分享前啰嗦 我之前介绍过vue1.0如何实现observer和watcher.本想继续写下去,可是vue2.0横空出世..所以   直接看vue2.0吧.这篇文章在公司分享过,终于写出来了.我们采用用最精简的代码,还原vue2.0响应式架构实现   以前写的那篇 vue 源码分析之如何实现 observer 和 watcher可以作为本次分享的参考.   不过不看也没关系,但是最好了解下Object.defi

vue源码构建代码分析

这是xue源码学习记录,如有错误请指出,谢谢!相互学习相互进步. vue源码目录为 vue ├── src #vue源码 ├── flow #flow定义的数据类型库(vue通过flow来检测数据类型是否正确) ├── examples #demo ├── scripts #vue构建命令 ├── ... vue内部代码模块比较清晰,这边主要分析scripts内部代码,讲解vue是如何进行构建的.首先你必须要懂一些rollup,vue内部是通过rollup来进行构建的,rollup是一款js的构

Vue 2.0 深入源码分析(五) 基础篇 methods属性详解

用法 methods中定义了Vue实例的方法,官网是这样介绍的: 例如:: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script> <title>Document&

Vue 2.0 深入源码分析(六) 基础篇 computed 属性详解

用法 模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑会让模板过重且难以维护,比如: <div id="example">{{ message.split('').reverse().join('') }}</div> <script> var app = new Vue({ el:'#example', data:{message:'hello world'} }) </script> 这样模板不再是简