2017-02-21 05:58:24 +08:00
|
|
|
import Vue from 'vue'
|
2017-07-10 21:12:43 +08:00
|
|
|
import { Observer } from 'core/observer/index'
|
2022-07-16 21:33:48 +08:00
|
|
|
import { isNative, isObject, hasOwn, nextTick } from 'core/util/index'
|
2017-10-12 22:57:02 +08:00
|
|
|
import testObjectOption from '../../../helpers/test-object-option'
|
2017-02-21 05:58:24 +08:00
|
|
|
|
|
|
|
describe('Options provide/inject', () => {
|
2017-10-12 22:57:02 +08:00
|
|
|
testObjectOption('inject')
|
|
|
|
|
2017-02-21 05:58:24 +08:00
|
|
|
let injected
|
|
|
|
const injectedComp = {
|
|
|
|
inject: ['foo', 'bar'],
|
|
|
|
render() {},
|
|
|
|
created() {
|
|
|
|
injected = [this.foo, this.bar]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
injected = null
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should work', () => {
|
|
|
|
new Vue({
|
|
|
|
template: `<child/>`,
|
|
|
|
provide: {
|
|
|
|
foo: 1,
|
2017-03-02 00:01:24 +08:00
|
|
|
bar: false
|
2017-02-21 05:58:24 +08:00
|
|
|
},
|
|
|
|
components: {
|
|
|
|
child: {
|
|
|
|
template: `<injected-comp/>`,
|
|
|
|
components: {
|
|
|
|
injectedComp
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
2017-03-02 00:01:24 +08:00
|
|
|
expect(injected).toEqual([1, false])
|
2017-02-21 05:58:24 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
it('should use closest parent', () => {
|
|
|
|
new Vue({
|
|
|
|
template: `<child/>`,
|
|
|
|
provide: {
|
|
|
|
foo: 1,
|
2017-03-02 00:01:24 +08:00
|
|
|
bar: null
|
2017-02-21 05:58:24 +08:00
|
|
|
},
|
|
|
|
components: {
|
|
|
|
child: {
|
|
|
|
provide: {
|
|
|
|
foo: 3
|
|
|
|
},
|
|
|
|
template: `<injected-comp/>`,
|
|
|
|
components: {
|
|
|
|
injectedComp
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
2017-03-02 00:01:24 +08:00
|
|
|
expect(injected).toEqual([3, null])
|
2017-02-21 05:58:24 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
it('provide function', () => {
|
|
|
|
new Vue({
|
|
|
|
template: `<child/>`,
|
|
|
|
data: {
|
|
|
|
a: 1,
|
2017-03-02 00:01:24 +08:00
|
|
|
b: false
|
2017-02-21 05:58:24 +08:00
|
|
|
},
|
|
|
|
provide() {
|
|
|
|
return {
|
|
|
|
foo: this.a,
|
|
|
|
bar: this.b
|
|
|
|
}
|
|
|
|
},
|
|
|
|
components: {
|
|
|
|
child: {
|
|
|
|
template: `<injected-comp/>`,
|
|
|
|
components: {
|
|
|
|
injectedComp
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
2017-03-02 00:01:24 +08:00
|
|
|
expect(injected).toEqual([1, false])
|
2017-02-21 05:58:24 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
it('inject with alias', () => {
|
|
|
|
const injectAlias = {
|
|
|
|
inject: {
|
|
|
|
baz: 'foo',
|
|
|
|
qux: 'bar'
|
|
|
|
},
|
|
|
|
render() {},
|
|
|
|
created() {
|
|
|
|
injected = [this.baz, this.qux]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
new Vue({
|
|
|
|
template: `<child/>`,
|
|
|
|
provide: {
|
2017-03-02 00:01:24 +08:00
|
|
|
foo: false,
|
2017-02-21 05:58:24 +08:00
|
|
|
bar: 2
|
|
|
|
},
|
|
|
|
components: {
|
|
|
|
child: {
|
|
|
|
template: `<inject-alias/>`,
|
|
|
|
components: {
|
|
|
|
injectAlias
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
2017-03-02 00:01:24 +08:00
|
|
|
expect(injected).toEqual([false, 2])
|
2017-02-21 05:58:24 +08:00
|
|
|
})
|
|
|
|
|
2017-03-03 11:49:10 +08:00
|
|
|
it('inject before resolving data/props', () => {
|
2017-02-21 05:58:24 +08:00
|
|
|
const vm = new Vue({
|
|
|
|
provide: {
|
|
|
|
foo: 1
|
2017-03-03 11:49:10 +08:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
const child = new Vue({
|
|
|
|
parent: vm,
|
|
|
|
inject: ['foo'],
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
bar: this.foo + 1
|
|
|
|
}
|
2017-02-21 05:58:24 +08:00
|
|
|
},
|
2017-03-03 11:49:10 +08:00
|
|
|
props: {
|
|
|
|
baz: {
|
|
|
|
default() {
|
|
|
|
return this.foo + 2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-02-21 05:58:24 +08:00
|
|
|
})
|
|
|
|
|
2017-03-03 11:49:10 +08:00
|
|
|
expect(child.foo).toBe(1)
|
|
|
|
expect(child.bar).toBe(2)
|
|
|
|
expect(child.baz).toBe(3)
|
2017-02-21 05:58:24 +08:00
|
|
|
})
|
2017-02-26 06:13:41 +08:00
|
|
|
|
2017-09-07 19:33:09 +08:00
|
|
|
// GitHub issue #5194
|
2017-04-05 14:36:15 +08:00
|
|
|
it('should work with functional', () => {
|
|
|
|
new Vue({
|
|
|
|
template: `<child/>`,
|
|
|
|
provide: {
|
|
|
|
foo: 1,
|
|
|
|
bar: false
|
|
|
|
},
|
|
|
|
components: {
|
|
|
|
child: {
|
|
|
|
functional: true,
|
|
|
|
inject: ['foo', 'bar'],
|
|
|
|
render(h, context) {
|
|
|
|
const { injections } = context
|
|
|
|
injected = [injections.foo, injections.bar]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
|
|
|
expect(injected).toEqual([1, false])
|
|
|
|
})
|
|
|
|
|
2017-02-26 06:13:41 +08:00
|
|
|
if (typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys)) {
|
|
|
|
it('with Symbol keys', () => {
|
|
|
|
const s = Symbol()
|
|
|
|
const vm = new Vue({
|
|
|
|
template: `<child/>`,
|
|
|
|
provide: {
|
|
|
|
[s]: 123
|
|
|
|
},
|
|
|
|
components: {
|
|
|
|
child: {
|
|
|
|
inject: { s },
|
|
|
|
template: `<div>{{ s }}</div>`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
expect(vm.$el.textContent).toBe('123')
|
|
|
|
})
|
2018-12-22 01:49:21 +08:00
|
|
|
|
|
|
|
it('should merge symbol provide from mixins (functions)', () => {
|
|
|
|
const keyA = Symbol('foo')
|
|
|
|
const keyB = Symbol('bar')
|
|
|
|
|
|
|
|
const mixinA = { provide: () => ({ [keyA]: 'foo' }) }
|
|
|
|
const mixinB = { provide: () => ({ [keyB]: 'bar' }) }
|
|
|
|
const child = {
|
|
|
|
inject: {
|
|
|
|
foo: keyA,
|
|
|
|
bar: keyB
|
|
|
|
},
|
|
|
|
template: `<span/>`,
|
|
|
|
created() {
|
|
|
|
injected = [this.foo, this.bar]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
new Vue({
|
|
|
|
mixins: [mixinA, mixinB],
|
|
|
|
render(h) {
|
|
|
|
return h(child)
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
|
|
|
expect(injected).toEqual(['foo', 'bar'])
|
|
|
|
})
|
2017-02-26 06:13:41 +08:00
|
|
|
}
|
2017-03-21 15:22:32 +08:00
|
|
|
|
2017-09-07 19:33:09 +08:00
|
|
|
// GitHub issue #5223
|
2017-03-21 15:22:32 +08:00
|
|
|
it('should work with reactive array', done => {
|
|
|
|
const vm = new Vue({
|
|
|
|
template: `<div><child></child></div>`,
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
foo: []
|
|
|
|
}
|
|
|
|
},
|
|
|
|
provide() {
|
|
|
|
return {
|
|
|
|
foo: this.foo
|
|
|
|
}
|
|
|
|
},
|
|
|
|
components: {
|
|
|
|
child: {
|
|
|
|
inject: ['foo'],
|
|
|
|
template: `<span>{{foo.length}}</span>`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
|
|
|
expect(vm.$el.innerHTML).toEqual(`<span>0</span>`)
|
|
|
|
vm.foo.push(vm.foo.length)
|
|
|
|
vm.$nextTick(() => {
|
|
|
|
expect(vm.$el.innerHTML).toEqual(`<span>1</span>`)
|
|
|
|
vm.foo.pop()
|
|
|
|
vm.$nextTick(() => {
|
|
|
|
expect(vm.$el.innerHTML).toEqual(`<span>0</span>`)
|
|
|
|
done()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2017-06-15 22:15:36 +08:00
|
|
|
it('should extend properly', () => {
|
|
|
|
const parent = Vue.extend({
|
|
|
|
template: `<span/>`,
|
|
|
|
inject: ['foo']
|
|
|
|
})
|
|
|
|
|
|
|
|
const child = parent.extend({
|
|
|
|
template: `<span/>`,
|
|
|
|
inject: ['bar'],
|
|
|
|
created() {
|
|
|
|
injected = [this.foo, this.bar]
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
new Vue({
|
|
|
|
template: `<div><parent/><child/></div>`,
|
|
|
|
provide: {
|
|
|
|
foo: 1,
|
|
|
|
bar: false
|
|
|
|
},
|
|
|
|
components: {
|
|
|
|
parent,
|
|
|
|
child
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
|
|
|
expect(injected).toEqual([1, false])
|
|
|
|
})
|
|
|
|
|
2017-07-20 06:07:33 +08:00
|
|
|
it('should merge from mixins properly (objects)', () => {
|
|
|
|
const mixinA = { inject: { foo: 'foo' } }
|
|
|
|
const mixinB = { inject: { bar: 'bar' } }
|
|
|
|
const child = {
|
|
|
|
mixins: [mixinA, mixinB],
|
|
|
|
template: `<span/>`,
|
|
|
|
created() {
|
|
|
|
injected = [this.foo, this.bar]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
new Vue({
|
|
|
|
provide: { foo: 'foo', bar: 'bar', baz: 'baz' },
|
|
|
|
render(h) {
|
|
|
|
return h(child)
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
|
|
|
expect(injected).toEqual(['foo', 'bar'])
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should merge from mixins properly (arrays)', () => {
|
|
|
|
const mixinA = { inject: ['foo'] }
|
|
|
|
const mixinB = { inject: ['bar'] }
|
|
|
|
const child = {
|
|
|
|
mixins: [mixinA, mixinB],
|
|
|
|
inject: ['baz'],
|
|
|
|
template: `<span/>`,
|
|
|
|
created() {
|
|
|
|
injected = [this.foo, this.bar, this.baz]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
new Vue({
|
|
|
|
provide: { foo: 'foo', bar: 'bar', baz: 'baz' },
|
|
|
|
render(h) {
|
|
|
|
return h(child)
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
|
|
|
expect(injected).toEqual(['foo', 'bar', 'baz'])
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should merge from mixins properly (mix of objects and arrays)', () => {
|
|
|
|
const mixinA = { inject: { foo: 'foo' } }
|
|
|
|
const mixinB = { inject: ['bar'] }
|
|
|
|
const child = {
|
|
|
|
mixins: [mixinA, mixinB],
|
|
|
|
inject: { qux: 'baz' },
|
|
|
|
template: `<span/>`,
|
|
|
|
created() {
|
|
|
|
injected = [this.foo, this.bar, this.qux]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
new Vue({
|
|
|
|
provide: { foo: 'foo', bar: 'bar', baz: 'baz' },
|
|
|
|
render(h) {
|
|
|
|
return h(child)
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
|
|
|
expect(injected).toEqual(['foo', 'bar', 'baz'])
|
|
|
|
})
|
|
|
|
|
2017-03-21 15:22:32 +08:00
|
|
|
it('should warn when injections has been modified', () => {
|
|
|
|
const key = 'foo'
|
|
|
|
const vm = new Vue({
|
|
|
|
provide: {
|
|
|
|
foo: 1
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
const child = new Vue({
|
|
|
|
parent: vm,
|
|
|
|
inject: ['foo']
|
|
|
|
})
|
|
|
|
|
|
|
|
expect(child.foo).toBe(1)
|
|
|
|
child.foo = 2
|
|
|
|
expect(
|
2017-03-21 20:26:22 +08:00
|
|
|
`Avoid mutating an injected value directly since the changes will be ` +
|
2017-03-21 15:22:32 +08:00
|
|
|
`overwritten whenever the provided component re-renders. ` +
|
2017-03-21 20:26:22 +08:00
|
|
|
`injection being mutated: "${key}"`
|
|
|
|
).toHaveBeenWarned()
|
2017-03-21 15:22:32 +08:00
|
|
|
})
|
2017-05-29 13:49:49 +08:00
|
|
|
|
|
|
|
it('should warn when injections cannot be found', () => {
|
|
|
|
const vm = new Vue({})
|
|
|
|
new Vue({
|
|
|
|
parent: vm,
|
|
|
|
inject: ['foo', 'bar'],
|
|
|
|
created() {}
|
|
|
|
})
|
|
|
|
expect(`Injection "foo" not found`).toHaveBeenWarned()
|
|
|
|
expect(`Injection "bar" not found`).toHaveBeenWarned()
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should not warn when injections can be found', () => {
|
|
|
|
const vm = new Vue({
|
|
|
|
provide: {
|
|
|
|
foo: 1,
|
|
|
|
bar: false,
|
|
|
|
baz: undefined
|
|
|
|
}
|
|
|
|
})
|
|
|
|
new Vue({
|
|
|
|
parent: vm,
|
|
|
|
inject: ['foo', 'bar', 'baz'],
|
|
|
|
created() {}
|
|
|
|
})
|
|
|
|
expect(`Injection "foo" not found`).not.toHaveBeenWarned()
|
|
|
|
expect(`Injection "bar" not found`).not.toHaveBeenWarned()
|
|
|
|
expect(`Injection "baz" not found`).not.toHaveBeenWarned()
|
|
|
|
})
|
2017-07-07 11:39:25 +08:00
|
|
|
|
2017-09-13 13:05:11 +08:00
|
|
|
it('should not warn when injection key which is not provided is not enumerable', () => {
|
|
|
|
const parent = new Vue({ provide: { foo: 1 } })
|
|
|
|
const inject = { foo: 'foo' }
|
|
|
|
Object.defineProperty(inject, '__ob__', {
|
|
|
|
enumerable: false,
|
|
|
|
value: '__ob__'
|
|
|
|
})
|
|
|
|
new Vue({ parent, inject })
|
|
|
|
expect(`Injection "__ob__" not found`).not.toHaveBeenWarned()
|
|
|
|
})
|
|
|
|
|
2017-10-06 03:44:32 +08:00
|
|
|
// Github issue #6097
|
|
|
|
it('should not warn when injections cannot be found but have default value', () => {
|
|
|
|
const vm = new Vue({})
|
|
|
|
new Vue({
|
|
|
|
parent: vm,
|
|
|
|
inject: {
|
|
|
|
foo: { default: 1 },
|
|
|
|
bar: { default: false },
|
|
|
|
baz: { default: undefined }
|
|
|
|
},
|
2017-10-06 03:56:36 +08:00
|
|
|
created() {
|
|
|
|
injected = [this.foo, this.bar, this.baz]
|
|
|
|
}
|
2017-10-06 03:44:32 +08:00
|
|
|
})
|
2017-10-06 03:56:36 +08:00
|
|
|
expect(injected).toEqual([1, false, undefined])
|
2017-10-06 03:44:32 +08:00
|
|
|
})
|
|
|
|
|
2017-10-07 04:54:35 +08:00
|
|
|
it('should support name alias and default together', () => {
|
|
|
|
const vm = new Vue({
|
|
|
|
provide: {
|
|
|
|
FOO: 2
|
|
|
|
}
|
|
|
|
})
|
|
|
|
new Vue({
|
|
|
|
parent: vm,
|
|
|
|
inject: {
|
|
|
|
foo: { from: 'FOO', default: 1 },
|
|
|
|
bar: { default: false },
|
|
|
|
baz: { default: undefined }
|
|
|
|
},
|
|
|
|
created() {
|
|
|
|
injected = [this.foo, this.bar, this.baz]
|
|
|
|
}
|
|
|
|
})
|
|
|
|
expect(injected).toEqual([2, false, undefined])
|
|
|
|
})
|
|
|
|
|
2017-10-06 03:44:32 +08:00
|
|
|
it('should use provided value even if inject has default', () => {
|
|
|
|
const vm = new Vue({
|
|
|
|
provide: {
|
|
|
|
foo: 1,
|
|
|
|
bar: false,
|
|
|
|
baz: undefined
|
|
|
|
}
|
|
|
|
})
|
|
|
|
new Vue({
|
|
|
|
parent: vm,
|
|
|
|
inject: {
|
|
|
|
foo: { default: 2 },
|
|
|
|
bar: { default: 2 },
|
|
|
|
baz: { default: 2 }
|
|
|
|
},
|
|
|
|
created() {
|
|
|
|
injected = [this.foo, this.bar, this.baz]
|
|
|
|
}
|
|
|
|
})
|
|
|
|
expect(injected).toEqual([1, false, undefined])
|
|
|
|
})
|
|
|
|
|
2017-09-13 13:05:11 +08:00
|
|
|
// Github issue #6008
|
2017-07-07 11:39:25 +08:00
|
|
|
it('should merge provide from mixins (objects)', () => {
|
|
|
|
const mixinA = { provide: { foo: 'foo' } }
|
|
|
|
const mixinB = { provide: { bar: 'bar' } }
|
|
|
|
const child = {
|
|
|
|
inject: ['foo', 'bar'],
|
|
|
|
template: `<span/>`,
|
|
|
|
created() {
|
|
|
|
injected = [this.foo, this.bar]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
new Vue({
|
|
|
|
mixins: [mixinA, mixinB],
|
|
|
|
render(h) {
|
|
|
|
return h(child)
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
|
|
|
expect(injected).toEqual(['foo', 'bar'])
|
|
|
|
})
|
2017-07-21 09:47:52 +08:00
|
|
|
|
2017-07-07 11:39:25 +08:00
|
|
|
it('should merge provide from mixins (functions)', () => {
|
|
|
|
const mixinA = { provide: () => ({ foo: 'foo' }) }
|
|
|
|
const mixinB = { provide: () => ({ bar: 'bar' }) }
|
|
|
|
const child = {
|
|
|
|
inject: ['foo', 'bar'],
|
|
|
|
template: `<span/>`,
|
|
|
|
created() {
|
|
|
|
injected = [this.foo, this.bar]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
new Vue({
|
|
|
|
mixins: [mixinA, mixinB],
|
|
|
|
render(h) {
|
|
|
|
return h(child)
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
|
|
|
expect(injected).toEqual(['foo', 'bar'])
|
|
|
|
})
|
2017-07-21 09:47:52 +08:00
|
|
|
|
2017-07-07 11:39:25 +08:00
|
|
|
it('should merge provide from mixins (mix of objects and functions)', () => {
|
|
|
|
const mixinA = { provide: { foo: 'foo' } }
|
|
|
|
const mixinB = { provide: () => ({ bar: 'bar' }) }
|
|
|
|
const mixinC = { provide: { baz: 'baz' } }
|
|
|
|
const mixinD = { provide: () => ({ bam: 'bam' }) }
|
|
|
|
const child = {
|
|
|
|
inject: ['foo', 'bar', 'baz', 'bam'],
|
|
|
|
template: `<span/>`,
|
|
|
|
created() {
|
|
|
|
injected = [this.foo, this.bar, this.baz, this.bam]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
new Vue({
|
|
|
|
mixins: [mixinA, mixinB, mixinC, mixinD],
|
|
|
|
render(h) {
|
|
|
|
return h(child)
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
|
|
|
expect(injected).toEqual(['foo', 'bar', 'baz', 'bam'])
|
|
|
|
})
|
2017-07-21 09:47:52 +08:00
|
|
|
|
2017-07-07 11:39:25 +08:00
|
|
|
it('should merge provide from mixins and override existing keys', () => {
|
|
|
|
const mixinA = { provide: { foo: 'foo' } }
|
|
|
|
const mixinB = { provide: { foo: 'bar' } }
|
|
|
|
const child = {
|
|
|
|
inject: ['foo'],
|
|
|
|
template: `<span/>`,
|
|
|
|
created() {
|
|
|
|
injected = [this.foo]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
new Vue({
|
|
|
|
mixins: [mixinA, mixinB],
|
|
|
|
render(h) {
|
|
|
|
return h(child)
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
|
|
|
expect(injected).toEqual(['bar'])
|
|
|
|
})
|
2017-07-21 09:47:52 +08:00
|
|
|
|
2017-07-07 11:39:25 +08:00
|
|
|
it('should merge provide when Vue.extend', () => {
|
|
|
|
const mixinA = { provide: () => ({ foo: 'foo' }) }
|
|
|
|
const child = {
|
|
|
|
inject: ['foo', 'bar'],
|
|
|
|
template: `<span/>`,
|
|
|
|
created() {
|
|
|
|
injected = [this.foo, this.bar]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const Ctor = Vue.extend({
|
|
|
|
mixins: [mixinA],
|
|
|
|
provide: { bar: 'bar' },
|
|
|
|
render(h) {
|
|
|
|
return h(child)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
new Ctor().$mount()
|
|
|
|
|
|
|
|
expect(injected).toEqual(['foo', 'bar'])
|
|
|
|
})
|
2017-07-10 21:12:43 +08:00
|
|
|
|
|
|
|
// #5913
|
|
|
|
it('should keep the reactive with provide', () => {
|
|
|
|
function isObserver(obj) {
|
|
|
|
if (isObject(obj)) {
|
|
|
|
return hasOwn(obj, '__ob__') && obj.__ob__ instanceof Observer
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
const vm = new Vue({
|
|
|
|
template: `<div><child ref='child'></child></div>`,
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
foo: {},
|
|
|
|
$foo: {},
|
|
|
|
foo1: []
|
|
|
|
}
|
|
|
|
},
|
|
|
|
provide() {
|
|
|
|
return {
|
|
|
|
foo: this.foo,
|
|
|
|
$foo: this.$foo,
|
|
|
|
foo1: this.foo1,
|
|
|
|
bar: {},
|
|
|
|
baz: []
|
|
|
|
}
|
|
|
|
},
|
|
|
|
components: {
|
|
|
|
child: {
|
|
|
|
inject: ['foo', '$foo', 'foo1', 'bar', 'baz'],
|
|
|
|
template: `<span/>`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
const child = vm.$refs.child
|
|
|
|
expect(isObserver(child.foo)).toBe(true)
|
|
|
|
expect(isObserver(child.$foo)).toBe(false)
|
|
|
|
expect(isObserver(child.foo1)).toBe(true)
|
|
|
|
expect(isObserver(child.bar)).toBe(false)
|
|
|
|
expect(isObserver(child.baz)).toBe(false)
|
|
|
|
})
|
2017-07-21 09:47:52 +08:00
|
|
|
|
|
|
|
// #6175
|
|
|
|
it('merge provide properly from mixins', () => {
|
|
|
|
const ProvideFooMixin = {
|
|
|
|
provide: {
|
|
|
|
foo: 'foo injected'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const ProvideBarMixin = {
|
|
|
|
provide: {
|
|
|
|
bar: 'bar injected'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const Child = {
|
|
|
|
inject: ['foo', 'bar'],
|
|
|
|
render(h) {
|
|
|
|
return h('div', [`foo: ${this.foo}, `, `bar: ${this.bar}`])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const Parent = {
|
|
|
|
mixins: [ProvideFooMixin, ProvideBarMixin],
|
|
|
|
render(h) {
|
|
|
|
return h(Child)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const vm = new Vue({
|
|
|
|
render(h) {
|
|
|
|
return h(Parent)
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
|
|
|
expect(vm.$el.textContent).toBe(`foo: foo injected, bar: bar injected`)
|
|
|
|
})
|
2017-09-06 04:01:50 +08:00
|
|
|
|
|
|
|
it('merge provide with object syntax when using Vue.extend', () => {
|
|
|
|
const child = {
|
|
|
|
inject: ['foo'],
|
|
|
|
template: `<span/>`,
|
|
|
|
created() {
|
|
|
|
injected = this.foo
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const Ctor = Vue.extend({
|
|
|
|
provide: { foo: 'foo' },
|
|
|
|
render(h) {
|
|
|
|
return h(child)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
new Ctor().$mount()
|
|
|
|
|
|
|
|
expect(injected).toEqual('foo')
|
|
|
|
})
|
2018-03-09 00:15:35 +08:00
|
|
|
|
|
|
|
// #7284
|
|
|
|
it('should not inject prototype properties', () => {
|
|
|
|
const vm = new Vue({
|
|
|
|
provide: {}
|
|
|
|
})
|
|
|
|
new Vue({
|
|
|
|
parent: vm,
|
|
|
|
inject: ['constructor']
|
|
|
|
})
|
|
|
|
expect(`Injection "constructor" not found`).toHaveBeenWarned()
|
|
|
|
})
|
2022-07-16 21:33:48 +08:00
|
|
|
|
|
|
|
// #12667
|
|
|
|
test('provide with getters', async () => {
|
|
|
|
const spy = vi.fn()
|
|
|
|
const Child = {
|
|
|
|
render() {},
|
|
|
|
inject: ['foo'],
|
|
|
|
mounted() {
|
|
|
|
spy(this.foo)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let val = 1
|
|
|
|
const vm = new Vue({
|
|
|
|
components: { Child },
|
|
|
|
template: `<Child v-if="ok" />`,
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
ok: false
|
|
|
|
}
|
|
|
|
},
|
|
|
|
provide() {
|
|
|
|
return {
|
|
|
|
get foo() {
|
|
|
|
return val
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).$mount()
|
|
|
|
|
|
|
|
val = 2
|
|
|
|
vm.ok = true
|
|
|
|
await nextTick()
|
|
|
|
expect(spy).toHaveBeenCalledWith(2)
|
|
|
|
})
|
2022-11-09 20:04:25 +08:00
|
|
|
|
|
|
|
// #12854
|
|
|
|
test('should not mutate original provide options', () => {
|
|
|
|
const hairMixin = { provide: { hair: 'red' } }
|
|
|
|
const eyesMixin = { provide: { eyes: 'brown' } }
|
|
|
|
new Vue({ mixins: [hairMixin, eyesMixin], render() {} }).$mount()
|
|
|
|
expect(eyesMixin.provide).toStrictEqual({ eyes: 'brown' })
|
|
|
|
})
|
2017-02-21 05:58:24 +08:00
|
|
|
})
|