Skip to main content

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.