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<F: Function> ( modules: ?Array<Object>, key: string ): Array<F> { return modules ? modules.map(m => m[key]).filter(_ => _) : [] } //看看下面的例子就明白了 function A (modules, key) { return modules ? modules.map(m => m[key]).filter(_ => _) : [] } 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) if (start) { const match = { tagName: start[1], attrs: [], start: index } advance(start[0].length) let end, attr 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 } }