remove inherit option

This commit is contained in:
Evan You 2015-09-02 12:17:39 -04:00
parent 1169252c07
commit 8cc6c72cd6
11 changed files with 20 additions and 198 deletions

View File

@ -1,9 +1,7 @@
var _ = require('../util') var _ = require('../util')
/** /**
* Create a child instance that prototypally inherits * Create a child instance.
* data on parent. To achieve that we create an intermediate
* constructor with its prototype pointing to parent.
* *
* @param {Object} opts * @param {Object} opts
* @param {Function} [BaseCtor] * @param {Function} [BaseCtor]
@ -12,36 +10,9 @@ var _ = require('../util')
*/ */
exports.$addChild = function (opts, BaseCtor) { exports.$addChild = function (opts, BaseCtor) {
BaseCtor = BaseCtor || _.Vue var ChildVue = BaseCtor || _.Vue
opts = opts || {}
var ChildVue
var parent = this var parent = this
// transclusion context opts = opts || {}
var context = opts._context || parent
var inherit = opts.inherit !== undefined
? opts.inherit
: BaseCtor.options.inherit
if (inherit) {
var ctors = context._childCtors
ChildVue = ctors[BaseCtor.cid]
if (!ChildVue) {
var optionName = BaseCtor.options.name
var className = optionName
? _.classify(optionName)
: 'VueComponent'
ChildVue = new Function(
'return function ' + className + ' (options) {' +
'this.constructor = ' + className + ';' +
'this._init(options) }'
)()
ChildVue.options = BaseCtor.options
ChildVue.linker = BaseCtor.linker
ChildVue.prototype = context
ctors[BaseCtor.cid] = ChildVue
}
} else {
ChildVue = BaseCtor
}
opts._parent = parent opts._parent = parent
opts._root = parent.$root opts._root = parent.$root
var child = new ChildVue(opts) var child = new ChildVue(opts)

View File

@ -23,7 +23,6 @@ exports._init = function (options) {
this.$$ = {} // element references this.$$ = {} // element references
this._watchers = [] // all watchers as an array this._watchers = [] // all watchers as an array
this._directives = [] // all directives this._directives = [] // all directives
this._childCtors = {} // inherit:true constructors
// a flag to avoid this being observed // a flag to avoid this being observed
this._isVue = true this._isVue = true
@ -59,11 +58,6 @@ exports._init = function (options) {
// and container directives. // and container directives.
this._scope = options._scope this._scope = options._scope
// set ref
if (options._ref) {
(this._scope || this._context).$[options._ref] = this
}
// fragment: // fragment:
// if this instance is compiled inside a Fragment, it // if this instance is compiled inside a Fragment, it
// needs to reigster itself as a child of that fragment // needs to reigster itself as a child of that fragment
@ -78,6 +72,11 @@ exports._init = function (options) {
this.$parent.$children.push(this) this.$parent.$children.push(this)
} }
// set ref
if (options._ref) {
(this._scope || this._context).$[options._ref] = this
}
// merge options. // merge options.
options = this.$options = mergeOptions( options = this.$options = mergeOptions(
this.constructor.options, this.constructor.options,

View File

@ -156,18 +156,9 @@ exports._unproxy = function (key) {
*/ */
exports._digest = function () { exports._digest = function () {
var i = this._watchers.length for (var i = 0, l = this._watchers.length; i < l; i++) {
while (i--) {
this._watchers[i].update(true) // shallow updates this._watchers[i].update(true) // shallow updates
} }
var children = this.$children
i = children.length
while (i--) {
var child = children[i]
if (child.$options.inherit) {
child._digest()
}
}
} }
/** /**
@ -220,8 +211,8 @@ function makeComputedGetter (getter, owner) {
/** /**
* Setup instance methods. Methods must be bound to the * Setup instance methods. Methods must be bound to the
* instance since they might be called by children * instance since they might be passed down as a prop to
* inheriting them. * child components.
*/ */
exports._initMethods = function () { exports._initMethods = function () {

View File

@ -52,8 +52,6 @@ exports.checkComponent = function (el, options) {
/** /**
* Set a prop's initial value on a vm and its data object. * Set a prop's initial value on a vm and its data object.
* The vm may have inherit:true so we need to make sure
* we don't accidentally overwrite parent value.
* *
* @param {Vue} vm * @param {Vue} vm
* @param {Object} prop * @param {Object} prop
@ -63,12 +61,7 @@ exports.checkComponent = function (el, options) {
exports.initProp = function (vm, prop, value) { exports.initProp = function (vm, prop, value) {
if (exports.assertProp(prop, value)) { if (exports.assertProp(prop, value)) {
var key = prop.path var key = prop.path
if (key in vm) { vm[key] = vm._data[key] = value
_.define(vm, key, value, true)
} else {
vm[key] = value
}
vm._data[key] = value
} }
} }

View File

@ -304,13 +304,6 @@ function guardArrayAssets (assets) {
*/ */
exports.mergeOptions = function merge (parent, child, vm) { exports.mergeOptions = function merge (parent, child, vm) {
if (process.env.NODE_ENV !== 'production') {
if (child.inherit && !child._repeat) {
_.deprecation.INHERIT()
}
}
guardComponents(child) guardComponents(child)
guardProps(child) guardProps(child)
var options = {} var options = {}

View File

@ -23,55 +23,4 @@ describe('Child API', function () {
expect(child.$root).toBe(vm) expect(child.$root).toBe(vm)
expect(vm.$children.indexOf(child)).toBe(0) expect(vm.$children.indexOf(child)).toBe(0)
}) })
it('inherit scope', function () {
var child = vm.$addChild({
inherit: true,
data: {
b: 2
}
})
expect(child.a).toBe(1)
expect(child.b).toBe(2)
expect(child.constructor.prototype).toBe(vm)
})
it('with constructor', function () {
var Ctor = Vue.extend({
inherit: true,
data: function () {
return {
c: 3
}
}
})
var child = vm.$addChild({
data: {
b: 2
}
}, Ctor)
expect(child.a).toBe(1)
expect(child.b).toBe(2)
expect(child.c).toBe(3)
expect(child.constructor.options).toBe(Ctor.options)
})
it('cache constructor', function () {
var Ctor = Vue.extend({
inherit: true
})
var child1 = vm.$addChild(null, Ctor)
var child2 = vm.$addChild(null, Ctor)
expect(child1.constructor).toBe(child2.constructor)
})
it('Use proper constructor name with inherit', function () {
var Ctor = Vue.extend({
name: 'vue-test',
inherit: true
})
var child = vm.$addChild(null, Ctor)
expect(child.constructor.toString().match(/^function VueTest\s?\(/)).toBeTruthy()
})
}) })

View File

@ -14,10 +14,10 @@ if (_.inBrowser) {
var vm = new Vue({ var vm = new Vue({
el: el, el: el,
data: { test: false, a: 'A' }, data: { test: false, a: 'A' },
template: '<div v-if="test"><test></test></div>', template: '<div v-if="test"><test prop-a="a"></test></div>',
components: { components: {
test: { test: {
inherit: true, props: ['a'],
template: '{{a}}' template: '{{a}}'
} }
} }

View File

@ -144,8 +144,7 @@ if (_.inBrowser) {
}) })
parent.$addChild({ parent.$addChild({
el: el, el: el,
inherit: true, template: '<a v-on="click:$parent.test($event)"></a>'
template: '<a v-on="click:test($event)"></a>'
}) })
var e = trigger(el.firstChild, 'click') var e = trigger(el.firstChild, 'click')
expect(test).toHaveBeenCalledWith(e) expect(test).toHaveBeenCalledWith(e)

View File

@ -91,7 +91,7 @@ if (_.inBrowser) {
}) })
it('$data as prop', function () { it('$data as prop', function () {
var vm = new Vue({ new Vue({
el: el, el: el,
template: '<test $data="{{ok}}"></test>', template: '<test $data="{{ok}}"></test>',
data: { data: {
@ -398,25 +398,6 @@ if (_.inBrowser) {
expect(el.textContent).toBe('AAA') expect(el.textContent).toBe('AAA')
}) })
it('should not overwrite inherit:true properties', function () {
var vm = new Vue({
el: el,
data: {
msg: 'hi!'
},
template: '<test msg="ho!"></test>',
components: {
test: {
props: ['msg'],
inherit: true,
template: '{{msg}}'
}
}
})
expect(vm.msg).toBe('hi!')
expect(el.textContent).toBe('ho!')
})
it('should not overwrite default value for an absent Boolean prop', function () { it('should not overwrite default value for an absent Boolean prop', function () {
var vm = new Vue({ var vm = new Vue({
el: el, el: el,

View File

@ -185,29 +185,6 @@ describe('Instance state initialization', function () {
}) })
}) })
it('inherit', function (done) {
var child = vm.$addChild({
inherit: true
})
expect(child.c).toBe('cd')
child.d = 'e f'
expect(vm.a).toBe('e')
expect(vm.b).toBe('f')
expect(vm.c).toBe('ef')
expect(vm.d).toBe('ef')
expect(vm.e).toBe('efe')
expect(child.a).toBe('e')
expect(child.b).toBe('f')
expect(child.c).toBe('ef')
expect(child.d).toBe('ef')
expect(vm.e).toBe('efe')
Vue.nextTick(function () {
expect(spyE).toHaveBeenCalledWith('efe', 'cde')
done()
})
})
it('cached computed', function () { it('cached computed', function () {
expect(spyF).not.toHaveBeenCalled() expect(spyF).not.toHaveBeenCalled()
var f = vm.f var f = vm.f
@ -273,11 +250,6 @@ describe('Instance state initialization', function () {
} }
}) })
expect(vm.test()).toBe(1) expect(vm.test()).toBe(1)
var child = vm.$addChild({
inherit: true
})
expect(child.test()).toBe(1)
}) })
}) })

View File

@ -128,25 +128,17 @@ describe('Watcher', function () {
var watcher2 = new Watcher(vm, 'b.e', spy) var watcher2 = new Watcher(vm, 'b.e', spy)
expect(watcher.value).toBeUndefined() expect(watcher.value).toBeUndefined()
expect(watcher2.value).toBeUndefined() expect(watcher2.value).toBeUndefined()
// check $add affecting children
var child = vm.$addChild({
inherit: true
})
var watcher3 = new Watcher(child, 'd.e', spy)
var watcher4 = new Watcher(child, 'b.e', spy)
// check $add should not affect isolated children // check $add should not affect isolated children
var child2 = vm.$addChild() var child2 = vm.$addChild()
var watcher5 = new Watcher(child2, 'd.e', spy) var watcher3 = new Watcher(child2, 'd.e', spy)
expect(watcher5.value).toBeUndefined() expect(watcher3.value).toBeUndefined()
vm.$set('d', { e: 123 }) vm.$set('d', { e: 123 })
vm.b.$set('e', 234) vm.b.$set('e', 234)
nextTick(function () { nextTick(function () {
expect(watcher.value).toBe(123) expect(watcher.value).toBe(123)
expect(watcher2.value).toBe(234) expect(watcher2.value).toBe(234)
expect(watcher3.value).toBe(123) expect(watcher3.value).toBeUndefined()
expect(watcher4.value).toBe(234) expect(spy.calls.count()).toBe(2)
expect(watcher5.value).toBeUndefined()
expect(spy.calls.count()).toBe(4)
expect(spy).toHaveBeenCalledWith(123, undefined) expect(spy).toHaveBeenCalledWith(123, undefined)
expect(spy).toHaveBeenCalledWith(234, undefined) expect(spy).toHaveBeenCalledWith(234, undefined)
done() done()
@ -211,24 +203,6 @@ describe('Watcher', function () {
}) })
}) })
it('watching parent scope properties', function (done) {
var child = vm.$addChild({
inherit: true
})
var spy2 = jasmine.createSpy('watch')
var watcher1 = new Watcher(child, '$data', spy)
var watcher2 = new Watcher(child, 'a', spy2)
vm.a = 123
nextTick(function () {
// $data should only be called on self data change
expect(watcher1.value).toBe(child.$data)
expect(spy).not.toHaveBeenCalled()
expect(watcher2.value).toBe(123)
expect(spy2).toHaveBeenCalledWith(123, 1)
done()
})
})
it('filters', function (done) { it('filters', function (done) {
vm.$options.filters.test = function (val, multi) { vm.$options.filters.test = function (val, multi) {
return val * multi return val * multi