feat: support casting plain element to component via is="vue:xxx"

In Vue 3's custom elements interop, we no longer process `is` usage on
known native elements as component casting. (ref:
https://v3.vuejs.org/guide/migration/custom-elements-interop.html)
This introduced the need for `v-is`. However, since it is a directive,
its value is considered a JavaScript expression. This makes it awkward
to use (e.g. `v-is="'foo'"`) when majority of casting is non-dynamic,
and also hinders static analysis when casting to built-in Vue
components, e.g. transition-group.

This commit adds the ability to cast a native element to a Vue component
by simply adding a `vue:` prefix:

```html
<button is="vue:my-button"></button>
<ul is="vue:transition-group" tag="ul"></ul>
```
This commit is contained in:
Evan You
2021-04-12 13:07:59 -04:00
parent 422b13e798
commit af9e6999e1
2 changed files with 30 additions and 15 deletions

View File

@@ -488,7 +488,12 @@ function parseTag(
const options = context.options
if (!context.inVPre && !options.isCustomElement(tag)) {
const hasVIs = props.some(
p => p.type === NodeTypes.DIRECTIVE && p.name === 'is'
p =>
p.name === 'is' &&
// v-is="xxx" (TODO: deprecate)
(p.type === NodeTypes.DIRECTIVE ||
// is="vue:xxx"
(p.value && p.value.content.startsWith('vue:')))
)
if (options.isNativeTag && !hasVIs) {
if (!options.isNativeTag(tag)) tagType = ElementTypes.COMPONENT