资讯专栏INFORMATION COLUMN

vue源码阅读笔记

hightopo / 622人阅读

摘要:说明源码万多行,完全解析透太耗时间里面细节处理很多,通读代码,语法都不难个人认为重点在于理解它的思想,掌握面向数据编程的原理。一案例代码及运行流程用说明里面提供的命令行,生成的项目,稍微改动。

说明
vue源码1万多行,完全解析透太耗时间;里面细节处理很多,通读代码,语法都不难;个人认为重点在于理解它的思想,掌握面向数据编程的原理。
通过一个合适的例子,断点调试来查看代码运行流程,可以快速了解编码的思路。
vue@2.5.13

一、案例代码及运行流程

用api说明里面提供的命令行,生成的vue项目,稍微改动。
目录结构:

components/HelloWorld.vue






router/index.js

import Vue from "vue"
import Router from "vue-router"
import index from "../index.vue"

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: "/",
      name: "index",
      component: index
    }
  ]
})

App.vue





index.vue







main.js

import Vue from "vue"
import App from "./App"
import router from "./router"
import helloworld from "./components/HelloWorld.vue"

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: "#app",
  router,
  components: { App, helloworld},
  template: ""
})
断点运行流程

建议用工具打开,里面的缩进代表函数的层级关系

function Vue$3 (options) { //创建新的vue实例
    this._init(options);    //初始化
          vm.$options = mergeOptions( //混合options
            resolveConstructorOptions(vm.constructor), //获取构造函数Vue$3的options对象;key有beforeCreate、components、destroyed、directives、filters、_base
            options || {},
            vm
        );
            checkComponents(child);//验证options里面components的命名
                validateComponentName(key);//校验components的命名合法性
            normalizeProps(child, vm);//规范props;无值返回;数组[string]返{string:{ type: null }},对象{key:val}返回 val为string为{key:{type:val}},val为obj为{key:val}
            normalizeInject(child, vm);//规范inject;无值返回;数组[string]返{string:{ from: string }},对象{key:val}返回 val为string为{key:{from:val}},val为obj为{key:extend({from:key},val)}
            normalizeDirectives(child);//规范directives;无值不处理;默认为对象{key:def},仅处理def类型为function,返回{key:{bind:def,update:def}}
            mergeField(key);  
            //parent
                //components、directives、filters调用mergeAssets;  浅合并child到parent
                //_base调用defaultStrat;  child无值取parent,有值取child
                //beforeCreate、destroyed调用mergeHook;  child无值取parent,child有值 parent有值取parent.concat(child);parent无值 child是数组取child,不是数组取[child]
            //child父级无此属性执行
                //el调用strats.el; return defaultStrat(parent, child)
                //router、template调用defaultStrat
                //components父级有,忽略
        initProxy(vm);
            vm._renderProxy = new Proxy(vm, handlers);//handlers = hasHandler
        initLifecycle(vm);
            /**
            此时vm={
                _uid: 0,
                _isVue: true,
                $options: {
                    beforeCreate: [1],
                    destroyed: [1],
                    directives: {},
                    filters: {},
                    _base: Vue$3(options),
                    el: "#app",
                    router: VueRouter,
                    template: "",
                    components:{
                        App: {},
                        helloworld: {}
                    }
                },
                _renderProxy: new Proxy(vm, hasHandler),
                $parent: undefined,
                $root: vm,
                $children: [],
                $refs: {},
                _watcher: null,
                _inactive: null,
                _directInactive: false,
                _isMounted: false,
                _isDestroyed: false,
                _isBeingDestroyed: false
            }
            **/
        initEvents(vm);
            /**
            vm添加
            {
                _events: {},
                _hasHookEvent: false
            }
            **/
        initRender(vm);
            /**
            vm添加
            {
                _vnode: null,
                _staticTrees: null,
                $vnode: undefined,
                $slots: {},
                $scopedSlots: {},
                _c: function (a, b, c, d) { return createElement(vm, a, b, c, d, false); },
                $createElement: function (a, b, c, d) { return createElement(vm, a, b, c, d, true); }
            }
            **/
              defineReactive();
                var dep = new Dep();
            /**
            此时vm添加
            {
                $attrs: ,
                $listeners: 
            }
            监听属性变动
            **/
        callHook(vm, "beforeCreate");
            beforeCreate: function beforeCreate () {}//调用vue-router.js方法
                this._router.init(this);//调用vue-router.js
                    this.apps.push(app);//app为此vue实例
                    var setupHashListener = function () {
                        history.setupListeners();
                    };
                    history.transitionTo(
                      history.getCurrentLocation(),//调return getHash();返回href;
                      setupHashListener,
                      setupHashListener
                    );
                Vue.util.defineReactive(this, "_route", this._router.history.current);
                    var dep = new Dep();
                registerInstance(this, this);

            Vue.extend = function (extendOptions) {
                validateComponentName(name);
                var Sub = function VueComponent (options) {
                    this._init(options);
                };
                Sub.options = mergeOptions(
                    Super.options,
                    extendOptions
                );
                return Sub;
        initInjections(vm); // resolve injections before data/props
            var result = resolveInject(vm.$options.inject, vm);
        initState(vm);
            /**
            vm添加
            {
                _watchers: [],
                _data: {}
            }
            **/
            observe(vm._data = {}, true /* asRootData */);
                ob = new Observer(value);
                    var dep = new Dep();
                    def(value, "__ob__", this);
                    this.walk(value);
        initProvide(vm); 
        callHook(vm, "created");

        vm.$mount(vm.$options.el);
            el = el && query(el);//获取el元素
            var ref = compileToFunctions(template, {}, this)
                new Function("return 1");
                var compiled = compile(template, options);
                    var finalOptions = Object.create(baseOptions);
                    /*
                    baseOptions = {
                          expectHTML: true,
                          modules: [{
                                  staticKeys: ["staticClass"],
                                  transformNode: transformNode,
                                  genData: genData
                            },
                            {
                                  staticKeys: ["staticStyle"],
                                  transformNode: transformNode$1,
                                  genData: genData$1
                            },
                            {
                                  preTransformNode: preTransformNode
                            }],
                          directives: {
                                  model: model,
                                  text: text,
                                  html: html
                            },
                          isPreTag: isPreTag,
                          isUnaryTag: isUnaryTag,
                          mustUseProp: mustUseProp,
                          canBeLeftOpenTag: canBeLeftOpenTag,
                          isReservedTag: isReservedTag,
                          getTagNamespace: getTagNamespace,
                          staticKeys: genStaticKeys(modules$1)
                    };
                    */
                    var compiled = baseCompile(template, finalOptions);
                        var ast = parse(template.trim(), options);
                            transforms = pluckModuleFunction(options.modules, "transformNode");
                            //例:pluckModuleFunction(modules,key);遍历modules,返回键为key的值的数组
                            //transforms=[transformNode,transformNode$1]
                            preTransforms = pluckModuleFunction(options.modules, "preTransformNode");
                            postTransforms = pluckModuleFunction(options.modules, "postTransformNode");
                            parseHTML(template, {})
                                var startTagMatch = parseStartTag();
                                /*例
                                    startTagMatch = {
                                        attrs: [],
                                        end: 6,
                                        start: 0,
                                        tagName: "App",
                                        unarySlash: "/"
                                    }
                                */
                                handleStartTag(startTagMatch);
                                    options.start(tagName, attrs, unary, match.start, match.end);
                                        var element = createASTElement(tag, attrs, currentParent);
                                        /*
                                            element = {
                                                type: 1,
                                                tag: tag,
                                                attrsList: attrs,
                                                attrsMap: makeAttrsMap(attrs),
                                                parent: parent,
                                                children: []
                                            }
                                        */
                                        element = preTransforms[i](element, options) || element;//preTransformNode(el, options);仅处理tag为input
                                        processPre(element);//v-pre
                                        processFor(element);//v-for
                                             //getAndRemoveAttr(el, name, removeFromMap)删除el.attrsList数组里的name,removeFromMap为真删除el.attrsMap[name],返回el.attrsMap[name]
                                        processIf(element);//v-if v-else-if v-else
                                        processOnce(element);//v-once
                                        processElement(element, options);
                                            processKey(element);//key
                                                //getBindingAttr(el, name, getStatic);返回绑定的属性值;有:name或v-bind:name返回parseFilters(getAndRemoveAttr(el,":"+name||"v-bind:"+name)),没有动态属性值查找静态;getStatic不为false,有name,返回JSON.stringify(getAndRemoveAttr(el,name))
                                            processRef(element);//ref
                                            processSlot(element);//slot||template||slot-scope
                                            processComponent(element);//is||inline-template
                                            element = transforms[i](element, options) || element;//transformNode(element, options);transformNode$1(element, options);处理class和style
                                            processAttrs(element);//处理attrsList里的属性值
                                        checkRootConstraints(root);//组件根约束,slot、template、v-for
                                        closeElement(element);
                                parseEndTag();
                            return root;
                            /*
                            root={
                                attrsList: [],
                                attrsMap: {},
                                children: [],
                                parent: undefined,
                                plain: true,
                                tag: "App",
                                type: 1
                            }
                            */
                        optimize(ast, options);
                            isStaticKey = genStaticKeysCached(options.staticKeys || "");
                            /*
                            isStaticKey=function (val) { return map[val]; }
                            map={
                                type: true,
                                tag: true,
                                attrsList: true,
                                attrsMap: true,
                                plain: true,
                                parent: true,
                                children: true,
                                attrs: true,
                                staticClass: true,
                                staticStyle: true
                            }
                            */
                            markStatic$1(root);
                                node.static = isStatic(node);//false
                            markStaticRoots(root, false);
                                node.staticRoot = false;
                        var code = generate(ast, options);
                            var state = new CodegenState(options);
                            var code = ast ? genElement(ast, state) : "_c("div")";
                            //code="_c("App")"
                        /*
                        code={
                            render: "with(this){return _c("App")}",
                            staticRenderFns: []
                        }
                        */
                    /*
                    compiled={
                        ast: {
                            attrsList: [],
                            attrsMap: {},
                            children: [],
                            parent: undefined,
                            plain: true,
                            static: false,
                            staticRoot: false,
                            tag: "App",
                            type: 1
                        },
                        render: "with(this){return _c("App")}",
                        staticRenderFns: []
                    }
                    */
                    errors.push.apply(errors, detectErrors(compiled.ast));
                        checkNode(ast, errors);
                /*
                compiled加{
                    errors: [],
                    tips: []
                }
                */        
                res.render = createFunction(compiled.render, fnGenErrors);
                    return new Function(code)
            /*
            res={
                render: function anonymous(){with(this){return _c("App")}}
                staticRenderFns: []
            }
            */
            return mount.call(this, el, hydrating)
            /*注:
                var mount = Vue$3.prototype.$mount;   //1
                Vue$3.prototype.$mount = function(){} //2
                初次调用,1被2重写,调用2;
                此时调用,指定mount,调用1;
            */
                el = el && inBrowser ? query(el) : undefined;//获取el元素
                    return el;
                return mountComponent(this, el, hydrating)
                    callHook(vm, "beforeMount");
                    updateComponent = function () {
                          vm._update(vm._render(), hydrating);
                    };
                    new Watcher(vm, updateComponent, noop, null, true /* isRenderWatcher */);
                        /*
                        此时Watcher
                        Watcher={
                            active: true,
                            cb: ƒ noop(a, b, c),
                            deep: false,
                            depIds: Set(0) {},
                            deps: [],
                            dirty: false,
                            expression: "function () {↵      vm._update(vm._render(), hydrating);↵    }",
                            getter: ƒ (),
                            id: 1,
                            lazy: false,
                            newDepIds: Set(0) {},
                            newDeps: [],
                            sync: false,
                            user: false,
                            vm : vue实例
                        }
                        */
                        this.get();
                            pushTarget(this);//将Watcher实例赋值给Dep._target;
                            value = this.getter.call(vm, vm);
                                 vm._update(vm._render(), hydrating);
                                      Vue.prototype._render
                                          vnode = render.call(vm._renderProxy, vm.$createElement);
                                              vm._c = function (a, b, c, d) { return createElement(vm, a, b, c, d, false); };
                                                    return _createElement(context, tag, data, children, normalizationType)//(vue实例, "App", undefined, undefined, undefined)
                                                        vnode = createComponent(Ctor, data, context, children, tag);//(组件App, undefined, vue实例, undefined, "App" )
                                                            Ctor = baseCtor.extend(Ctor);
                                                                validateComponentName(name);
                                                                var Sub = function VueComponent (options) {
                                                                Sub.options = mergeOptions(Super.options,extendOptions);
                                                                    checkComponents(child);
                                                                    normalizeProps(child, vm);
                                                                        name = camelize(key);

                                                                      normalizeInject(child, vm);
                                                                      normalizeDirectives(child);
                                                                      mergeField(key); 
                                                                      //parent
                                                                        //components、directives、filters调用mergeAssets;  浅合并child到parent,child无值取{}
                                                                        //_base调用defaultStrat;  child无值取parent,有值取child
                                                                        //beforeCreate、destroyed调用mergeHook;  child无值取parent,child有值 parent有值取parent.concat(child);parent无值 child是数组取child,不是数组取[child]
                                                                    //child父级无此属性执行
                                                                        //beforeDestroy调用mergeHook;
                                                                        //name、render、staticRenderFns、_compiled、_file、_Ctor调用defaultStrat
                                                                        //beforeCreate父级有,忽略
                                                                  ASSET_TYPES.forEach(function (type) {})
                                                                return Sub;
                                                            //Ctor=Sub;
                                                            resolveConstructorOptions (Ctor)
                                                                var superOptions = resolveConstructorOptions(Ctor.super);
                                                                //递归获取最初的options
                                                            //返回混合后的options
                                                            var propsData = extractPropsFromVNodeData(data, Ctor, tag);
                                                            mergeHooks(data);//data={on:undefined};
                                                            var vnode = new VNode()//("vue-component-4-App",data1, undefined, undefined, undefined, vue实例,组件options, undefined,)
                                                            /*
                                                            data1={
                                                                hook: {
                                                                    destroy: ƒ destroy(vnode),
                                                                    init: ƒ init( vnode, hydrating, parentElm, refElm ),
                                                                    insert: ƒ insert(vnode),
                                                                    prepatch: ƒ prepatch(oldVnode, vnode)
                                                                },
                                                                on: undefined
                                                            }
                                                            组件options={
                                                                Ctor: ƒ VueComponent(options)
                                                                children: undefined
                                                                listeners: undefined
                                                                propsData: undefined
                                                                tag: "App"
                                                            }
                                                            */
                                                            return vnode;
                                                            /*
                                                            vnode={
                                                                asyncFactory: undefined
                                                                asyncMeta: undefined
                                                                children: undefined
                                                                componentInstance: undefined
                                                                componentOptions: {Ctor: ƒ, propsData: undefined, listeners: undefined, tag: "App", children: undefined}
                                                                context: Vue$3 {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue$3, …}
                                                                data: {on: undefined, hook: {…}}
                                                                elm: undefined
                                                                fnContext: undefined
                                                                fnOptions: undefined
                                                                fnScopeId: undefined
                                                                isAsyncPlaceholder: false
                                                                isCloned: false
                                                                isComment: false
                                                                isOnce: false
                                                                isRootInsert: true
                                                                isStatic: false
                                                                key: undefined
                                                                ns: undefined
                                                                parent: undefined
                                                                raw: false
                                                                tag: "vue-component-4-App"
                                                                text: undefined
                                                            }
                                                            */
                                                        return vnode
                                                    //vnode
                                        //vnode
                                        return vnode;
                                    //参数vm._render()为vnode = new VNode();
                                    vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false, vm.$options._parentElm, vm.$options._refElm)
                                        oldVnode = emptyNodeAt(oldVnode);
                                            return new VNode(nodeOps.tagName(elm).toLowerCase(), {}, [], undefined, elm)
                                        var oldElm = oldVnode.elm;
                                        var parentElm$1 = nodeOps.parentNode(oldElm);//parentElm$1=body;
                                        createElm(vnode, insertedVnodeQueue, oldElm._leaveCb ? null : parentElm$1, nodeOps.nextSibling(oldElm) );
                                            if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {}
                                                i(vnode, false /* hydrating */, parentElm, refElm);//i=componentVNodeHooks.init
                                                    var child = vnode.componentInstance = createComponentInstanceForVnode()//(vnode,vue实例,body,下一节点)
                                                        return new vnode.componentOptions.Ctor(options)
                                                        /*
                                                        调function VueComponent (options);
                                                        options={
                                                            parent: Vue$3 {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue$3, …}
                                                            _isComponent: true
                                                            _parentElm: body
                                                            _parentVnode: VNode {tag: "vue-component-4-App", data: {…}, children: undefined, text: undefined, elm: undefined, …}
                                                            _refElm: text
                                                        }
                                                        */
                                                            this._init(options);
                                                            /*
                                                            重新调用_init方法;
                                                            var Sub = function VueComponent (options) {
                                                                this._init(options);
                                                            };
                                                            */
                                                                initInternalComponent(vm, options);
                                                                initProxy(vm);
                                                                vm._renderProxy = new Proxy(vm, handlers);//handlers为getHandler
                                                                initLifecycle(vm);
                                                                initEvents(vm);
                                                                initRender(vm);
                                                                    defineReactive(vm, "$attrs", parentData && parentData.attrs || emptyObject, function () {
                                                                        !isUpdatingChildComponent && warn("$attrs is readonly.", vm);
                                                                    }, true);
                                                                    defineReactive(vm, "$listeners", options._parentListeners || emptyObject, function () {
                                                                        !isUpdatingChildComponent && warn("$listeners is readonly.", vm);
                                                                    }, true);
                                                                callHook(vm, "beforeCreate");
                                                                initInjections(vm); // resolve injections before data/props
                                                                initState(vm);
                                                                initProvide(vm); // resolve provide after data/props
                                                                callHook(vm, "created");
                                                    /*
                                                    child={
                                                        $attrs: (...),
                                                        $children: [],
                                                        $createElement: ƒ (a, b, c, d),
                                                        $listeners: (...),
                                                        $options: {parent: Vue$3, _parentVnode: VNode, _parentElm: body, _refElm: text, propsData: undefined, …},
                                                        $parent: Vue$3 {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue$3, …},
                                                        $refs: {},
                                                        $root: Vue$3 {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue$3, …},
                                                        $scopedSlots: {},
                                                        $slots: {},
                                                        $vnode: VNode {tag: "vue-component-4-App", data: {…}, children: undefined, text: undefined, elm: undefined, …},
                                                        _c: ƒ (a, b, c, d),
                                                        _data: {__ob__: Observer},
                                                        _directInactive: false,
                                                        _events: {},
                                                        _hasHookEvent: false,
                                                        _inactive: null,
                                                        _isBeingDestroyed: false,
                                                        _isDestroyed: false,
                                                        _isMounted: false,
                                                        _isVue: true,
                                                        _renderProxy: Proxy {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …},
                                                        _routerRoot: Vue$3 {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue$3, …},
                                                        _self: VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …},
                                                        _staticTrees: null,
                                                        _uid: 1,
                                                        _vnode: null,
                                                        _watcher: null,
                                                        _watchers: []
                                                    }
                                                    */
                                                    child.$mount(hydrating ? vnode.elm : undefined, hydrating);
                                                        return mount.call(this, el, hydrating)
                                                            return mountComponent(this, el, hydrating)
                                                                callHook(vm, "beforeMount");
                                                                updateComponent = function () {
                                                                    vm._update(vm._render(), hydrating);
                                                                };
                                                                new Watcher(vm, updateComponent, noop, null, true /* isRenderWatcher */);
                                                                    this.get();
                                                                        pushTarget(this);
                                                                        value = this.getter.call(vm, vm);
                                                                        vm._update(vm._render(), hydrating);
                                                                            vnode = render.call(vm._renderProxy, vm.$createElement);
                                                                            /*
                                                                            App.vue;
                                                                            var render = function() {
                                                                                var _vm = this
                                                                                var _h = _vm.$createElement
                                                                                var _c = _vm._self._c || _h
                                                                                return _c(
                                                                                    "div",
                                                                                    { attrs: { id: "app" } },
                                                                                    [
                                                                                          _c("img", { attrs: { src: require("./assets/logo.png") } }),
                                                                                          _vm._v(" "),
                                                                                          _c("router-view")
                                                                                    ],
                                                                                    1
                                                                                  )
                                                                            }
                                                                            */
                                                initComponent(vnode, insertedVnodeQueue);
                                                    insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert);
                                                    if (isPatchable(vnode)) {}
                                                          invokeCreateHooks(vnode, insertedVnodeQueue);
                                                              cbs.create[i$1](emptyNode, vnode);//updateAttrs、updateClass、updateDOMListeners、updateDOMProps、updateStyle、_enter_、create、updateDirectives
                                                                   //_enter_
                                                                   enter(vnode);
                                                                   //create
                                                                   registerRef(vnode);
                                                          setScope(vnode);
                                            nodeOps.createElement(tag, vnode);
                                            setScope(vnode);
                                            createChildren(vnode, children, insertedVnodeQueue);
                                                checkDuplicateKeys(children);
                                                //3个createElm
                                                createElm(children[i], insertedVnodeQueue, vnode.elm, null, true);
                                                    if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {}
                                                    nodeOps.createElement(tag, vnode);
                                                    setScope(vnode);
                                                    createChildren(vnode, children, insertedVnodeQueue);
                                                    invokeCreateHooks(vnode, insertedVnodeQueue);
                                                        cbs.create[i$1](emptyNode, vnode);
                                                    insert(parentElm, vnode.elm, refElm);
                                                        nodeOps.appendChild(parent, elm);
                                                createElm(children[i], insertedVnodeQueue, vnode.elm, null, true);
                                                    if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {}
                                                    vnode.elm = nodeOps.createTextNode(vnode.text);
                                                      insert(parentElm, vnode.elm, refElm);
                                                          nodeOps.appendChild(parent, elm);
                                                  createElm(children[i], insertedVnodeQueue, vnode.elm, null, true);
                                                    if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {}
                                                        i(vnode, false /* hydrating */, parentElm, refElm);
                                                        initComponent(vnode, insertedVnodeQueue);
                                                            insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert);
                                                            if (isPatchable(vnode)) {}
                                                                invokeCreateHooks(vnode, insertedVnodeQueue);
                                                                    cbs.create[i$1](emptyNode, vnode);//updateAttrs、updateClass、updateDOMListeners、updateDOMProps、updateStyle、_enter_、create、updateDirectives
                                                                           //_enter_
                                                                           enter(vnode);
                                                                           //create
                                                                           registerRef(vnode);
                                                                  setScope(vnode);
                                              invokeCreateHooks(vnode, insertedVnodeQueue);
                                              insert(parentElm, vnode.elm, refElm);
                                                  nodeOps.insertBefore(parent, elm, ref$$1);//页面展示出来,created data;
                                          invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch);
                                          return vnode.elm
                              popTarget();
                                  Dep.target = targetStack.pop();
                              this.cleanupDeps();
                                  dep.removeSub(this$1);
                                      remove(this.subs, sub);
                                  this.newDepIds.clear();
                              return value;//value=undefined;
                      return vm;//$el为div#app这个VueComponent;



