Vue 自定义组件
Vue 自定义组件通过 vuera 来完成 vue2 和 react 的互交互,最终暴露出一个 React 组件来跟现有的 React 自定义源码组件兼容。
数据
数据(props)层面与 React 自定义组件一致,但是由于style
是 Vue 中的保留字,所以平台传入的 style 内联样式会通过styles
传入。
事件
与 React 自定义组件通过 events 传入不同,Vue 组件中通过this.$emit
触发自定义事件。
插槽
组件插槽机制在 Vue 中可以通过<slot></slot>
默认插槽获取 React children
<slot name="xxx"></slot>
获得具名插槽
模版
使用tcb lowcode create
可以创建vue模版
下面以模版中的示例组件counter
,来展示写法。
1)React 组件
首先创建组件的 config,并且导出相关的配置。自定义组件导出最终是个 React 组件。在 React 组件中通过@tcwd/vuera
提供的WedaVueWrapper
包装 Vue 组件并且导出。
import React from 'react';
import {WedaVueWrapper} from '@tcwd/vuera';
import counter from './counter.vue';
export default function Counter(props) {
return (
<WedaVueWrapper
component={counter}
{...props}
/>
);
}
WedaVueWrapper
的component
prop接收一个 Vue 组件。其他 props 可以透传提供给 Vue 组件获取。
2)Vue 组件
<template>
<div :id="id" :style="styles" :class="className">
<div class="counter-row">
<button class="counter-button" @click="minus">-</button>
<span class="counter-num">{{count}}</span>
<button class="counter-button" @click="add">+</button>
</div>
<div>
<slot name="innerSlot"></slot>
</div>
</div>
</template>
<script>
export default {
props: ['init', 'styles', 'className', 'id'],
methods: {
add() {
this.count++;
this.$emit('add', this.count);
},
minus() {
this.count--;
this.$emit('minus', this.count);
}
},
data() {
return {
count: this.init ?? 0,
};
},
watch: {
init: function(val) {
this.count = val;
}
}
}
</script>
<style>
.counter-row {
display: flex;
align-items: center;
}
.counter-num {
padding: 0 8px;
}
.counter-button {
display: inline-block;
padding-left: 0;
padding-right: 0;
padding-top: 0;
padding-bottom: 0;
margin: 0;
font-size: 14px;
width: 40px;
height: 40px;
border: none;
background-color: rgb(239, 239, 239);
}
</style>
Vue 组件中可以从 props 获得传入的属性。
和一般的 Vue 组件写法一致通过slot
获取 React 中的 children 和具名slot
获取 props 传入的JSX Element
,自定义事件通过this.$emit
触发。
但在微搭自定义组件中,与 React 自定义组件一样,有一些平台传入的 props 用于平台/用户设计态自定义的保留属性会固定传入比如id
,styles
(React 中为style
内联样式)和className
。他们会用在设计态和运行态注入自定义样式,class 等场景。同时编辑器会也会过这些属性来定位元素和显示编辑态提示所以需要在模版中进行绑定。
最后确认将组件正确导出即可。