Skip to content

Slot scope id refactor #3374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 19 additions & 32 deletions packages/compiler-core/__tests__/__snapshots__/scopeId.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,91 +1,78 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`scopeId compiler support should push scopeId for hoisted nodes 1`] = `
"import { createVNode as _createVNode, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \\"vue\\"
const _withId = /*#__PURE__*/_withScopeId(\\"test\\")
"import { createVNode as _createVNode, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, openBlock as _openBlock, createBlock as _createBlock, setScopeId as _setScopeId } from \\"vue\\"

_pushScopeId(\\"test\\")
_setScopeId(\\"test\\")
const _hoisted_1 = /*#__PURE__*/_createVNode(\\"div\\", null, \\"hello\\", -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createVNode(\\"div\\", null, \\"world\\", -1 /* HOISTED */)
_popScopeId()
_setScopeId(null)

export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"div\\", null, [
_hoisted_1,
_createTextVNode(_toDisplayString(_ctx.foo), 1 /* TEXT */),
_hoisted_2
]))
})"
}"
`;

exports[`scopeId compiler support should wrap default slot 1`] = `
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
const _withId = /*#__PURE__*/_withScopeId(\\"test\\")
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"

export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
export function render(_ctx, _cache) {
const _component_Child = _resolveComponent(\\"Child\\")

return (_openBlock(), _createBlock(_component_Child, null, {
default: _withId(() => [
default: _withCtx(() => [
_createVNode(\\"div\\")
]),
_: 1 /* STABLE */
}))
})"
}"
`;

exports[`scopeId compiler support should wrap dynamic slots 1`] = `
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, renderList as _renderList, createSlots as _createSlots, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
const _withId = /*#__PURE__*/_withScopeId(\\"test\\")
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, renderList as _renderList, createSlots as _createSlots, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"