二、数据双向绑定原理

这边有一篇文章 剖析Vue原理&实现双向绑定MVVM 讲的很细,就不再重复写
以上面文章的内容为基础补充一张 vue数据双向绑定原理图

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93298.html

相关文章

  • Vuex源码阅读笔记

    摘要:而钻研最好的方式,就是阅读的源代码。整个的源代码,核心内容包括两部分。逃而动手脚的代码,就存在于源代码的中。整个源代码读下来一遍,虽然有些部分不太理解,但是对和一些代码的使用的理解又加深了一步。 笔记中的Vue与Vuex版本为1.0.21和0.6.2,需要阅读者有使用Vue,Vuex,ES6的经验。 起因 俗话说得好,没有无缘无故的爱,也没有无缘无故的恨,更不会无缘无故的去阅读别人的源...

    hosition 评论0 收藏0
  • Vue原理】Vue源码阅读总结大会 - 序

    摘要:扎实基础幸好自己之前花了大力气去给自己打基础,让自己现在的基础还算不错。 写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【2.5.17】 如果你觉得排版难看,请点击 下面链接 或者 拉到 下面关注公众号也可以吧 【Vue原理】Vue源码阅读总结大会 - 序 阅读源码是需...

    Edison 评论0 收藏0
  • 笔记Vue数据响应式绑定原理—观源码

    摘要:没有具体对应源码分析,只是阅读源码的笔记,等之后学好点再写成文章,构造生成的。带指令的所有元素,通过获取,涉及,返回属性选择器对里的进行绑定处理节点提取所有,返回数组,元素是对象,包含。 没有具体对应源码分析,只是阅读源码的笔记,等之后学好点再写成文章 Vue self,构造生成的this。 root根元素。 els带指令的所有元素,通过querySelectorAll获取,涉及ge...

    Chiclaim 评论0 收藏0
  • Vue.js 源码学习笔记

    摘要:实际上,我在看代码的过程中顺手提交了这个,作者眼明手快,当天就进行了修复,现在最新的代码里已经不是这个样子了而且状态机标识由字符串换成了数字常量,解析更准确的同时执行效率也会更高。 最近饶有兴致的又把最新版 Vue.js 的源码学习了一下,觉得真心不错,个人觉得 Vue.js 的代码非常之优雅而且精辟,作者本身可能无 (bu) 意 (xie) 提及这些。那么,就让我来吧:) 程序结构梳...

    darkbaby123 评论0 收藏0
  • Vue.js 源码学习笔记

    摘要:实际上,我在看代码的过程中顺手提交了这个,作者眼明手快,当天就进行了修复,现在最新的代码里已经不是这个样子了而且状态机标识由字符串换成了数字常量,解析更准确的同时执行效率也会更高。 最近饶有兴致的又把最新版 Vue.js 的源码学习了一下,觉得真心不错,个人觉得 Vue.js 的代码非常之优雅而且精辟,作者本身可能无 (bu) 意 (xie) 提及这些。那么,就让我来吧:) 程序结构梳...

    jsdt 评论0 收藏0

发表评论

0条评论

hightopo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<