1import Vue from 'vue'23describe('Component slot', () => {4 let vm, child5 function mount(options) {6 vm = new Vue({7 data: {8 msg: 'parent message'9 },10 template: `<div><test>${options.parentContent || ''}</test></div>`,11 components: {12 test: {13 template: options.childTemplate,14 data() {15 return {16 msg: 'child message'17 }18 }19 }20 }21 }).$mount()22 child = vm.$children[0]23 }2425 it('no content', () => {26 mount({27 childTemplate: '<div><slot></slot></div>'28 })29 expect(child.$el.childNodes.length).toBe(0)30 })3132 it('default slot', done => {33 mount({34 childTemplate: '<div><slot></slot></div>',35 parentContent: '<p>{{ msg }}</p>'36 })37 expect(child.$el.tagName).toBe('DIV')38 expect(child.$el.children[0].tagName).toBe('P')39 expect(child.$el.children[0].textContent).toBe('parent message')40 vm.msg = 'changed'41 waitForUpdate(() => {42 expect(child.$el.children[0].textContent).toBe('changed')43 }).then(done)44 })4546 it('named slot', done => {47 mount({48 childTemplate: '<div><slot name="test"></slot></div>',49 parentContent: '<p slot="test">{{ msg }}</p>'50 })51 expect(child.$el.tagName).toBe('DIV')52 expect(child.$el.children[0].tagName).toBe('P')53 expect(child.$el.children[0].textContent).toBe('parent message')54 vm.msg = 'changed'55 waitForUpdate(() => {56 expect(child.$el.children[0].textContent).toBe('changed')57 }).then(done)58 })5960 it('named slot with 0 as a number', done => {61 mount({62 childTemplate: '<div><slot :name="0"></slot></div>',63 parentContent: '<p :slot="0">{{ msg }}</p>'64 })65 expect(child.$el.tagName).toBe('DIV')66 expect(child.$el.children[0].tagName).toBe('P')67 expect(child.$el.children[0].textContent).toBe('parent message')68 vm.msg = 'changed'69 waitForUpdate(() => {70 expect(child.$el.children[0].textContent).toBe('changed')71 }).then(done)72 })7374 it('fallback content', () => {75 mount({76 childTemplate: '<div><slot><p>{{msg}}</p></slot></div>'77 })78 expect(child.$el.children[0].tagName).toBe('P')79 expect(child.$el.textContent).toBe('child message')80 })8182 it('fallback content with multiple named slots', () => {83 mount({84 childTemplate: `85 <div>86 <slot name="a"><p>fallback a</p></slot>87 <slot name="b">fallback b</slot>88 </div>89 `,90 parentContent: '<p slot="b">slot b</p>'91 })92 expect(child.$el.children.length).toBe(2)93 expect(child.$el.children[0].textContent).toBe('fallback a')94 expect(child.$el.children[1].textContent).toBe('slot b')95 })9697 it('fallback content with mixed named/unnamed slots', () => {98 mount({99 childTemplate: `100 <div>101 <slot><p>fallback a</p></slot>102 <slot name="b">fallback b</slot>103 </div>104 `,105 parentContent: '<p slot="b">slot b</p>'106 })107 expect(child.$el.children.length).toBe(2)108 expect(child.$el.children[0].textContent).toBe('fallback a')109 expect(child.$el.children[1].textContent).toBe('slot b')110 })111112 it('it should work with previous versions of the templates', () => {113 const Test = {114 render() {115 const _vm = this116 // const _h = _vm.$createElement;117 const _c = _vm._self._c || vm._h118 return _c(119 'div',120 [_vm._t('default', [_c('p', [_vm._v('slot default')])])],121 2122 )123 }124 }125 let vm = new Vue({126 template: `<test/>`,127 components: { Test }128 }).$mount()129 expect(vm.$el.textContent).toBe('slot default')130 vm = new Vue({131 template: `<test>custom content</test>`,132 components: { Test }133 }).$mount()134 expect(vm.$el.textContent).toBe('custom content')135 })136137 it('fallback content should not be evaluated when the parent is providing it', () => {138 const test = vi.fn()139 const vm = new Vue({140 template: '<test>slot default</test>',141 components: {142 test: {143 template: '<div><slot>{{test()}}</slot></div>',144 methods: {145 test() {146 test()147 return 'test'148 }149 }150 }151 }152 }).$mount()153 expect(vm.$el.textContent).toBe('slot default')154 expect(test).not.toHaveBeenCalled()155 })156157 it('selector matching multiple elements', () => {158 mount({159 childTemplate: '<div><slot name="t"></slot></div>',160 parentContent: '<p slot="t">1</p><div></div><p slot="t">2</p>'161 })162 expect(child.$el.innerHTML).toBe('<p>1</p><p>2</p>')163 })164165 it('default content should only render parts not selected', () => {166 mount({167 childTemplate: `168 <div>169 <slot name="a"></slot>170 <slot></slot>171 <slot name="b"></slot>172 </div>173 `,174 parentContent: '<div>foo</div><p slot="a">1</p><p slot="b">2</p>'175 })176 expect(child.$el.innerHTML).toBe('<p>1</p> <div>foo</div> <p>2</p>')177 })178179 it('name should only match children', function () {180 mount({181 childTemplate: `182 <div>183 <slot name="a"><p>fallback a</p></slot>184 <slot name="b"><p>fallback b</p></slot>185 <slot name="c"><p>fallback c</p></slot>186 </div>187 `,188 parentContent: `189 '<p slot="b">select b</p>190 '<span><p slot="b">nested b</p></span>191 '<span><p slot="c">nested c</p></span>192 `193 })194 expect(child.$el.children.length).toBe(3)195 expect(child.$el.children[0].textContent).toBe('fallback a')196 expect(child.$el.children[1].textContent).toBe('select b')197 expect(child.$el.children[2].textContent).toBe('fallback c')198 })199200 it('should accept expressions in slot attribute and slot names', () => {201 mount({202 childTemplate: `<div><slot :name="'a'"></slot></div>`,203 parentContent: `<p>one</p><p :slot="'a'">two</p>`204 })205 expect(child.$el.innerHTML).toBe('<p>two</p>')206 })207208 it('slot inside v-if', done => {209 const vm = new Vue({210 data: {211 a: 1,212 b: 2,213 show: true214 },215 template: '<test :show="show"><p slot="b">{{b}}</p><p>{{a}}</p></test>',216 components: {217 test: {218 props: ['show'],219 template: '<div v-if="show"><slot></slot><slot name="b"></slot></div>'220 }221 }222 }).$mount()223 expect(vm.$el.textContent).toBe('12')224 vm.a = 2225 waitForUpdate(() => {226 expect(vm.$el.textContent).toBe('22')227 vm.show = false228 })229 .then(() => {230 expect(vm.$el.textContent).toBe('')231 vm.show = true232 vm.a = 3233 })234 .then(() => {235 expect(vm.$el.textContent).toBe('32')236 })237 .then(done)238 })239240 it('slot inside v-for', () => {241 mount({242 childTemplate: '<div><slot v-for="i in 3" :name="i"></slot></div>',243 parentContent: '<p v-for="i in 3" :slot="i">{{ i - 1 }}</p>'244 })245 expect(child.$el.innerHTML).toBe('<p>0</p><p>1</p><p>2</p>')246 })247248 it('nested slots', done => {249 const vm = new Vue({250 template: '<test><test2><p>{{ msg }}</p></test2></test>',251 data: {252 msg: 'foo'253 },254 components: {255 test: {256 template: '<div><slot></slot></div>'257 },258 test2: {259 template: '<div><slot></slot></div>'260 }261 }262 }).$mount()263 expect(vm.$el.innerHTML).toBe('<div><p>foo</p></div>')264 vm.msg = 'bar'265 waitForUpdate(() => {266 expect(vm.$el.innerHTML).toBe('<div><p>bar</p></div>')267 }).then(done)268 })269270 it('v-if on inserted content', done => {271 const vm = new Vue({272 template: '<test><p v-if="ok">{{ msg }}</p></test>',273 data: {274 ok: true,275 msg: 'hi'276 },277 components: {278 test: {279 template: '<div><slot>fallback</slot></div>'280 }281 }282 }).$mount()283 expect(vm.$el.innerHTML).toBe('<p>hi</p>')284 vm.ok = false285 waitForUpdate(() => {286 expect(vm.$el.innerHTML).toBe('fallback')287 vm.ok = true288 vm.msg = 'bye'289 })290 .then(() => {291 expect(vm.$el.innerHTML).toBe('<p>bye</p>')292 })293 .then(done)294 })295296 it('template slot', function () {297 const vm = new Vue({298 template: '<test><template slot="test">hello</template></test>',299 components: {300 test: {301 template: '<div><slot name="test"></slot> world</div>'302 }303 }304 }).$mount()305 expect(vm.$el.innerHTML).toBe('hello world')306 })307308 it('combined with v-for', () => {309 const vm = new Vue({310 template: '<div><test v-for="i in 3" :key="i">{{ i }}</test></div>',311 components: {312 test: {313 template: '<div><slot></slot></div>'314 }315 }316 }).$mount()317 expect(vm.$el.innerHTML).toBe('<div>1</div><div>2</div><div>3</div>')318 })319320 it('inside template v-if', () => {321 mount({322 childTemplate: `323 <div>324 <template v-if="true"><slot></slot></template>325 </div>326 `,327 parentContent: 'foo'328 })329 expect(child.$el.innerHTML).toBe('foo')330 })331332 it('default slot should use fallback content if has only whitespace', () => {333 mount({334 childTemplate: `335 <div>336 <slot name="first"><p>first slot</p></slot>337 <slot><p>this is the default slot</p></slot>338 <slot name="second"><p>second named slot</p></slot>339 </div>340 `,341 parentContent: `<div slot="first">1</div> <div slot="second">2</div> <div slot="second">2+</div>`342 })343 expect(child.$el.innerHTML).toBe(344 '<div>1</div> <p>this is the default slot</p> <div>2</div><div>2+</div>'345 )346 })347348 it('programmatic access to $slots', () => {349 const vm = new Vue({350 template: '<test><p slot="a">A</p><div>C</div><p slot="b">B</p></test>',351 components: {352 test: {353 render() {354 expect(this.$slots.a.length).toBe(1)355 expect(this.$slots.a[0].tag).toBe('p')356 expect(this.$slots.a[0].children.length).toBe(1)357 expect(this.$slots.a[0].children[0].text).toBe('A')358359 expect(this.$slots.b.length).toBe(1)360 expect(this.$slots.b[0].tag).toBe('p')361 expect(this.$slots.b[0].children.length).toBe(1)362 expect(this.$slots.b[0].children[0].text).toBe('B')363364 expect(this.$slots.default.length).toBe(1)365 expect(this.$slots.default[0].tag).toBe('div')366 expect(this.$slots.default[0].children.length).toBe(1)367 expect(this.$slots.default[0].children[0].text).toBe('C')368369 return this.$slots.default[0]370 }371 }372 }373 }).$mount()374 expect(vm.$el.tagName).toBe('DIV')375 expect(vm.$el.textContent).toBe('C')376 })377378 it('warn if user directly returns array', () => {379 new Vue({380 template: '<test><div slot="foo"></div><div slot="foo"></div></test>',381 components: {382 test: {383 render() {384 return this.$slots.foo385 }386 }387 }388 }).$mount()389 expect(390 'Render function should return a single root node'391 ).toHaveBeenWarned()392 })393394 // #3254395 it('should not keep slot name when passed further down', () => {396 const vm = new Vue({397 template: '<test><span slot="foo">foo</span></test>',398 components: {399 test: {400 template: '<child><slot name="foo"></slot></child>',401 components: {402 child: {403 template: `404 <div>405 <div class="default"><slot></slot></div>406 <div class="named"><slot name="foo"></slot></div>407 </div>408 `409 }410 }411 }412 }413 }).$mount()414 expect(vm.$el.querySelector('.default').textContent).toBe('foo')415 expect(vm.$el.querySelector('.named').textContent).toBe('')416 })417418 it('should not keep slot name when passed further down (nested)', () => {419 const vm = new Vue({420 template: '<wrap><test><span slot="foo">foo</span></test></wrap>',421 components: {422 wrap: {423 template: '<div><slot></slot></div>'424 },425 test: {426 template: '<child><slot name="foo"></slot></child>',427 components: {428 child: {429 template: `430 <div>431 <div class="default"><slot></slot></div>432 <div class="named"><slot name="foo"></slot></div>433 </div>434 `435 }436 }437 }438 }439 }).$mount()440 expect(vm.$el.querySelector('.default').textContent).toBe('foo')441 expect(vm.$el.querySelector('.named').textContent).toBe('')442 })443444 it('should not keep slot name when passed further down (functional)', () => {445 const child = {446 template: `447 <div>448 <div class="default"><slot></slot></div>449 <div class="named"><slot name="foo"></slot></div>450 </div>451 `452 }453454 const vm = new Vue({455 template: '<test><span slot="foo">foo</span></test>',456 components: {457 test: {458 functional: true,459 render(h, ctx) {460 const slots = ctx.slots()461 return h(child, slots.foo)462 }463 }464 }465 }).$mount()466 expect(vm.$el.querySelector('.default').textContent).toBe('foo')467 expect(vm.$el.querySelector('.named').textContent).toBe('')468 })469470 // #3400471 it('named slots should be consistent across re-renders', done => {472 const vm = new Vue({473 template: `474 <comp>475 <div slot="foo">foo</div>476 </comp>477 `,478 components: {479 comp: {480 data() {481 return { a: 1 }482 },483 template: `<div><slot name="foo"></slot>{{ a }}</div>`484 }485 }486 }).$mount()487 expect(vm.$el.textContent).toBe('foo1')488 vm.$children[0].a = 2489 waitForUpdate(() => {490 expect(vm.$el.textContent).toBe('foo2')491 }).then(done)492 })493494 // #3437495 it('should correctly re-create components in slot', done => {496 const calls: any[] = []497 const vm = new Vue({498 template: `499 <comp ref="child">500 <div slot="foo">501 <child></child>502 </div>503 </comp>504 `,505 components: {506 comp: {507 data() {508 return { ok: true }509 },510 template: `<div><slot name="foo" v-if="ok"></slot></div>`511 },512 child: {513 template: '<div>child</div>',514 created() {515 calls.push(1)516 },517 destroyed() {518 calls.push(2)519 }520 }521 }522 }).$mount()523524 expect(calls).toEqual([1])525 vm.$refs.child.ok = false526 waitForUpdate(() => {527 expect(calls).toEqual([1, 2])528 vm.$refs.child.ok = true529 })530 .then(() => {531 expect(calls).toEqual([1, 2, 1])532 vm.$refs.child.ok = false533 })534 .then(() => {535 expect(calls).toEqual([1, 2, 1, 2])536 })537 .then(done)538 })539540 it('should support duplicate slots', done => {541 const vm = new Vue({542 template: `543 <foo ref="foo">544 <div slot="a">{{ n }}</div>545 </foo>546 `,547 data: {548 n: 1549 },550 components: {551 foo: {552 data() {553 return { ok: true }554 },555 template: `556 <div>557 <slot name="a" />558 <slot v-if="ok" name="a" />559 <pre><slot name="a" /></pre>560 </div>561 `562 }563 }564 }).$mount()565 expect(vm.$el.innerHTML).toBe(566 `<div>1</div> <div>1</div> <pre><div>1</div></pre>`567 )568 vm.n++569 waitForUpdate(() => {570 expect(vm.$el.innerHTML).toBe(571 `<div>2</div> <div>2</div> <pre><div>2</div></pre>`572 )573 vm.n++574 })575 .then(() => {576 expect(vm.$el.innerHTML).toBe(577 `<div>3</div> <div>3</div> <pre><div>3</div></pre>`578 )579 vm.$refs.foo.ok = false580 })581 .then(() => {582 expect(vm.$el.innerHTML).toBe(583 `<div>3</div> <!----> <pre><div>3</div></pre>`584 )585 vm.n++586 vm.$refs.foo.ok = true587 })588 .then(() => {589 expect(vm.$el.innerHTML).toBe(590 `<div>4</div> <div>4</div> <pre><div>4</div></pre>`591 )592 })593 .then(done)594 })595596 // #3518597 it('events should not break when slot is toggled by v-if', done => {598 const spy = vi.fn()599 const vm = new Vue({600 template: `<test><div class="click" @click="test">hi</div></test>`,601 methods: {602 test: spy603 },604 components: {605 test: {606 data: () => ({607 toggle: true608 }),609 template: `<div v-if="toggle"><slot></slot></div>`610 }611 }612 }).$mount()613614 document.body.appendChild(vm.$el)615 expect(vm.$el.textContent).toBe('hi')616 vm.$children[0].toggle = false617 waitForUpdate(() => {618 vm.$children[0].toggle = true619 })620 .then(() => {621 global.triggerEvent(vm.$el.querySelector('.click'), 'click')622 expect(spy).toHaveBeenCalled()623 })624 .then(() => {625 document.body.removeChild(vm.$el)626 })627 .then(done)628 })629630 it('renders static tree with text', () => {631 const vm = new Vue({632 template: `<div><test><template><div></div>Hello<div></div></template></test></div>`,633 components: {634 test: {635 template: '<div><slot></slot></div>'636 }637 }638 })639 vm.$mount()640 expect('Error when rendering root').not.toHaveBeenWarned()641 })642643 // #3872644 it('functional component as slot', () => {645 const vm = new Vue({646 template: `647 <parent>648 <child>one</child>649 <child slot="a">two</child>650 </parent>651 `,652 components: {653 parent: {654 template: `<div><slot name="a"></slot><slot></slot></div>`655 },656 child: {657 functional: true,658 render(h, { slots }) {659 return h('div', slots().default)660 }661 }662 }663 }).$mount()664 expect(vm.$el.innerHTML.trim()).toBe('<div>two</div><div>one</div>')665 })666667 // #4209668 it('slot of multiple text nodes should not be infinitely merged', done => {669 const wrap = {670 template: `<inner ref="inner">foo<slot></slot></inner>`,671 components: {672 inner: {673 data: () => ({ a: 1 }),674 template: `<div>{{a}}<slot></slot></div>`675 }676 }677 }678 const vm = new Vue({679 template: `<wrap ref="wrap">bar</wrap>`,680 components: { wrap }681 }).$mount()682683 expect(vm.$el.textContent).toBe('1foobar')684 vm.$refs.wrap.$refs.inner.a++685 waitForUpdate(() => {686 expect(vm.$el.textContent).toBe('2foobar')687 }).then(done)688 })689690 // #4315691 it('functional component passing slot content to stateful child component', done => {692 const ComponentWithSlots = {693 render(h) {694 return h('div', this.$slots.slot1)695 }696 }697698 const FunctionalComp = {699 functional: true,700 render(h) {701 return h(ComponentWithSlots, [h('span', { slot: 'slot1' }, 'foo')])702 }703 }704705 const vm = new Vue({706 data: { n: 1 },707 render(h) {708 return h('div', [this.n, h(FunctionalComp)])709 }710 }).$mount()711712 expect(vm.$el.textContent).toBe('1foo')713 vm.n++714 waitForUpdate(() => {715 // should not lose named slot716 expect(vm.$el.textContent).toBe('2foo')717 }).then(done)718 })719720 it('the elements of slot should be updated correctly', done => {721 const vm = new Vue({722 data: { n: 1 },723 template:724 '<div><test><span v-for="i in n" :key="i">{{ i }}</span><input value="a"/></test></div>',725 components: {726 test: {727 template: '<div><slot></slot></div>'728 }729 }730 }).$mount()731 expect(vm.$el.innerHTML).toBe('<div><span>1</span><input value="a"></div>')732 const input = vm.$el.querySelector('input')733 input.value = 'b'734 vm.n++735 waitForUpdate(() => {736 expect(vm.$el.innerHTML).toBe(737 '<div><span>1</span><span>2</span><input value="a"></div>'738 )739 expect(vm.$el.querySelector('input')).toBe(input)740 expect(vm.$el.querySelector('input').value).toBe('b')741 }).then(done)742 })743744 // GitHub issue #5888745 it('should resolve correctly slot with keep-alive', () => {746 const vm = new Vue({747 template: `748 <div>749 <container>750 <keep-alive slot="foo">751 <child></child>752 </keep-alive>753 </container>754 </div>755 `,756 components: {757 container: {758 template:759 '<div><slot>default</slot><slot name="foo">named</slot></div>'760 },761 child: {762 template: '<span>foo</span>'763 }764 }765 }).$mount()766 expect(vm.$el.innerHTML).toBe('<div>default<span>foo</span></div>')767 })768769 // #6372, #6915770 it('should handle nested components in slots properly', done => {771 const TestComponent = {772 template: `773 <component :is="toggleEl ? 'b' : 'i'">774 <slot />775 </component>776 `,777 data() {778 return {779 toggleEl: true780 }781 }782 }783784 const vm = new Vue({785 template: `786 <div>787 <test-component ref="test">788 <div>789 <foo/>790 </div>791 <bar>792 <foo/>793 </bar>794 </test-component>795 </div>796 `,797 components: {798 TestComponent,799 foo: {800 template: `<div>foo</div>`801 },802 bar: {803 template: `<div>bar<slot/></div>`804 }805 }806 }).$mount()807808 expect(vm.$el.innerHTML).toBe(809 `<b><div><div>foo</div></div> <div>bar<div>foo</div></div></b>`810 )811812 vm.$refs.test.toggleEl = false813 waitForUpdate(() => {814 expect(vm.$el.innerHTML).toBe(815 `<i><div><div>foo</div></div> <div>bar<div>foo</div></div></i>`816 )817 }).then(done)818 })819820 it('should preserve slot attribute if not absorbed by a Vue component', () => {821 const vm = new Vue({822 template: `823 <div>824 <div slot="foo"></div>825 </div>826 `827 }).$mount()828 expect(vm.$el.children[0].getAttribute('slot')).toBe('foo')829 })830831 it('passing a slot down as named slot', () => {832 const Bar = {833 template: `<div class="bar"><slot name="foo"/></div>`834 }835836 const Foo = {837 components: { Bar },838 template: `<div class="foo"><bar><slot slot="foo"/></bar></div>`839 }840841 const vm = new Vue({842 components: { Foo },843 template: `<div><foo>hello</foo></div>`844 }).$mount()845846 expect(vm.$el.innerHTML).toBe(847 '<div class="foo"><div class="bar">hello</div></div>'848 )849 })850851 it('fallback content for named template slot', () => {852 const Bar = {853 template: `<div class="bar"><slot name="foo">fallback</slot></div>`854 }855856 const Foo = {857 components: { Bar },858 template: `<div class="foo"><bar><template slot="foo"/><slot/></template></bar></div>`859 }860861 const vm = new Vue({862 components: { Foo },863 template: `<div><foo></foo></div>`864 }).$mount()865866 expect(vm.$el.innerHTML).toBe(867 '<div class="foo"><div class="bar">fallback</div></div>'868 )869 })870871 // #7106872 it('should not lose functional slot across renders', done => {873 const One = {874 data: () => ({875 foo: true876 }),877 render(h) {878 this.foo879 return h('div', this.$slots.slot)880 }881 }882883 const Two = {884 render(h) {885 return h('span', this.$slots.slot)886 }887 }888889 const Three = {890 functional: true,891 render: (h, { children }) => h('span', children)892 }893894 const vm = new Vue({895 template: `896 <div>897 <one ref="one">898 <two slot="slot">899 <three slot="slot">hello</three>900 </two>901 </one>902 </div>903 `,904 components: { One, Two, Three }905 }).$mount()906907 expect(vm.$el.textContent).toBe('hello')908 // trigger re-render of <one>909 vm.$refs.one.foo = false910 waitForUpdate(() => {911 // should still be there912 expect(vm.$el.textContent).toBe('hello')913 }).then(done)914 })915916 it('should allow passing named slots as raw children down multiple layers of functional component', () => {917 const CompB = {918 functional: true,919 render(h, { slots }) {920 return slots().foo921 }922 }923924 const CompA = {925 functional: true,926 render(h, { children }) {927 return h(CompB, children)928 }929 }930931 const vm = new Vue({932 components: {933 CompA934 },935 template: `936 <div>937 <comp-a>938 <span slot="foo">foo</span>939 </comp-a>940 </div>941 `942 }).$mount()943944 expect(vm.$el.textContent).toBe('foo')945 })946947 // #7817948 it('should not match wrong named slot in functional component on re-render', done => {949 const Functional = {950 functional: true,951 render: (h, ctx) => ctx.slots().default952 }953954 const Stateful = {955 data() {956 return { ok: true }957 },958 render(h) {959 this.ok // register dep960 return h('div', [h(Functional, this.$slots.named)])961 }962 }963964 const vm = new Vue({965 template: `<stateful ref="stateful"><div slot="named">foo</div></stateful>`,966 components: { Stateful }967 }).$mount()968969 expect(vm.$el.textContent).toBe('foo')970 vm.$refs.stateful.ok = false971 waitForUpdate(() => {972 expect(vm.$el.textContent).toBe('foo')973 }).then(done)974 })975976 // #7975977 it('should update named slot correctly when its position in the tree changed', done => {978 const ChildComponent = {979 template: '<b>{{ message }}</b>',980 props: ['message']981 }982 let parentVm983 const ParentComponent = {984 template: `985 <div>986 <span v-if="alter">987 <span><slot name="foo" /></span>988 </span>989 <span v-else>990 <slot name="foo" />991 </span>992 </div>993 `,994 data() {995 return {996 alter: true997 }998 },999 mounted() {1000 parentVm = this1001 }1002 }1003 const vm = new Vue({1004 template: `1005 <parent-component>1006 <span slot="foo">1007 <child-component :message="message" />1008 </span>1009 </parent-component>1010 `,1011 components: {1012 ChildComponent,1013 ParentComponent1014 },1015 data() {1016 return {1017 message: 11018 }1019 }1020 }).$mount()1021 expect(vm.$el.firstChild.innerHTML).toBe(1022 '<span><span><b>1</b></span></span>'1023 )1024 parentVm.alter = false1025 waitForUpdate(() => {1026 vm.message = 21027 })1028 .then(() => {1029 expect(vm.$el.firstChild.innerHTML).toBe('<span><b>2</b></span>')1030 })1031 .then(done)1032 })10331034 // #121021035 it('v-if inside scoped slot', () => {1036 const vm = new Vue({1037 template: `<test><template #custom><span v-if="false">a</span><span>b</span></template></test>`,1038 components: {1039 test: {1040 template: `<div><slot name="custom"/></div>`1041 }1042 }1043 }).$mount()10441045 expect(vm.$el.innerHTML).toBe(`<!----><span>b</span>`)1046 })10471048 // regression 2.7.0-alpha.41049 it('passing scoped slots through nested parent chain', () => {1050 const Foo = {1051 template: `1052 <div><slot>foo default</slot></div>1053 `1054 }10551056 const Bar = {1057 components: { Foo },1058 template: `<Foo><slot name="bar"/></Foo>`1059 }10601061 const App = {1062 components: { Bar },1063 template: `<Bar>1064 <template #bar>1065 <span>App content for Bar#bar</span>1066 </template>1067 </Bar>`1068 }10691070 const vm = new Vue({1071 render: h => h(App)1072 }).$mount()10731074 expect(vm.$el.innerHTML).toMatch(`App content for Bar#bar`)1075 })1076})
Findings
✓ No findings reported for this file.