Explorar o código

mergeOptions should perform 3-way merge for assets

Evan You %!s(int64=12) %!d(string=hai) anos
pai
achega
64870b77ee
Modificáronse 6 ficheiros con 51 adicións e 36 borrados
  1. 1 5
      src/api/global.js
  2. 0 1
      src/api/lifecycle.js
  3. 14 12
      src/instance/init.js
  4. 1 1
      src/instance/scope.js
  5. 34 14
      src/util/index.js
  6. 1 3
      src/util/lang.js

+ 1 - 5
src/api/global.js

@@ -43,11 +43,7 @@ exports.extend = function (extendOptions) {
   }
   Sub.prototype = Object.create(Super.prototype)
   _.define(Sub.prototype, 'constructor', Sub)
-  Sub.options = _.mergeOptions(
-    Super.options,
-    extendOptions,
-    true // indicates an inheritance merge
-  )
+  Sub.options = _.mergeOptions(Super.options, extendOptions)
   Sub.super = Super
   // allow further extension
   Sub.extend = Super.extend

+ 0 - 1
src/api/lifecycle.js

@@ -12,7 +12,6 @@ var _ = require('../util')
 exports.$mount = function (el) {
   this._initElement(el)
   this._compile()
-  this._isMounted = true
 }
 
 /**

+ 14 - 12
src/instance/init.js

@@ -11,20 +11,29 @@ var _ = require('../util')
  */
 
 exports._init = function (options) {
+
+  options = options || {}
+
+  this.$el          = null
+  this.$parent      = options.parent
+  this._isBlock     = false
+  this._isDestroyed = false 
+  this._rawContent  = null
+
   // merge options.
   this.$options = _.mergeOptions(
     this.constructor.options,
-    options
+    options,
+    this
   )
 
   // create scope.
-  // @creates this.$parent
   // @creates this.$scope
   this._initScope()
 
   // setup initial data.
   // @creates this._data
-  this._initData(this.$options.data || {}, true)
+  this._initData(options.data || {}, true)
 
   // setup property proxying
   this._initProxy()
@@ -33,15 +42,8 @@ exports._init = function (options) {
   // @creates this._rootBinding
   this._initBindings()
 
-  // compilation and lifecycle related state properties
-  this.$el = null
-  this._rawContent = null
-  this._isBlock = false
-  this._isMounted = false
-  this._isDestroyed = false 
-
   // if `el` option is passed, start compilation.
-  if (this.$options.el) {
-    this.$mount(this.$options.el)
+  if (options.el) {
+    this.$mount(options.el)
   }
 }

+ 1 - 1
src/instance/scope.js

@@ -11,7 +11,7 @@ var scopeEvents = ['set', 'mutate', 'add', 'delete']
  */
 
 exports._initScope = function () {
-  var parent = this.$parent = this.$options.parent
+  var parent = this.$parent
   var scope = this.$scope = parent
     ? Object.create(parent.$scope)
     : {}

+ 34 - 14
src/util/index.js

@@ -1,8 +1,8 @@
 var _ = exports
+var config = require('../config')
 var env = require('./env')
 var lang = require('./lang')
 var dom = require('./dom')
-
 var mixin = lang.mixin
 
 mixin(_, env)
@@ -13,6 +13,12 @@ mixin(_, dom)
  * Option overwriting strategies are functions that handle
  * how to merge a parent option value and a child option
  * value into the final value.
+ *
+ * All strategy functions follow the same signature:
+ *
+ * @param {*} parentVal
+ * @param {*} childVal
+ * @param {Vue} [vm]
  */
 
 var strats = {}
@@ -32,26 +38,39 @@ strats.paramAttributes = function (parentVal, childVal) {
 }
 
 /**
- * Assets, methods and computed properties are hash objects,
- * and are merged with prototypal inheritance.
+ * Assets
+ *
+ * When a vm is present (instance creation), we need to do a
+ * 3-way merge for assets: constructor assets, instance assets,
+ * and instance scope assets.
  */
 
 strats.directives =
 strats.filters =
 strats.partials =
 strats.effects =
-strats.components = 
+strats.components = function (parentVal, childVal, key, vm) {
+  var ret = Object.create(vm.$parent
+    ? vm.$parent.$options[key]
+    : null)
+  mixin(ret, parentVal) 
+  mixin(ret, childVal)
+  return ret
+}
+
+/**
+ * Methods and computed properties
+ */
+
 strats.methods =
 strats.computed = function (parentVal, childVal) {
   var ret = Object.create(parentVal || null)
-  for (var key in childVal) {
-    ret[key] = childVal[key]
-  }
+  mixin(ret, childVal)
   return ret
 }
 
 /**
- * Default strategy - overwrite if child value is not undefined.
+ * Default strategy
  */
 
 var defaultStrat = function (parentVal, childVal) {
@@ -66,10 +85,11 @@ var defaultStrat = function (parentVal, childVal) {
  *
  * @param {Object} parent
  * @param {Object} child
- * @param {Boolean} inheriting
+ * @param {Vue} [vm] - if vm is present, indicates this is
+ *                     an instantiation merge.
  */
 
-exports.mergeOptions = function (parent, child, inheriting) {
+_.mergeOptions = function (parent, child, vm) {
   var options = {}
   var key
   for (key in parent) {
@@ -81,7 +101,7 @@ exports.mergeOptions = function (parent, child, inheriting) {
     }
   }
   function merge (key) {
-    if (inheriting && (key === 'el' || key === 'data')) {
+    if (!vm && (key === 'el' || key === 'data' || key === 'parent')) {
       _.warn(
         'The "' + key + '" option can only be used as an instantiation ' +
         'option and will be ignored in Vue.extend().'
@@ -89,7 +109,7 @@ exports.mergeOptions = function (parent, child, inheriting) {
       return
     }
     var strat = strats[key] || defaultStrat
-    options[key] = strat(parent[key], child[key])
+    options[key] = strat(parent[key], child[key], key, vm)
   }
   return options
 }
@@ -112,7 +132,7 @@ function enableDebug () {
    * @param {String} msg
    */
 
-  exports.log = function (msg) {
+  _.log = function (msg) {
     if (hasConsole && config.debug) {
       console.log(msg)
     }
@@ -124,7 +144,7 @@ function enableDebug () {
    * @param {String} msg
    */
 
-  exports.warn = function (msg) {
+  _.warn = function (msg) {
     if (hasConsole && !config.silent) {
       console.warn(msg)
       if (config.debug && console.trace) {

+ 1 - 3
src/util/lang.js

@@ -20,9 +20,7 @@ exports.toArray = function (list, i) {
 
 exports.mixin = function (to, from) {
   for (var key in from) {
-    if (to[key] !== from[key]) {
-      to[key] = from[key]
-    }
+    to[key] = from[key]
   }
 }