正文
, {
class
: [
'foo'
,
'bar'
],
style
: {
margin
:
'10px'
}
attrs: {
id
:
'foo'
},
on
: {
click
: foo }
})
可以看到vue会将传入的属性做一个分类,会分为
class
、
style
、
attrs
、
on
等不同部分。这样做非常繁琐,也不好处理。
在vue 3.0中跟react更加相似,会转成这样:
h('div', {
class: ['foo', 'bar'],
style: { margin: '10px' }
id: 'foo',
onClick: foo
})
基本上是传入什么就是什么,没有做额外的处理。
当然和
React.createElement
相比也有一些区别:
-
子节点不会作为以
children
这个名字在
props
中传入,而是通过
slots
去取,这个下文会做说明。
-
多个子节点是以数组的形式传入,而不是像React那样作为分开的参数
所以只能自己动手来实现这个插件,我是在babel-plugin-transform-react-jsx的基础上修改的,并且自动注入了
h
方法。
实际使用
在上面的工作完成以后,我们可以真正开始做开发了。
渲染子节点
上文说到,子节点不会像React那样作为
children
这个
prop
传递,而是要通过
slots
去取:
例如实现一个Button组件
// button.tsx
import { defineComponent } from 'vue';
import './style.less';
interface ButtonProps {
type: 'primary' | 'dashed' | 'link'
}
const Button = defineComponent({
setup(props: ButtonProps, { slots }) {
return () => (
<button class={'btn', `btn-${props.type}`}>
{slots.default()}
button>
)
}
})
export default Button;
然后我们就可以使用它了:
import { createApp } from 'vue';
import Button from './button';
// vue 3.0也支持函数组件
const App = () => <Button>Click Me!Button>
createApp().mount(App, '#app');
Reactive
配合vue 3.0提供的
reactive
,不需要主动通知Vue更新视图,直接更新数据即可。