feat: add isCustomElement option (#299)

This commit is contained in:
月迷津渡 2019-10-16 05:30:47 +08:00 committed by Evan You
parent b60355d857
commit f71bf2f1d3
5 changed files with 36 additions and 1 deletions

View File

@ -616,6 +616,25 @@ describe('compiler: parse', () => {
})
})
test('custom element', () => {
const ast = parse('<div></div><comp></comp>', {
isNativeTag: tag => tag === 'div',
isCustomElement: tag => tag === 'comp'
})
expect(ast.children[0]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'div',
tagType: ElementTypes.ELEMENT
})
expect(ast.children[1]).toMatchObject({
type: NodeTypes.ELEMENT,
tag: 'comp',
tagType: ElementTypes.ELEMENT
})
})
test('attribute with no value', () => {
const ast = parse('<div id></div>')
const element = ast.children[0] as ElementNode

View File

@ -32,6 +32,7 @@ import { extend } from '@vue/shared'
export interface ParserOptions {
isVoidTag?: (tag: string) => boolean // e.g. img, br, hr
isNativeTag?: (tag: string) => boolean // e.g. loading-indicator in weex
isCustomElement?: (tag: string) => boolean
getNamespace?: (tag: string, parent: ElementNode | undefined) => Namespace
getTextMode?: (tag: string, ns: Namespace) => TextModes
delimiters?: [string, string] // ['{{', '}}']
@ -54,6 +55,7 @@ export const defaultParserOptions: MergedParserOptions = {
getNamespace: () => Namespaces.HTML,
getTextMode: () => TextModes.DATA,
isVoidTag: NO,
isCustomElement: NO,
namedCharacterReferences: {
'gt;': '>',
'lt;': '<',
@ -433,7 +435,7 @@ function parseTag(
}
let tagType = ElementTypes.ELEMENT
if (!context.inPre) {
if (!context.inPre && !context.options.isCustomElement(tag)) {
if (context.options.isNativeTag) {
if (!context.options.isNativeTag(tag)) tagType = ElementTypes.COMPONENT
} else {

View File

@ -28,6 +28,7 @@ export interface AppConfig {
devtools: boolean
performance: boolean
readonly isNativeTag?: (tag: string) => boolean
isCustomElement?: (tag: string) => boolean
errorHandler?: (
err: Error,
instance: ComponentPublicInstance | null,
@ -62,6 +63,7 @@ export function createAppContext(): AppContext {
devtools: true,
performance: false,
isNativeTag: NO,
isCustomElement: NO,
errorHandler: undefined,
warnHandler: undefined
},

View File

@ -350,6 +350,7 @@ function finishComponentSetup(
if (__RUNTIME_COMPILE__ && Component.template && !Component.render) {
if (compile) {
Component.render = compile(Component.template, {
isCustomElement: instance.appContext.config.isCustomElement || NO,
onError(err: CompilerError) {
if (__DEV__) {
const message = `Template compilation error: ${err.message}`

View File

@ -29,3 +29,14 @@ it('should correctly normalize class with on-the-fly template compilation', () =
expect(classes.contains('test')).toBe(true)
expect(classes.contains('test2')).toBe(false)
})
it('should support custom element', () => {
const app = createApp()
const container = document.createElement('div')
const App = {
template: '<custom></custom>'
}
app.config.isCustomElement = tag => tag === 'custom'
app.mount(App, container)
expect(container.innerHTML).toBe('<custom></custom>')
})