export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
export function render(_ctx, _cache) {
const _component_Child = _resolveComponent(\\"Child\\")

return (_openBlock(), _createBlock(_component_Child, null, _createSlots({ _: 2 /* DYNAMIC */ }, [
(_ctx.ok)
? {
name: \\"foo\\",
fn: _withId(() => [
fn: _withCtx(() => [
_createVNode(\\"div\\")
])
}
: undefined,
_renderList(_ctx.list, (i) => {
return {
name: i,
fn: _withId(() => [
fn: _withCtx(() => [
_createVNode(\\"div\\")
])
}
})
]), 1024 /* DYNAMIC_SLOTS */))
})"
}"
`;

exports[`scopeId compiler support should wrap named slots 1`] = `
"import { toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
const _withId = /*#__PURE__*/_withScopeId(\\"test\\")
"import { toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"

export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
export function render(_ctx, _cache) {
const _component_Child = _resolveComponent(\\"Child\\")

return (_openBlock(), _createBlock(_component_Child, null, {
foo: _withId(({ msg }) => [
foo: _withCtx(({ msg }) => [
_createTextVNode(_toDisplayString(msg), 1 /* TEXT */)
]),
bar: _withId(() => [
bar: _withCtx(() => [
_createVNode(\\"div\\")
]),
_: 1 /* STABLE */
}))
})"
`;

exports[`scopeId compiler support should wrap render function 1`] = `
"import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
const _withId = /*#__PURE__*/_withScopeId(\\"test\\")

export const render = /*#__PURE__*/_withId((_ctx, _cache) => {
return (_openBlock(), _createBlock(\\"div\\"))
})"
}"
`;
41 changes: 14 additions & 27 deletions packages/compiler-core/__tests__/scopeId.spec.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,26 @@
import { baseCompile } from '../src/compile'
import {
WITH_SCOPE_ID,
PUSH_SCOPE_ID,
POP_SCOPE_ID
} from '../src/runtimeHelpers'
import { SET_SCOPE_ID } from '../src/runtimeHelpers'
import { PatchFlags } from '@vue/shared'
import { genFlagText } from './testUtils'

/**
* Ensure all slot functions are wrapped with _withCtx
* which sets the currentRenderingInstance and currentScopeId when rendering
* the slot.
*/
describe('scopeId compiler support', () => {
test('should only work in module mode', () => {
expect(() => {
baseCompile(``, { scopeId: 'test' })
}).toThrow(`"scopeId" option is only supported in module mode`)
})

test('should wrap render function', () => {
const { ast, code } = baseCompile(`<div/>`, {
mode: 'module',
scopeId: 'test'
})
expect(ast.helpers).toContain(WITH_SCOPE_ID)
expect(code).toMatch(`const _withId = /*#__PURE__*/_withScopeId("test")`)
expect(code).toMatch(
`export const render = /*#__PURE__*/_withId((_ctx, _cache) => {`
)
expect(code).toMatchSnapshot()
})

test('should wrap default slot', () => {
const { code } = baseCompile(`<Child><div/></Child>`, {
mode: 'module',
scopeId: 'test'
})
expect(code).toMatch(`default: _withId(() => [`)
expect(code).toMatch(`default: _withCtx(() => [`)
expect(code).toMatchSnapshot()
})

Expand All @@ -48,8 +36,8 @@ describe('scopeId compiler support', () => {
scopeId: 'test'
}
)
expect(code).toMatch(`foo: _withId(({ msg }) => [`)
expect(code).toMatch(`bar: _withId(() => [`)
expect(code).toMatch(`foo: _withCtx(({ msg }) => [`)
expect(code).toMatch(`bar: _withCtx(() => [`)
expect(code).toMatchSnapshot()
})

Expand All @@ -65,8 +53,8 @@ describe('scopeId compiler support', () => {
scopeId: 'test'
}
)
expect(code).toMatch(/name: "foo",\s+fn: _withId\(/)
expect(code).toMatch(/name: i,\s+fn: _withId\(/)
expect(code).toMatch(/name: "foo",\s+fn: _withCtx\(/)
expect(code).toMatch(/name: i,\s+fn: _withCtx\(/)
expect(code).toMatchSnapshot()
})

Expand All @@ -79,19 +67,18 @@ describe('scopeId compiler support', () => {
hoistStatic: true
}
)
expect(ast.helpers).toContain(PUSH_SCOPE_ID)
expect(ast.helpers).toContain(POP_SCOPE_ID)
expect(ast.helpers).toContain(SET_SCOPE_ID)
expect(ast.hoists.length).toBe(2)
expect(code).toMatch(
[
`_pushScopeId("test")`,
`_setScopeId("test")`,
`const _hoisted_1 = /*#__PURE__*/_createVNode("div", null, "hello", ${genFlagText(
PatchFlags.HOISTED
)})`,
`const _hoisted_2 = /*#__PURE__*/_createVNode("div", null, "world", ${genFlagText(
PatchFlags.HOISTED
)})`,
`_popScopeId()`
`_setScopeId(null)`
].join('\n')
)
expect(code).toMatchSnapshot()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ return function render(_ctx, _cache) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, renderSlot: _renderSlot } = _Vue

return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return _renderSlot($slots, \\"default\\")
return _renderSlot($slots, \\"default\\", {}, undefined, true)
}), 256 /* UNKEYED_FRAGMENT */))
}
}"
Expand All @@ -143,7 +143,7 @@ return function render(_ctx, _cache) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, renderSlot: _renderSlot } = _Vue

return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return _renderSlot($slots, \\"default\\")
return _renderSlot($slots, \\"default\\", {}, undefined, true)
}), 256 /* UNKEYED_FRAGMENT */))
}
}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ return function render(_ctx, _cache) {
const { renderSlot: _renderSlot, createCommentVNode: _createCommentVNode } = _Vue

return ok
? _renderSlot($slots, \\"default\\", { key: 0 })
? _renderSlot($slots, \\"default\\", { key: 0 }, undefined, true)
: _createCommentVNode(\\"v-if\\", true)
}
}"
Expand Down Expand Up @@ -140,7 +140,7 @@ return function render(_ctx, _cache) {
const { renderSlot: _renderSlot, createCommentVNode: _createCommentVNode } = _Vue

return ok
? _renderSlot($slots, \\"default\\", { key: 0 })
? _renderSlot($slots, \\"default\\", { key: 0 }, undefined, true)
: _createCommentVNode(\\"v-if\\", true)
}
}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ return function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"div\\", null, [
_cache[1] || (
_setBlockTracking(-1),
_cache[1] = _renderSlot($slots, \\"default\\"),
_cache[1] = _renderSlot($slots, \\"default\\", {}, undefined, true),
_setBlockTracking(1),
_cache[1]
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { transformSlotOutlet } from '../../src/transforms/transformSlotOutlet'
function parseWithSlots(template: string, options: CompilerOptions = {}) {
const ast = parse(template)
transform(ast, {
slotted: false,
nodeTransforms: [
...(options.prefixIdentifiers ? [transformExpression] : []),
transformSlotOutlet,
Expand Down Expand Up @@ -339,6 +340,15 @@ describe('compiler: transform <slot> outlets', () => {
})
})

test('slot with slotted: true', async () => {
const ast = parseWithSlots(`<slot/>`, { slotted: true })
expect((ast.children[0] as ElementNode).codegenNode).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_SLOT,
arguments: [`$slots`, `"default"`, `{}`, `undefined`, `true`]
})
})

test(`error on unexpected custom directive on <slot>`, () => {
const onError = jest.fn()
const source = `<slot v-foo />`
Expand Down
16 changes: 14 additions & 2 deletions packages/compiler-core/__tests__/transforms/vIf.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,13 @@ describe('compiler: v-if', () => {
expect(codegenNode.consequent).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_SLOT,
arguments: ['$slots', '"default"', createObjectMatcher({ key: `[0]` })]
arguments: [
'$slots',
'"default"',
createObjectMatcher({ key: `[0]` }),
'undefined',
'true'
]
})
expect(generate(root).code).toMatchSnapshot()
})
Expand All @@ -417,7 +423,13 @@ describe('compiler: v-if', () => {
expect(codegenNode.consequent).toMatchObject({
type: NodeTypes.JS_CALL_EXPRESSION,
callee: RENDER_SLOT,
arguments: ['$slots', '"default"', createObjectMatcher({ key: `[0]` })]
arguments: [
'$slots',
'"default"',
createObjectMatcher({ key: `[0]` }),
'undefined',
'true'
]
})
expect(generate(root).code).toMatchSnapshot()
})
Expand Down
Loading