wip: is usage compat

This commit is contained in:
Evan You 2021-04-16 11:43:05 -04:00
parent e130c7db23
commit d974adb327
3 changed files with 36 additions and 12 deletions

View File

@ -31,7 +31,10 @@ type DeprecationData = {
const deprecationData: Record<CompilerDeprecationTypes, DeprecationData> = { const deprecationData: Record<CompilerDeprecationTypes, DeprecationData> = {
[CompilerDeprecationTypes.IS_ON_ELEMENT]: { [CompilerDeprecationTypes.IS_ON_ELEMENT]: {
message: ``, message:
`Platform-native elements with "is" prop will no longer be ` +
`treated as components in Vue 3 unless the "is" value is explicitly ` +
`prefixed with "vue:".`,
link: `https://v3.vuejs.org/guide/migration/custom-elements-interop.html` link: `https://v3.vuejs.org/guide/migration/custom-elements-interop.html`
}, },

View File

@ -30,7 +30,11 @@ import {
createRoot, createRoot,
ConstantTypes ConstantTypes
} from './ast' } from './ast'
import { CompilerCompatOptions } from './compat/compatConfig' import {
checkCompatEnabled,
CompilerCompatOptions,
CompilerDeprecationTypes
} from './compat/compatConfig'
type OptionalOptions = type OptionalOptions =
| 'isNativeTag' | 'isNativeTag'
@ -499,14 +503,28 @@ function parseTag(
let tagType = ElementTypes.ELEMENT let tagType = ElementTypes.ELEMENT
const options = context.options const options = context.options
if (!context.inVPre && !options.isCustomElement(tag)) { if (!context.inVPre && !options.isCustomElement(tag)) {
const hasVIs = props.some( const hasVIs = props.some(p => {
p => if (p.name !== 'is') return
p.name === 'is' &&
// v-is="xxx" (TODO: deprecate) // v-is="xxx" (TODO: deprecate)
(p.type === NodeTypes.DIRECTIVE || if (p.type === NodeTypes.DIRECTIVE) {
return true
}
// is="vue:xxx" // is="vue:xxx"
(p.value && p.value.content.startsWith('vue:'))) if (p.value && p.value.content.startsWith('vue:')) {
return true
}
// in compat mode, any is usage is considered a component
if (
__COMPAT__ &&
checkCompatEnabled(
CompilerDeprecationTypes.IS_ON_ELEMENT,
context,
p.loc
) )
) {
return true
}
})
if (options.isNativeTag && !hasVIs) { if (options.isNativeTag && !hasVIs) {
if (!options.isNativeTag(tag)) tagType = ElementTypes.COMPONENT if (!options.isNativeTag(tag)) tagType = ElementTypes.COMPONENT
} else if ( } else if (

View File

@ -240,8 +240,11 @@ export function resolveComponentType(
if (!isExplicitDynamic && isProp.type === NodeTypes.ATTRIBUTE) { if (!isExplicitDynamic && isProp.type === NodeTypes.ATTRIBUTE) {
// <button is="vue:xxx"> // <button is="vue:xxx">
// if not <component>, only is value that starts with "vue:" will be // if not <component>, only is value that starts with "vue:" will be
// treated as component by the parse phase and reach here. // treated as component by the parse phase and reach here, unless it's
tag = isProp.value!.content.slice(4) // compat mode where all is values are considered components
tag = __COMPAT__
? isProp.value!.content.replace(/^vue:/, '')
: isProp.value!.content.slice(4)
} else { } else {
const exp = const exp =
isProp.type === NodeTypes.ATTRIBUTE isProp.type === NodeTypes.ATTRIBUTE