Skip to content

Commit e4d8c2c

Browse files
authored
Merge pull request #1383 from vuejs/issue-1261
Support v-slot
2 parents a7d551f + 0921ace commit e4d8c2c

File tree

7 files changed

+125
-20
lines changed

7 files changed

+125
-20
lines changed

Diff for: package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,12 @@
7676
"sinon-chai": "^3.3.0",
7777
"typescript": "3",
7878
"vee-validate": "^2.1.3",
79-
"vue": "^2.5.22",
79+
"vue": "^2.6.11",
8080
"vue-class-component": "^6.1.2",
8181
"vue-loader": "^13.6.2",
8282
"vue-router": "^3.0.1",
83-
"vue-server-renderer": "^2.5.22",
84-
"vue-template-compiler": "^2.5.22",
83+
"vue-server-renderer": "^2.6.11",
84+
"vue-template-compiler": "^2.6.11",
8585
"vuepress": "^0.14.2",
8686
"vuepress-theme-vue": "^1.0.3",
8787
"vuex": "^3.0.1",

Diff for: packages/create-instance/create-component-stubs.js

+32-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
// @flow
22

33
import Vue from 'vue'
4-
import { throwError, camelize, capitalize, hyphenate } from '../shared/util'
4+
import {
5+
throwError,
6+
camelize,
7+
capitalize,
8+
hyphenate,
9+
keys
10+
} from '../shared/util'
511
import {
612
componentNeedsCompiling,
713
templateContainsComponent,
@@ -74,6 +80,25 @@ function resolveOptions(component, _Vue) {
7480
return options
7581
}
7682

83+
function getScopedSlotRenderFunctions(ctx: any): Array<string> {
84+
// In Vue 2.6+ a new v-slot syntax was introduced
85+
// scopedSlots are now saved in parent._vnode.data.scopedSlots
86+
// We filter out the _normalized and $stable key
87+
if (
88+
ctx &&
89+
ctx.$options &&
90+
ctx.$options.parent &&
91+
ctx.$options.parent._vnode &&
92+
ctx.$options.parent._vnode.data &&
93+
ctx.$options.parent._vnode.data.scopedSlots
94+
) {
95+
const slotKeys: Array<string> = ctx.$options.parent._vnode.data.scopedSlots
96+
return keys(slotKeys).filter(x => x !== '_normalized' && x !== '$stable')
97+
}
98+
99+
return []
100+
}
101+
77102
export function createStubFromComponent(
78103
originalComponent: Component,
79104
name: string,
@@ -109,7 +134,12 @@ export function createStubFromComponent(
109134
...this.$props
110135
}
111136
},
112-
context ? context.children : this.$options._renderChildren
137+
context
138+
? context.children
139+
: this.$options._renderChildren ||
140+
getScopedSlotRenderFunctions(this).map(x =>
141+
this.$options.parent._vnode.data.scopedSlots[x]()
142+
)
113143
)
114144
}
115145
}

Diff for: packages/shared/util.js

+4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ function hasOwnProperty(obj, prop) {
3636
return Object.prototype.hasOwnProperty.call(obj, prop)
3737
}
3838

39+
export function keys<T: string>(obj: any): Array<T> {
40+
return Object.keys(obj)
41+
}
42+
3943
export function resolveComponent(id: string, components: Object) {
4044
if (typeof id !== 'string') {
4145
return
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<template>
2+
<ComponentWithVSlot>
3+
<template v-slot:newSyntax>
4+
<p class="new-example">new slot syntax</p>
5+
</template>
6+
</ComponentWithVSlot>
7+
</template>
8+
9+
<script>
10+
import ComponentWithVSlot from './component-with-v-slot.vue'
11+
12+
export default {
13+
name: 'ComponentWithVSlotSyntax',
14+
15+
components: { ComponentWithVSlot }
16+
}
17+
</script>

Diff for: test/resources/components/component-with-v-slot.vue

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<template>
2+
<div>
3+
<slot name="newSyntax" />
4+
</div>
5+
</template>
6+
7+
<script>
8+
export default {
9+
name: 'ComponentWithVSlot'
10+
}
11+
</script>

Diff for: test/specs/shallow-mount.spec.js

+38
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import ComponentWithNestedChildren from '~resources/components/component-with-ne
77
import ComponentWithLifecycleHooks from '~resources/components/component-with-lifecycle-hooks.vue'
88
import ComponentWithoutName from '~resources/components/component-without-name.vue'
99
import ComponentAsAClassWithChild from '~resources/components/component-as-a-class-with-child.vue'
10+
import ComponentWithVSlotSyntax from '~resources/components/component-with-v-slot-syntax.vue'
11+
import ComponentWithVSlot from '~resources/components/component-with-v-slot.vue'
1012
import RecursiveComponent from '~resources/components/recursive-component.vue'
1113
import { vueVersion } from '~resources/utils'
1214
import { describeRunIf, itDoNotRunIf } from 'conditional-specs'
@@ -96,6 +98,42 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'shallowMount', () => {
9698
)
9799
})
98100

