import Vue from 'vue'
describe('Component scoped slot', () => {
it('default slot', done => {
const vm = new Vue({
template: `
{{ props.msg }}
`,
components: {
test: {
data () {
return { msg: 'hello' }
},
template: `
`
}
}
}).$mount()
expect(vm.$el.innerHTML).toBe('hello')
vm.$refs.test.msg = 'world'
waitForUpdate(() => {
expect(vm.$el.innerHTML).toBe('world')
}).then(done)
})
it('with v-bind', done => {
const vm = new Vue({
template: `
{{ props.msg }} {{ props.msg2 }}
`,
components: {
test: {
data () {
return {
msg: 'hello',
obj: { msg2: 'world' }
}
},
template: `
`
}
}
}).$mount()
expect(vm.$el.innerHTML).toBe('hello world')
vm.$refs.test.msg = 'bye'
vm.$refs.test.obj.msg2 = 'bye'
waitForUpdate(() => {
expect(vm.$el.innerHTML).toBe('bye bye')
}).then(done)
})
it('template slot', done => {
const vm = new Vue({
template: `
{{ props.foo }}{{ props.bar }}
`,
components: {
test: {
data () {
return { foo: 'FOO', bar: 'BAR' }
},
template: `
`
}
}
}).$mount()
expect(vm.$el.innerHTML).toBe('FOOBAR')
vm.$refs.test.foo = 'BAZ'
waitForUpdate(() => {
expect(vm.$el.innerHTML).toBe('BAZBAR')
}).then(done)
})
it('fallback content', () => {
const vm = new Vue({
template: ``,
components: {
test: {
data () {
return { msg: 'hello' }
},
template: `
{{ msg }} fallback
`
}
}
}).$mount()
expect(vm.$el.innerHTML).toBe('hello fallback')
})
it('slot with v-for', done => {
const vm = new Vue({
template: `
{{ props.text }}
`,
components: {
test: {
data () {
return {
items: ['foo', 'bar', 'baz']
}
},
template: `
`
}
}
}).$mount()
function assertOutput () {
expect(vm.$el.innerHTML).toBe(vm.$refs.test.items.map(item => {
return `${item}`
}).join(''))
}
assertOutput()
vm.$refs.test.items.reverse()
waitForUpdate(assertOutput).then(() => {
vm.$refs.test.items.push('qux')
}).then(assertOutput).then(done)
})
it('slot inside v-for', done => {
const vm = new Vue({
template: `
{{ props.text }}
`,
components: {
test: {
data () {
return {
items: ['foo', 'bar', 'baz']
}
},
template: `
`
}
}
}).$mount()
function assertOutput () {
expect(vm.$el.innerHTML).toBe(vm.$refs.test.items.map(item => {
return `${item}`
}).join(''))
}
assertOutput()
vm.$refs.test.items.reverse()
waitForUpdate(assertOutput).then(() => {
vm.$refs.test.items.push('qux')
}).then(assertOutput).then(done)
})
it('scoped slot without scope alias', () => {
const vm = new Vue({
template: `
I am static
`,
components: {
test: {
data () {
return { msg: 'hello' }
},
template: `
`
}
}
}).$mount()
expect(vm.$el.innerHTML).toBe('I am static')
})
it('non-scoped slot with scope alias', () => {
const vm = new Vue({
template: `
{{ props.text || 'meh' }}
`,
components: {
test: {
data () {
return { msg: 'hello' }
},
template: `
`
}
}
}).$mount()
expect(vm.$el.innerHTML).toBe('meh')
})
it('warn key on slot', () => {
new Vue({
template: `
{{ props.text }}
`,
components: {
test: {
data () {
return {
items: ['foo', 'bar', 'baz']
}
},
template: `
`
}
}
}).$mount()
expect(`\`key\` does not work on `).toHaveBeenWarned()
})
it('render function usage (named, via data)', done => {
const vm = new Vue({
render (h) {
return h('test', {
ref: 'test',
scopedSlots: {
item: props => h('span', props.text)
}
})
},
components: {
test: {
data () {
return { msg: 'hello' }
},
render (h) {
return h('div', [
this.$scopedSlots.item({
text: this.msg
})
])
}
}
}
}).$mount()
expect(vm.$el.innerHTML).toBe('hello')
vm.$refs.test.msg = 'world'
waitForUpdate(() => {
expect(vm.$el.innerHTML).toBe('world')
}).then(done)
})
it('render function usage (default, as children)', () => {
const vm = new Vue({
render (h) {
return h('test', [
props => h('span', [props.msg])
])
},
components: {
test: {
data () {
return { msg: 'hello' }
},
render (h) {
return h('div', [
this.$scopedSlots.default({ msg: this.msg })
])
}
}
}
}).$mount()
expect(vm.$el.innerHTML).toBe('hello')
})
// #4779
it('should support dynamic slot target', done => {
const Child = {
template: `
`
}
const vm = new Vue({
data: {
a: 'a',
b: 'b'
},
template: `
A {{ props.msg }}
B {{ props.msg }}
`,
components: { Child }
}).$mount()
expect(vm.$el.textContent.trim()).toBe('A a B b')
// switch slots
vm.a = 'b'
vm.b = 'a'
waitForUpdate(() => {
expect(vm.$el.textContent.trim()).toBe('B a A b')
}).then(done)
})
it('render function usage (JSX)', () => {
const vm = new Vue({
render (h) {
return {
props => {props.msg}
}
},
components: {
test: {
data () {
return { msg: 'hello' }
},
render (h) {
return
{this.$scopedSlots.default({ msg: this.msg })}
}
}
}
}).$mount()
expect(vm.$el.innerHTML).toBe('hello')
})
})