Vue3 Custom Components
Vue3 custom components use veaury to achieve interoperability between vue3 and react, ultimately exposing a React component to be compatible with existing custom React components.
Data
At the data (props) level, it is consistent with React custom components.
Events
In Vue3, you need to use defineEmit
to trigger custom events, and pass onXXXEvent
in Vue component tags to set up event listener functions. See the following sample for details.
Slots
In Vue3, you can use the <slot></slot>
tag to declare slots, and <slot name="xxx"></slot>
to define named slots. When using them, pass the vSlot
property to Vue components to embed components into corresponding slots. See the following sample for details.
Template
Using tcb lowcode create
can create the Vue3 template.
The following uses the sample component counter
in the template to demonstrate how to write WeDa custom components using Vue3.
React Component
When using Vue3 to write custom components, the ultimately exported component is also a React component. We first write a React component as a container to host the actual Vue3 component and perform parameter conversions within this component:
// index.tsx
import React from "react";
import { WedaVue3Wrapper } from '../../util';
import counter from "./counter.vue";
export default function CounterWithWrapper({ header, footer, ...props }) {
const vSlot = { header, footer };
return <WedaVue3Wrapper component={counter} vSlot={vSlot} {...props} />;
}
The project template provides the WedaVue3Wrapper
component to help developers more conveniently create Vue3 custom components. In the React component above, we pass the imported Vue3 component to the component
prop of WedaVue3Wrapper
.
In addition, we need to define slots as an object and pass it to the vSlot
prop. The keys in the vSlot
object correspond to the names of named slots in Vue components. For example, vSlot = { keyA: <div>i am a slot</div> }
corresponds to <slot name="keyA"></slot>
in the Vue component.
For anonymous slots, i.e., slots without a name attribute like <slot></slot>
, use default
as the key in the object, such as vSlot = { default: <div>i am a default slot</div> }
.
Vue Component
// counter.vue
<script setup>
import { ref, onUnmounted } from "vue";
const emit = defineEmits(["add", "minus"]);
const props = defineProps(["initialCount"]);
const count = ref(props.initialCount ?? 0);
function dec() {
count.value--;
emit("minus", { value: count.value });
}
function add() {
count.value++;
emit("add", { value: count.value });
}
</script>
<template>
<div>
<slot name="header"></slot>
<button @click="dec">minus</button>
<span>{{ count }}</span>
<button @click="add">add</button>
<slot name="footer"></slot>
</div>
</template>
Building WeDa custom components with Vue3 is no different from building a regular Vue3 component in terms of approach. Use defineProps
to declare the component's accepted props. Use defineEmits
to declare custom events and trigger them using the returned emit
function.
Note that Vue components' template must have a root node. The platform will pass in additional props beyond the defined ones for scenarios like injecting custom styles and classes, which will be passed through by Vue to the root node. For details, see Vue official documentation - Fallthrough Attributes.