读vue源码(1)

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
  }
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 (
  modules: ?Array,
  key: string
): Array {
  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
  }
}

 

 







你可能感兴趣的:(读vue源码(1))