zoukankan      html  css  js  c++  java
  • 读vue源码笔记

    gobal-api/index.js

    initMixin(Vue) 对Vue.mixin方法进行定义,参数为要混入到Vue.options对象的对象。

    Vue.mixin = function (mixin: Object) {
        this.options = mergeOptions(this.options, mixin)
        return this
      }

    gobal-api/use.js
    这段源码简单,global-api/use.js中,this._installedPlugins储存插件的数组。

    export function initUse (Vue: GlobalAPI) {
      Vue.use = function (plugin: Function | Object) {
        const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
       // 已经执行过了插件暴露的方法就不需要执行了
        if (installedPlugins.indexOf(plugin) > -1) {
          return this
        }
        // additional parameters,数组中的参数后移一位。
        const args = toArray(arguments, 1)
        args.unshift(this)
        // 第一个参数是vue本身了
        if (typeof plugin.install === 'function') {
        // 插件要实现install函数,或者本身就是函数,
          plugin.install.apply(plugin, args)
        } else if (typeof plugin === 'function') {
          plugin.apply(null, args)
        }
        installedPlugins.push(plugin)
        return this
      }
    使用的过程中:vue.use(vue-router); vue-router 是个函数,在window下执行plugin.apply(null, args)。第一个参数就是Vue。然后把函数推入installedPlugins数组中。
    mergeOptions是utils/options.js
    export function mergeOptions (
      parent: Object,
      child: Object,
      vm?: Component
    ): Object {
      if (process.env.NODE_ENV !== 'production') {
        //核实子对象中components的名字合法
        checkComponents(child)
      }
    
      if (typeof child === 'function') {
        child = child.options
      }
      // 对options中的props、inject、 directive格式化对象
      normalizeProps(child, vm)
      normalizeInject(child, vm)
      normalizeDirectives(child)
      // extends、mixins 格式化变成对象
      const extendsFrom = child.extends
      if (extendsFrom) {
        parent = mergeOptions(parent, extendsFrom, vm)
      }
      if (child.mixins) {
        for (let i = 0, l = child.mixins.length; i < l; i++) {
          parent = mergeOptions(parent, child.mixins[i], vm)
        }
      }
      const options = {}
      // 对 vm.constructor的成员和目前options成员的key进行自定义化处理,一般不会自定义化处理的。
      let key
      for (key in parent) {
        mergeField(key)
      }
      for (key in child) {
        if (!hasOwn(parent, key)) {
          mergeField(key)
        }
      }
      function mergeField (key) {
        const strat = strats[key] || defaultStrat
        options[key] = strat(parent[key], child[key], vm, key)
      }
      return options
    }

     initState

    // 对vm实例的props,method、data、computed、watch初始化。
    在beforeCreated 和created 钩子函数之间执行
    export function initState (vm: Component) {
      vm._watchers = []
      const opts = vm.$options
      if (opts.props) initProps(vm, opts.props)
      if (opts.methods) initMethods(vm, opts.methods)
      if (opts.data) {
        initData(vm)
      } else {
        observe(vm._data = {}, true /* asRootData */)
      }
      if (opts.computed) initComputed(vm, opts.computed)
      if (opts.watch && opts.watch !== nativeWatch) {
        initWatch(vm, opts.watch)
      }
    }
    
    export function pluckModuleFunction<F: Function> (
      modules: ?Array<Object>,
      key: string
    ): Array<F> {
      return modules
        ? modules.map(m => m[key]).filter(_ => _)
        : []
    }
    //看看下面的例子就明白了,map返回经过每个数组成员函数处理的的值的数组,filter返回每个成员经过函数处理返回为true的数组。
    function A (modules, key) {
      return modules
            ? modules.map(m => m[key]).filter(_ => _)
            : []
     }
    // map 处理返回[undefind, ['33']], filter返回['33'] let a
    = [{ '1': '11', '2': '22' },{ '1': '11', '3': '33' }] console.log(A(a, '3')) //['33']

    /compiler/helpers

    // 改变AST树的数据,如果removeFromMap为true, 则把AST树的attrsMap元素删除。最终返回name属性值。
    export function getAndRemoveAttr (
      el: ASTElement,
      name: string,
      removeFromMap?: boolean
    ): ?string {
      let val
      if ((val = el.attrsMap[name]) != null) {
        const list = el.attrsList
        for (let i = 0, l = list.length; i < l; i++) {
          if (list[i].name === name) {
            list.splice(i, 1)
            break
          }
        }
      }
      if (removeFromMap) {
        delete el.attrsMap[name]
      }
      return val
    }

     /parser/html-parser.js

    const start = html.match(startTagOpen) 
    // match匹配,/^<((?:[a-zA-Z_][w-.]*:)?[a-zA-Z_][w-.]*)/ 
    // ?:忽略分组
    if (start) {
      const match = {
        tagName: start[1], 
        attrs: [],
        start: index
      }
      advance(start[0].length)
      let end, attr
      // /^s*(/?)>/ 匹配 空格> 或者 空格/>
      while (!(end = html.match(startTagClose)) && (attr = html.match(attribute))) {
        advance(attr[0].length)
        match.attrs.push(attr)
      }
      // 可能是"/"
      if (end) {
        match.unarySlash = end[1]
        advance(end[0].length)
        match.end = index
        return match
      }
    }

    options.start 

    start (tag, attrs, unary, start, end) {
          // check namespace.
          // inherit parent ns if there is one
          const ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag)
    
          // handle IE svg bug
          /* istanbul ignore if */
          if (isIE && ns === 'svg') {
            attrs = guardIESVGBug(attrs)
          }
    
          let element: ASTElement = createASTElement(tag, attrs, currentParent)
          if (ns) {
            element.ns = ns
          }
    
          if (process.env.NODE_ENV !== 'production') {
            if (options.outputSourceRange) {
              element.start = start
              element.end = end
              element.rawAttrsMap = element.attrsList.reduce((cumulated, attr) => {
                cumulated[attr.name] = attr
                return cumulated
              }, {})
            }
            attrs.forEach(attr => {
              if (invalidAttributeRE.test(attr.name)) {
                warn(
                  `Invalid dynamic argument expression: attribute names cannot contain ` +
                  `spaces, quotes, <, >, / or =.`,
                  {
                    start: attr.start + attr.name.indexOf(`[`),
                    end: attr.start + attr.name.length
                  }
                )
              }
            })
          }
    
          if (isForbiddenTag(element) && !isServerRendering()) {
            element.forbidden = true
            process.env.NODE_ENV !== 'production' && warn(
              'Templates should only be responsible for mapping the state to the ' +
              'UI. Avoid placing tags with side-effects in your templates, such as ' +
              `<${tag}>` + ', as they will not be parsed.',
              { start: element.start }
            )
          }
    
          // apply pre-transforms
          for (let i = 0; i < preTransforms.length; i++) {
            element = preTransforms[i](element, options) || element
          }
    
          if (!inVPre) {
            processPre(element)  //处理v-pre,不参与编译。
            if (element.pre) {
              inVPre = true
            }
          }
          // 特定平台设置的不需要编译标签,默认没有。
          if (platformIsPreTag(element.tag)) {
            inPre = true
          }
          //  如果是不需要参与编译的element
          if (inVPre) {
            // ele得到一个数组,ele.attrs = []
            processRawAttrs(element)
          } else if (!element.processed) {
            // structural directives
            processFor(element)
            processIf(element)
            processOnce(element)
          }
    
          if (!root) {
            root = element
            if (process.env.NODE_ENV !== 'production') {
              //根节点不能有v-for,template,slot
              checkRootConstraints(root)
            }
          }
          //不是自闭标签
          if (!unary) {
             // 类似指针,形成链表,start 的核心代码
            currentParent = element
            stack.push(element)
          } else {
            closeElement(element)
          }
        },

     

    
    
  • 相关阅读:
    这个夏天,感动我的歌,感动我的你
    设计中最困难的部分在于决定要设计什么 设计原本择录
    Sql效能优化总结(续) sql语句优化篇
    sql效能优化总结
    使用AStyle进行代码格式化
    迭代模型 转
    软件项目开发系列开篇杂谈
    Sql效能优化总结(续) 架构调整篇
    throw和throw ex的区别
    面向过程&面向对象 UML&RUP
  • 原文地址:https://www.cnblogs.com/liuyinlei/p/10448735.html
Copyright © 2011-2022 走看看