Closed
Description
Edit by @yyx990803 : there are currently two JSX transform implementations for Vue 3 with slightly differing syntax (for Vue specific features). We are using this thread to unify the design and land on an official specification of how Vue features should be handled in JSX.
Babel JSX Transform [Github]
- patchFlags
- same as Vue 3 Compiler
- compatible with Vue 2.x
Syntax
Content
functional component
const App = () => <div></div>
with render
const App = {
render() {
return <div>Vue 3.0</div>
}
}
const App = defineComponent(() => {
const count = ref(0);
const inc = () => {
count.value++;
};
return () => (
<div onClick={inc}>
{count.value}
</div>
)
})
Fragment
const App = () => (
<>
<span>I'm</span>
<span>Fragment</span>
</>
)
Attributes/Props
const App = () => <input type="email" />
with a dynamic binding:
const placeholderText = 'email'
const App = () => (
<input
type="email"
placeholder={placeholderText}
/>
)
Directives
It is recommended to use camelCase version of it (
vModel
) in JSX, but you can use kebab-case too (v-model
).
v-show
const App = {
data() {
return { visible: true };
},
render() {
return <input vShow={this.visible} />;
},
};
v-model
- You should use underscore (
_
) instead of dot (.
) for modifiers (vModel_trim={this.test}
)
export default {
data: () => ({
test: 'Hello World',
}),
render() {
return (
<>
<input type="text" vModel_trim={this.test} />
{this.test}
</>
)
},
}
custom directive
const App = {
directives: { custom: customDirective },
setup() {
return () => (
<a
vCustom={{
value: 123,
arg: 'arg',
}}
/>
);
},
}
Activity
tangjinzhou commentedon Jul 3, 2020
Compatible with Vue2 should give a deprecated warning.
I prefer not to support in future, if compatible, we need to add runtime, performance will be lost.
tangjinzhou commentedon Jul 3, 2020
About slots,proposed API look like:
children has higher priority than
vSlots.default
or does not supportvSlots.default
.HcySunYang commentedon Jul 3, 2020
@Amour1688 Great job, in addition to the above, I have some same or different proposals:
Experimental project: vue-next-jsx
Unified syntax
Since
tsx
does not supportJSXNamespacedName
and the.
cannot appear in the attribute name, it is necessary to unify how to writedirectives
injsx
.Proposed syntax:
jsx
-
instead of:
_
instead of.
Examples
Note that: in Vue3, we use
v-model:foo
instead of:foo.sync
modifierpros
jsx
andtsx
cons
Restricted slot
Since the scoped slot is still manually built in the Vue2' jsx, so I propose the only way to provide slots for components is:
pros
v-slot="props"
resulting in type loss in tscons
KeepAlive And Teleport
In Vue3, the children of
KeepAlive
andTeleport
components will not be built as slots, so we need to handle it.Fragment
Although we don't must to support fragment in jsx plugin, because Vue3 will handle it automatically, but it does bring development convenience:
Optimization mode
Vue3 makes full use of compile-time information to generate PatchFlags for runtime update performance improvement, Maybe the jsx plugin can also do some similar work
Specify source
Some people install
vue
, but some install@vue/runtime-dom
, so this should be configurable:It affects the import statement:
v-html / v-text
In Typescript, we must use
domPropsInnerHTML
, if we supportv-html
it will be more friendly.tangjinzhou commentedon Jul 3, 2020
@HcySunYang
We should declare events instead of skipping the check. In fact,when the event is declared in the props, we can still trigger by emit.
I prefer the camel case.
tangjinzhou commentedon Jul 3, 2020
Directives
with a modifier:
with an argument:
with an argument and modifiers:
v-html:
If support modifiers, we can also declare it.
I am not familiar with ts, is there any other better way.
HcySunYang commentedon Jul 3, 2020
@tangjinzhou
In Typescript, if you do this:
will get an error:
This is because
onClick
is treated as a standard html attribute.In fact, users can still use
onClick
, but it is not allowed to add modifiers on it, if you want to add modifiers, please use:Amour1688 commentedon Jul 3, 2020
If it's possible to extend types.
v-on-click
It doesn't look good.I think use
props.onXX
may be a better methodtangjinzhou commentedon Jul 3, 2020
@HcySunYang
maybe we should try to resolve it. If skip the check, the effect of using ts will no longer exist.
We can declare it like react :
fgr-araujo commentedon Jul 3, 2020
Dots to separate is more readable. We know that dot is a layer inside something
Unserscore means compound names.
fgr-araujo commentedon Jul 3, 2020
I love to use dash in HTML but in JSX can be confused with a minus sign.
tangjinzhou commentedon Jul 3, 2020
We are now using the vueComponent/jsx to refactor ant-design-vue. I expect a smaller change cost, so I hope to be compatible with the syntax in vue2. Even if it may cause a performance loss, we should give the old project enough time to migrate.
sonicoder86 commentedon Jul 3, 2020
Why not use JSX as is and use event handlers like this?
I feel it more intuitive for devs coming with React background.
HcySunYang commentedon Jul 3, 2020
@BlackSonic, Of course, you can.
One of the purposes of the jsx plugin is to bring the convenience of the template, such as event modifiers, but this does not prevent you from directly using
onClick
.74 remaining items