101+
it('renders SFC with named slots with v-slot syntax', () => {
102+
const wrapper = shallowMount(ComponentWithVSlotSyntax)
103+
104+
expect(wrapper.find(ComponentWithVSlot).exists()).to.equal(true)
105+
expect(wrapper.find('.new-example').exists()).to.equal(true)
106+
expect(wrapper.html()).to.equal(
107+
'<componentwithvslot-stub>\n' +
108+
' <p class="new-example">new slot syntax</p>\n' +
109+
'</componentwithvslot-stub>'
110+
)
111+
})
112+
113+
it('renders named slots with v-slot syntax', () => {
114+
const localVue = createLocalVue()
115+
localVue.component('Foo', {
116+
template: '<div><slot name="newSyntax" /></div>'
117+
})
118+
const TestComponent = {
119+
template: `
120+
<Foo>
121+
<template v-slot:newSyntax>
122+
<p class="new-example">text</p>
123+
</template>
124+
</Foo>
125+
`
126+
}
127+
const wrapper = shallowMount(TestComponent, {
128+
localVue
129+
})
130+
expect(wrapper.find({ name: 'Foo' }).exists()).to.equal(true)
131+
expect(wrapper.find('.new-example').exists()).to.equal(true)
132+
expect(wrapper.html()).to.equal(
133+
'<foo-stub>\n' + ' <p class="new-example">text</p>\n' + '</foo-stub>'
134+
)
135+
})
136+
99137
it('renders no children if none supplied', () => {
100138
const TestComponent = {
101139
template: '<child />',

Diff for: yarn.lock

+20-15
Original file line numberDiff line numberDiff line change
@@ -6290,7 +6290,7 @@ lodash.sortby@^4.7.0:
62906290
version "4.7.0"
62916291
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
62926292

6293-
lodash.template@^4.0.2, lodash.template@^4.4.0:
6293+
lodash.template@^4.0.2, lodash.template@^4.4.0, lodash.template@^4.5.0:
62946294
version "4.5.0"
62956295
resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
62966296
integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==
@@ -8787,6 +8787,11 @@ serialize-javascript@^1.4.0:
87878787
version "1.5.0"
87888788
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe"
87898789

8790+
serialize-javascript@^2.1.2:
8791+
version "2.1.2"
8792+
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61"
8793+
integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==
8794+
87908795
set-blocking@^2.0.0, set-blocking@~2.0.0:
87918796
version "2.0.0"
87928797
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
@@ -10092,18 +10097,18 @@ vue-server-renderer@^2.5.16:
1009210097
serialize-javascript "^1.3.0"
1009310098
source-map "0.5.6"
1009410099

10095-
vue-server-renderer@^2.5.22:
10096-
version "2.5.22"
10097-
resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.5.22.tgz#f119efef289c865adc22fda0ae7595299bedbdcf"
10098-
integrity sha512-PQ0PubA6b2MyZud/gepWeiUuDFSbRfa6h1qYINcbwXRr4Z3yLTHprEQuFnWikdkTkZpeLFYUqZrDxPbDcJ71mA==
10100+
vue-server-renderer@^2.6.11:
10101+
version "2.6.11"
10102+
resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.6.11.tgz#be8c9abc6aacc309828a755c021a05fc474b4bc3"
10103+
integrity sha512-V3faFJHr2KYfdSIalL+JjinZSHYUhlrvJ9pzCIjjwSh77+pkrsXpK4PucdPcng57+N77pd1LrKqwbqjQdktU1A==
1009910104
dependencies:
1010010105
chalk "^1.1.3"
1010110106
hash-sum "^1.0.2"
1010210107
he "^1.1.0"
10103-
lodash.template "^4.4.0"
10108+
lodash.template "^4.5.0"
1010410109
lodash.uniq "^4.5.0"
1010510110
resolve "^1.2.0"
10106-
serialize-javascript "^1.3.0"
10111+
serialize-javascript "^2.1.2"
1010710112
source-map "0.5.6"
1010810113

1010910114
vue-style-loader@^3.0.0:
@@ -10127,10 +10132,10 @@ vue-template-compiler@^2.5.16:
1012710132
de-indent "^1.0.2"
1012810133
he "^1.1.0"
1012910134

10130-
vue-template-compiler@^2.5.22:
10131-
version "2.5.22"
10132-
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.22.tgz#c3d3c02c65f1908205c4fbd3b0ef579e51239955"
10133-
integrity sha512-1VTw/NPTUeHNiwhkq6NkFzO7gYLjFCueBN0FX8NEiQIemd5EUMQ5hxrF7O0zCPo5tae+U9S/scETPea+hIz8Eg==
10135+
vue-template-compiler@^2.6.11:
10136+
version "2.6.11"
10137+
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz#c04704ef8f498b153130018993e56309d4698080"
10138+
integrity sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA==
1013410139
dependencies:
1013510140
de-indent "^1.0.2"
1013610141
he "^1.1.0"
@@ -10143,10 +10148,10 @@ vue@^2.5.16:
1014310148
version "2.5.16"
1014410149
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.16.tgz#07edb75e8412aaeed871ebafa99f4672584a0085"
1014510150

10146-
vue@^2.5.22:
10147-
version "2.5.22"
10148-
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.22.tgz#3bf88041af08b8539c37b268b70ca79245e9cc30"
10149-
integrity sha512-pxY3ZHlXNJMFQbkjEgGVMaMMkSV1ONpz+4qB55kZuJzyJOhn6MSy/YZdzhdnumegNzVTL/Dn3Pp4UrVBYt1j/g==
10151+
vue@^2.6.11:
10152+
version "2.6.11"
10153+
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5"
10154+
integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==
1015010155

1015110156
vuepress-html-webpack-plugin@^3.2.0:
1015210157
version "3.2.0"

0 commit comments

Comments
 (0)