Skip to content

Commit

Permalink
feat(compiler-core): support v-is
Browse files Browse the repository at this point in the history
see vuejs/rfcs#149 for details
  • Loading branch information
yyx990803 committed Mar 27, 2020
1 parent d777ac6 commit b8ffbff
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 5 deletions.
49 changes: 49 additions & 0 deletions packages/compiler-core/__tests__/parse.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,55 @@ describe('compiler: parse', () => {
})
})

test('v-is without `isNativeTag`', () => {
const ast = baseParse(
`<div></div><div v-is="'foo'"></div><Comp></Comp>`,
{
isNativeTag: tag => tag === 'div'
}
)

expect(ast.children[0]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'div',
tagType: ElementTypes.ELEMENT
})

expect(ast.children[1]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'div',
tagType: ElementTypes.COMPONENT
})

expect(ast.children[2]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'Comp',
tagType: ElementTypes.COMPONENT
})
})

test('v-is with `isNativeTag`', () => {
const ast = baseParse(`<div></div><div v-is="'foo'"></div><Comp></Comp>`)

expect(ast.children[0]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'div',
tagType: ElementTypes.ELEMENT
})

expect(ast.children[1]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'div',
tagType: ElementTypes.COMPONENT
})

expect(ast.children[2]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'Comp',
tagType: ElementTypes.COMPONENT
})
})

test('custom element', () => {
const ast = baseParse('<div></div><comp></comp>', {
isNativeTag: tag => tag === 'div',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,25 @@ describe('compiler: element transform', () => {
}
})
})

test('v-is', () => {
const { node, root } = parseWithBind(`<div v-is="'foo'" />`)
expect(root.helpers).toContain(RESOLVE_DYNAMIC_COMPONENT)
expect(node).toMatchObject({
tag: {
callee: RESOLVE_DYNAMIC_COMPONENT,
arguments: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: `'foo'`,
isStatic: false
}
]
},
// should skip v-is runtime check
directives: undefined
})
})
})

test('<svg> should be forced into blocks', () => {
Expand Down
6 changes: 5 additions & 1 deletion packages/compiler-core/src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,9 +451,13 @@ function parseTag(
let tagType = ElementTypes.ELEMENT
const options = context.options
if (!context.inPre && !options.isCustomElement(tag)) {
if (options.isNativeTag) {
const hasVIs = props.some(
p => p.type === NodeTypes.DIRECTIVE && p.name === 'is'
)
if (options.isNativeTag && !hasVIs) {
if (!options.isNativeTag(tag)) tagType = ElementTypes.COMPONENT
} else if (
hasVIs ||
isCoreComponent(tag) ||
(options.isBuiltInComponent && options.isBuiltInComponent(tag)) ||
/^[A-Z]/.test(tag) ||
Expand Down
13 changes: 9 additions & 4 deletions packages/compiler-core/src/transforms/transformElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ import {
toValidAssetId,
findProp,
isCoreComponent,
isBindKey
isBindKey,
findDir
} from '../utils'
import { buildSlots } from './vSlot'
import { isStaticNode } from './hoistStatic'
Expand Down Expand Up @@ -202,7 +203,8 @@ export function resolveComponentType(
const { tag } = node

// 1. dynamic component
const isProp = node.tag === 'component' && findProp(node, 'is')
const isProp =
node.tag === 'component' ? findProp(node, 'is') : findDir(node, 'is')
if (isProp) {
const exp =
isProp.type === NodeTypes.ATTRIBUTE
Expand Down Expand Up @@ -340,8 +342,11 @@ export function buildProps(
if (name === 'once') {
continue
}
// skip :is on <component>
if (isBind && tag === 'component' && isBindKey(arg, 'is')) {
// skip v-is and :is on <component>
if (
name === 'is' ||
(isBind && tag === 'component' && isBindKey(arg, 'is'))
) {
continue
}
// skip v-on in SSR compilation
Expand Down

0 comments on commit b8ffbff

Please sign in to comment.