组件运行时 JS 文件
组件运行时 JS 文件名为
- React 体系:“组件名.react.js”
- Vue 体系:“组件名.vue”
文件采用标准 ES6 语法,编写组件运行时的渲染逻辑及内容。
基础文件内容
在运行时 JS 文件中的 Render 方法实现组件渲染
- Render 方法中使用 React 语法
- return 的内容就是显示的内容,属性参考组件官网说明
- return 中的值变化后触发 Render 方法
React 体系文件内容
组件继承自 BaseComponent 类,引用运行时 CSS 文件,代码如下:
import React, { Fragment } from 'react';
import BaseComponent from 'components/pcx/BaseComponent';
import hoistNonReactStatic from 'hoist-non-react-statics';
import {组件名, 组件名2} from "antd";
import './css/组件名.css';
class 组件名Pro extends BaseComponent {
render() {
return <组件名 {...this.props}></组件名>
}
}
export default hoistNonReactStatic(组件名Pro, 组件名);
Vue 体系文件内容
使用 JSX 语法,代码如下:
<script setup lang="jsx">
import { 组件名 ,组件名2} from "ant-design-vue";
import { useAttrs, useSlots, reactive, watch, inject ,isVNode} from "vue";
import { commonProps, omitProps, useRefData, useUse, useFireEvent, usePage, useVisible, componentRenderWrapper} from "vue_addon/core";
let props = defineProps({
...commonProps
})
let emits = defineEmits([]);
let fireEvent = useFireEvent(emits);
let attrs = useAttrs();
let slots = useSlots();
let use = useUse(props);
let refData = useRefData(props);
let 组件名ProRender = () => {
let {...vSlots} = slots;
let omittedProps = omitProps(props, commonProps)
return <组件名 {...attrs} {...omittedProps} vSlots={vSlots}/>
};
</script>
<template>
<组件名ProRender />
</template>
引用组件
在运行时 JS 文件中,可以引用系统组件、基础组件和第三方组件
引用系统组件
使用”import 组件名 from 组件路径“引用系统组件
例如:引用“输入框”组件,代码如下
// React 桌面端
import Input from "../../../antdpro/components/Input/Input.react";
// Vue 桌面端
import Input from "../../../antdv/components/Input/Input.vue";
// React 移动端
import Field from "../../../vantui/components/Field/Field.react";
// Vue 移动端
import Field from "../../../vant/components/Field/Field.vue";
引用基础组件
引用 antd 的组件,注意引用的不是系统提供的组件,没有绑定数据组件的能力。
例如:引用“输入框”组件,代码如下
import {Input} from "antd";
import {Input} from "ant-design-vue";
引用第三方组件
第三方组件的 node_modules 放到命名空间的 lib 目录下后,即可引用,示例代码如下
import ReactECharts from 'echarts-for-react';
import * as echarts from 'echarts';
import { createComponent } from "echarts-for-vue";
React 体系 API
组件继承自 BaseComponent 类,BaseComponent 类提供以下 API
方法 | 参数 | 说明 |
---|---|---|
getRefData | 获取绑定数据集或者绑定数据列的数据组件对象 | |
getData | 数据集 ID | 通过数据集ID,获取数据组件对象 |
getRefValue | 获取绑定数据列的值 | |
setRefValue | 值 | 设置绑定数据列的值 |
getLabelRefValue | 获取绑定显示列的值 | |
setLabelRefValue | 值 | 设置绑定显示列的值 |
getUseProps | 获取引用组件的属性对象 | |
fireEvent | 事件名称、事件对象、默认行为 | 派发组件事件 |
getPage | 获取页面对象 |
获取组件属性
使用 this.props 获取组件的属性,示例代码如下
let { style, theme, externalThemeName, events } = this.props;
获取绑定数据组件对象
当组件定义了 bind:ref 或 bind:items 属性时,可通过 this.getRefData(); 方法,获取绑定数据集或绑定数据列对应的数据组件对象,方法定义如下
方法:
getRefData()
返回值:
数据组件对象
例如:“列表”组件的“绑定数据集”属性定义如下
{
"List": {
"properties": {
"bind:items": {
"type": "dataValue",
"editor": "dataValueEditor",
"label": "绑定数据集"
}
}
}
}
在运行时 JS 文件中获取数据集对象,代码如下
class ListPro extends BaseComponent {
render() {
//获取绑定的数据集对象
let data = this.getRefData();
//调用数据集的 toJson 方法
dataSource = data.toJson({ ui: true });
return <List {...this.props}></List>;
}
}
如果同时定义了 filter 过滤条件属性,代码如下
"filter": {
"type": "function",
"args": {
"record": {
"label": "行记录",
"editor": "rowEditor",
"editor-parameter": {
"dataPath": "@bind:items"
}
}
},
"editor-parameter": {
"isFilter": "false",
"isForeachFilter": "true"
},
"label": "过滤条件"
},
在运行时 JS 文件中,获取满足过滤条件的数据,代码如下
let dataObj = this.getRefData().toJson({ ui: true });
if(this.props.filter){
dataObj = dataObj.filter(this.props.filter);
}
获取数据组件对象
当组件设置了某个属性是数据集 ID 时,可通过 this.getData(数据集ID); 方法获取数据组件对象,方法定义如下
方法:
getData(dataId)
参数:
dataId:字符串类型,数据集ID
返回值:
数据组件对象
例如:“自动完成”组件定义搜索数据列,代码如下
{
"AutoComplete": {
"properties": {
"searchRef": {
"type": "dataRef",
"label": "搜索数据列",
"editor": "dataRef",
"visible-condition":"@mode='search'",
"required": "true"
}
}
}
}
在运行时 JS 文件中,通过搜索数据列属性,获取搜索数据集并刷新数据,代码如下
class AutoCompletePro extends BaseComponent {
onSearch(){
let searchData = this.getData(this.searchDataId);
searchData.refreshData();
}
render() {
let props = this.props;
if(this.mode === "search" && props['searchRef'] && props['suggestDataRef']){
let [searchDataId,,searchDataColumn] = props['searchRef'].split(".");
this.searchDataId = searchDataId;
this.searchDataColumn = searchDataColumn;
}
let {options,...restProps} = this.props;
return
return <AutoComplete >
<Input.Search onSearch={()=>{this.onSearch()}} />
</AutoComplete>
}
}
获取绑定数据列的值
当组件定义了 bind:ref 属性时,可通过 this.getRefValue(); 方法获取绑定数据列的值,方法定义如下
方法:
getRefValue(serialize)
参数:
serialize:布尔类型,日期类型是否序列化为字符串,默认是 false
返回值:
值
例如:“滑动输入条”组件定义绑定数据列,代码如下
{
"Slider": {
"properties": {
"bind:ref": {
"type": "dataRef",
"label": "绑定数据列",
"required": "true"
}
}
}
}
在运行时 JS 文件中,获取绑定数据列的值,代码如下
class SliderPro extends BaseComponent {
handleChange = (value) => {
this.fireEvent("onChange", value, () => {
this.setRefValue(value);
})
}
render() {
let { value, ...others } = this.props;
value = this.getRefValue();
return <Slider {...others} value={value} onChange={this.handleChange} />
}
}
设置绑定数据列的值
当组件定义了 bind:ref 属性时,可通过 this.setRefValue(); 设置绑定数据列的值,方法定义如下
方法:
setRefValue(value)
参数:
value:设置的值
例如:“滑动输入条”组件定义绑定数据列,代码如下
{
"Slider": {
"properties": {
"bind:ref": {
"type": "dataRef",
"label": "绑定数据列",
"required": "true"
}
}
}
}
在运行时 JS 文件中,设置绑定数据列的值,代码如下
class SliderPro extends BaseComponent {
handleChange = (value) => {
this.fireEvent("onChange", value, () => {
this.setRefValue(value);
})
}
render() {
let { value, ...others } = this.props;
value = this.getRefValue();
return <Slider {...others} value={value} onChange={this.handleChange} />
}
}
获取绑定显示列的值
当组件定义了 bind:labelRef 属性时,可通过 this.getLabelRefValue(); 获取绑定显示列的值,方法定义如下
方法:
getLabelRefValue(serialize)
参数:
serialize:布尔类型,日期类型是否序列化为字符串,默认是false
返回值:
值
例如:“选择器”组件定义绑定显示列,代码如下
{
"Select": {
"properties": {
"dataGroup": {
"label": "数据绑定",
"properties": {
"bind:labelRef": {
"type": "dataRef",
"label": "绑定显示列"
}
}
}
}
}
}
在运行时 JS 文件中,获取绑定显示列的值,代码如下
class SelectPro extends BaseComponent {
constructor(props, context) {
super(props, context);
this.refData = this.getRefData();
this.state = {
value: this.getRefValue(),
labelValue: this.getLabelRefValue()
}
}
handleChange = (value, options) => {
this.fireEvent("onChange", [value, options], () => {
this.setRefValue(options?.value)
this.setLabelRefValue(options?.label)
})
}
render() {
let { options, popupMatchSelectWidth = false, ...other } = this.props;
let value = this.state.value;
let label = this.state.labelValue;
if (this.props.labelRefDataId) {
let obj = {};
(value != null && value !== '') && (obj.value = value);
(label != null && label !== '') && (obj.label = label);
if (Object.keys(obj).length > 0) {
other.value = obj;
}
} else {
(value != null && value !== '') && (other.value = value);
}
return <Select {...other} onChange={this.handleChange} onSelect={this.handleSelect}
/>;
}
}
设置绑定显示列的值
当组件定义了 bind:labelRef 属性时,可通过 this.setLabelRefValue(); 设置绑定显示列的值
方法:
setLabelRefValue(value)
参数:
value:设置的值
例如:“选择器”组件定义绑定显示列,代码如下
{
"Select": {
"properties": {
"dataGroup": {
"label": "数据绑定",
"properties": {
"bind:labelRef": {
"type": "dataRef",
"label": "绑定显示列"
}
}
}
}
}
}
在运行时 JS 文件中,设置绑定显示列的值,代码如下
class SelectPro extends BaseComponent {
constructor(props, context) {
super(props, context);
this.refData = this.getRefData();
this.state = {
value: this.getRefValue(),
labelValue: this.getLabelRefValue()
}
}
handleChange = (value, options) => {
this.fireEvent("onChange", [value, options], () => {
this.setRefValue(options?.value)
this.setLabelRefValue(options?.label)
})
}
render() {
let { options, popupMatchSelectWidth = false, ...other } = this.props;
let value = this.state.value;
let label = this.state.labelValue;
if (this.props.labelRefDataId) {
let obj = {};
(value != null && value !== '') && (obj.value = value);
(label != null && label !== '') && (obj.label = label);
if (Object.keys(obj).length > 0) {
other.value = obj;
}
} else {
(value != null && value !== '') && (other.value = value);
}
return <Select {...other} onChange={this.handleChange} onSelect={this.handleSelect}
/>;
}
}
获取引用组件的属性对象
当组件元信息引用了其他组件时,可通过 this.getUseProps(); 获取引用组件的属性对象,方法定义如下
方法:
getUseProps(componentName, key, defaultValue)
参数:
componentName:字符串类型,组件名
key:字符串类型,在元信息文件中 uses 时定义的 key
defaultValue:对象类型,默认值
返回值:
对象类型,引用组件的属性对象
例如:“气泡确认框”组件元信息文件引用“文字提示”组件,设置 key 为 tooltip,代码如下
{
"Popconfirm":{
"uses": {
"tooltip": {
"label": "提示配置",
"key": "tooltip",
"componentName": "antdpro:Tooltip",
"editor-parameter": {
"ignore-properties": [
"title"
]
}
}
}
}
}
在运行时 JS 文件中获取引用组件 tooltip 的属性对象,代码如下
this.getUseProps("Tooltip","tooltip")
派发组件事件
在组件元信息文件中定义的事件,在运行时 JS 文件中调用 fireEvent 方法派发事件,方法定义如下
方法:
fireEvent(eventName, event, defaultAction)
参数:
eventName:字符串类型,事件名
event:Event对象,事件对象
defaultAction:函数类型,默认行为
例如:“分段控制器”组件定义了 onChange 事件,代码如下
{
"Segmented": {
"events": {
"onChange": {
"label": "选项变化",
"data": [
{
"label": "选项值",
"name": "value"
}
]
}
}
}
}
在运行时 JS 文件中,派发 onChange 事件,代码如下
class SegmentedPro extends BaseComponent {
handleChange = (value) => {
this.fireEvent("onChange", value, () => {
this.setRefValue(value);
});
}
render() {
return <Segmented {...this.props} onChange={this.handleChange} />
}
}
创建事件对象
在派发事件前,通过 CustomEvent 创建事件对象,用于定义事件参数,方法定义如下
方法:
CustomEvent(eventName, eventParams)
参数:
eventName:字符串类型,事件名
eventParams:事件参数,格式如下
{
cancelable: true,//是否允许使用代码 event.preventDefault() 阻止默认行为
detail: {//作为 event.detail 参数
option: option
}
}
返回值:
事件对象
例如:“图表”组件定义了 onBeforeSetOption 事件,用于开发者修改 option,代码如下
{
"Echarts": {
"events": {
"onBeforeSetOption": {
"label": "显示前",
"data": [
"event"
],
"option": {
}
}
}
}
}
在运行时 JS 文件中,提供开发者修改 option 的时机,代码如下
- 创建事件对象,将 option 作为事件参数
- 开发者在页面的组件事件中,通过 event.detail.option 获取并修改
- 在 fireEvent 的默认行为中,将开发者设置的 option 写回组件内部
let beforeSetOptionEvent = new CustomEvent("onBeforeSetOption", {
cancelable: true,
detail: {
option: option
}
});
this.fireEvent("onBeforeSetOption", beforeSetOptionEvent, () => {
option = beforeSetOptionEvent.detail.option;
});
获取页面对象
获取页面对象,从而获取配置上下文对象 configContext,调用 request 方法,方法定义如下
方法:
getPage()
返回值
页面对象
例如:“签名”组件中调用页面对象的 request 方法获取个人签名,代码如下
this.getPage().request({
method: "GET",
url,
header: {
},
datatype: "json",
success: (result = {}) => {
if (result && result.data) {
resolve(result && result.data.signature || null);
} else {
reject()
throw new Error(msg);
}
},
error: (result = {}) => {
reject(result)
throw new Error(msg);
},
complete: (result = {}) => {
}
});
例如:“图表”组件获取页面对象中的配置上下文对象 configContext,代码如下
if (this.getPage().getCurrentTheme()) {//没有设置主题,根据门户皮肤,自动设置使用深色模式或浅色模式
let colorTextBase = this.getPage().getCurrentTheme().token?.colorTextBase;
let colorBgBase = this.getPage().getCurrentTheme().token?.colorBgBase;
if (colorTextBase && !this.isDarkColor(colorTextBase) && colorBgBase && this.isDarkColor(colorBgBase)) {
themeName = "dark";
}
}
Vue 体系 API
组件通过引入 vue_addon/core 文件来获取 React 体系中对应的 Api。
import { useRefData, useUse, useFireEvent, usePage, } from "vue_addon/core";
方法 | 参数 | 说明 |
---|---|---|
useRefData | 获取绑定数据集或者绑定数据列的数据组件对象 | |
useData | 数据集 ID | 通过数据集ID,获取数据组件对象 |
useUse | 获取引用组件的属性对象 | |
useFireEvent | 事件名称、事件对象、默认行为 | 派发组件事件 |
usePage | 获取页面对象 |
通过 useRefData 或 useData 方法获取的数据组件对象,提供下面4个方法
方法 | 参数 | 说明 |
---|---|---|
getRefValue | 获取绑定数据列的值 | |
setRefValue | 值 | 设置绑定数据列的值 |
getLabelRefValue | 获取绑定显示列的值 | |
setLabelRefValue | 值 | 设置绑定显示列的值 |
获取组件属性
组件的属性定义在组件元信息文件中,属性分成两部分,一部分在 JS 中使用,使用后可传给组件,另一部分直接传给组件
- 通过 defineProps 方法获取指定的组件属性,在 JS 文件中使用
- 通过 useAttrs 方法获取其他属性,在 render 方法中直接传给组件
- 对于在 defineProps 方法中加入的通用属性 commonProps,使用 omitProps 方法排除 commonProps 后,在 render 方法中传给组件使用。之所以需要排除是因为 Vue 对于多余的属性会输出警告
- 通用属性 commonProps 有两个作用,一是将系统数据绑定属性拆分成3个属性,便于在 JS 文件中使用;二是一些通用属性无需定义。了解 commonProps 中的属性,参考 /tools/uix-web/vue_addon/core/utils.js 文件
- bind:ref 拆分为 refDataId、refColumnName、refRow
- bind:labelRef 拆分为 labelRefDataId、labelRefColumnName、labelRefRow
- bind:items 无需定义,直接使用 items
- bind:options 无需定义,直接使用 options,另外还提供了一个 optionsRefDataId 属性
- optionsLabel 无需定义,直接使用 optionsLabel
- optionsValue 无需定义,直接使用 optionsValue
//获取指定的属性和通用属性
let props = defineProps({
text: {type: String},
icon: {type: [Object, String]},
iconPosition: {type: String},
displayMode: {type: String},
opLabel: {type: String},
opIcon: {type: String},
iconStyle: {type: Object},
href: {type: String},
...commonProps
})
//获取其它属性
let attrs = useAttrs();
//获取指定属性中一部分属性
let {text, icon, iconPosition, displayMode, iconStyle, href, ...other} = props;
//从这一部分属性中排除通用属性
let omittedProps = omitProps(other, commonProps)
//将其它属性和排除后的属性传给组件
return <Button {...attrs} {...omittedProps}>{icon}</Button>
使用 defineProps 方法获取组件的属性
方法:
defineProps({
xxx: {type: xxx, default: xxx},
...commonProps})
参数:
JSON 对象,key 是组件的属性名,value 是 JSON 对象,里面指定了组件属性的类型 type 和默认值 default。加入 commonProps 后,系统内置属性:bind:items、bind:ref、bind:options 无需定义
返回值:
指定的属性和通用的属性
例如:在 Echarts 组件元信息文件中定义了 option、dataConfig、theme、bind:items、filter、events 等属性,使用 defineProps 方法获取组件的属性,加入了 commonProps,因此无需定义 bind:items,直接使用 items 即可,代码如下
import { commonProps, usePage, useRefData, useFireEvent } from "vue_addon/core";
let props = defineProps({
option: { type: String },
dataConfig: { type: String },
theme: { type: String },
filter: { type: Function },
events: { type: String },
...commonProps
})
let { option, dataConfig, ...other } = props;
获取绑定数据组件对象
当组件有定义了 bind:ref 或 bind:items 属性时,可通过 useRefData(); 方法获取绑定数据集或者绑定数据列的数据组件对象,方法定义如下
方法:
useRefData(props)
参数:
props:组件的属性,通过 defineProps 方法获取的组件的属性
返回值:
数据组件对象
例如:“列表”组件的“绑定数据集”属性定义如下
{
"List": {
"properties": {
"bind:items": {
"type": "dataValue",
"editor": "dataValueEditor",
"label": "绑定数据集"
}
}
}
}
在运行时 JS 文件中获取数据集对象,代码如下
<script setup lang="jsx">
import { Fragment, cloneVNode, useAttrs, useSlots, withDirectives } from "vue";
import { useRefData, omitProps, useFireEvent, commonProps, useUse, usePage } from "vue_addon/core";
let props = defineProps({
...commonProps,
});
let refData = useRefData(props);
let ListProRender = () => {
let { pureLoop, dataSource, loadMoreType, showEmpty, ...others } = props;
let _slots = { ...slots };
if (refData) {
dataSource = refData.toJson({ ui: true }) || [];
return (
<List
{...attrs}
{...omittedProps}
dataSource={dataSource}
rowKey={rowKey}
pagination={false}
vSlots={_slots}
></List>
);
}
};
</script>
<template>
<ListProRender />
</template>
如果同时定义了 filter 过滤条件属性,代码如下
"filter": {
"type": "function",
"args": {
"record": {
"label": "行记录",
"editor": "rowEditor",
"editor-parameter": {
"dataPath": "@bind:items"
}
}
},
"editor-parameter": {
"isFilter": "false",
"isForeachFilter": "true"
},
"label": "过滤条件"
},
在运行时 JS 文件中,获取满足过滤条件的数据,代码如下
let props = defineProps({
option: { type: String },
filter: { type: Function },
dataConfig: { type: String },
events: { type: String },
theme: { type: String },
...commonProps
})
let refData = useRefData(props);
let processDataSourceFilter = (filter, dataSource) => {
if (typeof filter == "function") {
dataSource = dataSource.filter(filter);
}
return dataSource;
}
let dataObj = refData.toJson({ ui: true });
dataObj = processDataSourceFilter(props.filter, dataObj);
获取数据组件对象
当组件设置了某个属性是数据集 ID 时,可通过 useData(数据集ID); 方法获取数据组件对象,方法定义如下
方法:
useData(dataId)
参数:
dataId:字符串类型,数据集ID
返回值:
数据组件对象
例如:“自动完成”组件定义搜索数据列,代码如下
{
"AutoComplete": {
"properties": {
"searchRef": {
"type": "dataRef",
"label": "搜索数据列",
"editor": "dataRef",
"visible-condition":"@mode='search'",
"required": "true"
}
}
}
}
在运行时 JS 文件中,通过搜索数据列属性,获取搜索数据集并刷新数据,代码如下
<script setup lang="jsx">
import {AutoComplete,Pagination,Button,Input} from 'ant-design-vue';
import {SearchOutlined} from '@ant-design/icons-vue';
import {Fragment, reactive, useAttrs, useSlots} from "vue";
import {commonProps,omitProps ,useRefData, useUse, useFireEvent,useData} from "vue_addon/core";
/**
* 支持2种模式
*
* 1. 提示输入后搜索模式 search 最要使用场景
* 2 提示输入后录入模式 input
* 3. 原本自动完成的模式
*/
let props = defineProps({
...commonProps,
mode: {
type: String
},
searchRef: {
type: String
},
})
let searchDataId,searchDataColumn,suggestDataId,suggestDataMatchColumn;
if(props.mode === "search" && props['searchRef'] && props['suggestDataRef']){
let [_searchDataId,,_searchDataColumn] = props['searchRef'].split(".");
searchDataId = _searchDataId;
searchDataColumn = _searchDataColumn;
}
let searchData = useData(searchDataId);
let onSearch = ()=>{
searchData.refreshData();
}
let AutoCompleteProRender = ()=>{
let {options,...restProps} = props;
//根据mode自动决定子节点
let children,childProps ;
if(props.mode == "search"){
childProps = use.getProps("Input",'search');
let btnProps = use.getProps("Button",'search-btn');
children = <Input {...childProps} />;
let omittedProps = omitProps(restProps, commonProps)
return <><AutoComplete
{...attrs}
vSlots={slots}
{...omittedProps}
onChange={(value)=>{
state.searchValue = value;
}}
options={options}>
{children}
</AutoComplete>
<Button type="primary" icon={<SearchOutlined onClick={()=>{onSearch()}}/>} {...btnProps}></Button>
</>
}
}
</script>
<template>
<AutoCompleteProRender/>
</template>
获取绑定数据列的值
当组件定义了 bind:ref 属性时,可通过 data.getRefValue(); 方法获取绑定数据列的值,data 是通过 useRefData 或 useData 方法获取的数据组件对象,方法定义如下
方法:
data.getRefValue()
返回值:
值
例如:“滑动输入条”组件定义绑定数据列,代码如下
{
"Slider": {
"properties": {
"bind:ref": {
"type": "dataRef",
"label": "绑定数据列",
"required": "true"
}
}
}
}
在运行时 JS 文件中,获取绑定数据列的值,代码如下
<script setup lang="jsx">
import {Slider} from 'ant-design-vue';
import {useAttrs, useSlots} from "vue";
import {commonProps, useRefData,omitProps, useUse, useFireEvent} from "vue_addon/core";
let props = defineProps({
...commonProps,
})
let emits = defineEmits(['change']);
let fireEvent = useFireEvent(emits);
let refData = useRefData(props);
let handleChange = (value) => {
fireEvent("change", value, () => {
if(props.range){
value = value.join(",")
}
refData?.setRefValue(value);
})
}
let SliderProRender = ()=>{
let { value, range, ...others } = props;
value = refData?.getRefValue() || value;
return <Slider {...attrs} {...omittedProps} range={range} value={value} onChange={handleChange} vSlots={slots}/>
}
</script>
<template>
<SliderProRender/>
</template>
设置绑定数据列的值
当组件定义了 bind:ref 属性时,可通过 data.setRefValue(); 设置绑定数据列的值,data 是通过 useRefData 或 useData 方法获取的数据组件对象,方法定义如下
方法:
data.setRefValue(value)
参数:
value:设置的值
例如:“滑动输入条”组件定义绑定数据列,代码如下
{
"Slider": {
"properties": {
"bind:ref": {
"type": "dataRef",
"label": "绑定数据列",
"required": "true"
}
}
}
}
在运行时 JS 文件中,设置绑定数据列的值,代码如下
<script setup lang="jsx">
import {Slider} from 'ant-design-vue';
import {useAttrs, useSlots} from "vue";
import {commonProps, useRefData,omitProps, useUse, useFireEvent} from "vue_addon/core";
let props = defineProps({
...commonProps,
})
let emits = defineEmits(['change']);
let fireEvent = useFireEvent(emits);
let refData = useRefData(props);
let handleChange = (value) => {
fireEvent("change", value, () => {
if(props.range){
value = value.join(",")
}
refData?.setRefValue(value);
})
}
let SliderProRender = ()=>{
let { value, range, ...others } = props;
value = refData?.getRefValue() || value;
return <Slider {...attrs} {...omittedProps} range={range} value={value} onChange={handleChange} vSlots={slots}/>
}
</script>
<template>
<SliderProRender/>
</template>
获取绑定显示列的值
当组件定义了 bind:labelRef 属性时,可通过 data.getLabelRefValue(); 获取绑定显示列的值,方法定义如下
方法:
data.getLabelRefValue()
返回值:
值
例如:“选择器”组件定义绑定显示列,代码如下
{
"Select": {
"properties": {
"dataGroup": {
"label": "数据绑定",
"properties": {
"bind:labelRef": {
"type": "dataRef",
"label": "绑定显示列"
}
}
}
}
}
}
在运行时 JS 文件中,获取绑定显示列的值,代码如下
let use = useUse(props);
let refData = useRefData(props);
let optionsData = useData(props.optionsRefDataId);
let state = reactive({
value: refData.getRefValue(),
labelValue: refData.getLabelRefValue(),
});
设置绑定显示列的值
当组件定义了 bind:labelRef 属性时,可通过 data.setLabelRefValue(); 设置绑定显示列的值
方法:
data.setLabelRefValue(value)
参数:
value:设置的值
例如:“选择器”组件定义绑定显示列,代码如下
{
"Select": {
"properties": {
"dataGroup": {
"label": "数据绑定",
"properties": {
"bind:labelRef": {
"type": "dataRef",
"label": "绑定显示列"
}
}
}
}
}
}
在运行时 JS 文件中,设置绑定显示列的值,代码如下
let refData = useRefData(props);
let handleChange = (value, options) => {
fireEvent("change", [value, options], () => {
if (props.mode == "multiple" || props.mode == "tags") {
if (value.length > 0) {
refData.setRefValue(value.join(","));
refData.setLabelRefValue(options.map((item) => item.label).join(","));
} else {
refData.setRefValue(null);
refData.setLabelRefValue(null);
}
} else {
refData.setRefValue(options?.value);
refData.setLabelRefValue(options?.label);
}
});
};
获取引用组件的属性对象
当组件元信息引用了其他组件时,可通过 useUse(props).getProps(); 获取引用组件的属性对象,方法定义如下
方法:
useUse(props).getProps(componentName, key, defaultValue)
参数:
props:组件的属性,通过 defineProps 方法获取的组件的属性
componentName:字符串类型,组件名
key:字符串类型,在元信息文件中 uses 时定义的 key
defaultValue:对象类型,默认值
返回值:
对象类型,引用组件的属性对象
例如:“气泡确认框”组件引用“文字提示”组件,设置 key 为 tooltip,代码如下
{
"Popconfirm": {
"uses": {
"tooltip": {
"label": "提示配置",
"key": "tooltip",
"componentName": "antdv:Tooltip",
"editor-parameter": {
"ignore-properties": [
"title"
],
"ignore-events": []
}
}
}
}
}
在运行时 JS 文件中获取引用组件 tooltip 的属性对象,代码如下
<script setup lang="jsx">
import {Popconfirm} from 'ant-design-vue';
import {commonProps,useRefData,useUse,omitProps} from "vue_addon/core";
let use = useUse(props);
let PopconfirmProRender = () => {
let {cancelButtonProps={},okButtonProps={},...other} = props;
Object.assign(other, use.getProps("Tooltip", 'tooltip', null));
let omittedProps = omitProps(other, commonProps)
return <Popconfirm {...attrs} {...omittedProps} vSlots={slots} />
}
</script>
<template>
<PopconfirmProRender/>
</template>
派发组件事件
在组件元信息文件中定义的事件,在运行时 JS 文件中调用 useFireEvent 方法派发事件,方法定义如下
方法:
let emits = defineEmits([]);
useFireEvent(emits)(eventName, event, defaultAction);
参数:
eventName:字符串类型,事件名
event:Event对象,事件对象
defaultAction:函数类型,默认行为
例如:“分段控制器”组件定义了 onChange 事件,代码如下
{
"Segmented": {
"events": {
"onChange": {
"label": "选项变化",
"data": [
{
"label": "选项值",
"name": "value"
}
]
}
}
}
}
在运行时 JS 文件中,派发 onChange 事件,代码如下
<script setup lang="jsx">
import { Segmented } from "ant-design-vue";
import { useAttrs, useSlots, reactive, watch } from "vue";
import { commonProps, useRefData, omitProps, useData, useFireEvent } from "vue_addon/core";
let emits = defineEmits(["change"]);
let fireEvent = useFireEvent(emits);
let handleChange = (value) => {
fireEvent("change", value, () => {
refData.setRefValue(value);
});
};
let SegmentedProRender = () => {
let { ...vSlots } = slots;
let omittedProps = omitProps(props, commonProps);
return (
<Segmented
{...attrs}
{...omittedProps}
vSlots={vSlots}
onChange={handleChange}
/>
);
};
</script>
<template>
<SegmentedProRender />
</template>
创建事件对象
在派发事件前,通过 CustomEvent 创建事件对象,用于定义事件参数,方法定义如下
方法:
CustomEvent(eventName, eventParams)
参数:
eventName:字符串类型,事件名
eventParams:事件参数,格式如下
{
cancelable: true,//是否允许使用代码 event.preventDefault() 阻止默认行为
detail: {//作为 event.detail 参数
option: option
}
}
返回值:
事件对象
例如:“图表”组件定义了 onBeforeSetOption 事件,用于开发者修改 option,代码如下
{
"Echarts": {
"events": {
"onBeforeSetOption": {
"label": "显示前",
"data": [
"event"
],
"option": {
}
}
}
}
}
在运行时 JS 文件中,提供开发者修改 option 的时机,代码如下
- 创建事件对象,将 option 作为事件参数
- 开发者在页面的组件事件中,通过 event.detail.option 获取并修改
- 在 fireEvent 的默认行为中,将开发者设置的 option 写回组件内部
import { commonProps, usePage, useRefData, useFireEvent } from "vue_addon/core";
let emits = defineEmits(['beforeSetOption']);
let fireEvent = useFireEvent(emits);
let event = new CustomEvent("onBeforeSetOption", {
cancelable: true,
detail: { option: option }
});
fireEvent("beforeSetOption", event, () => {
option = event.detail.option;
})
获取页面对象
获取页面对象,从而获取配置上下文对象 configContext,调用 request 方法,方法定义如下
方法:
usePage()
返回值:
页面对象
例如:“签名”组件中调用页面对象的 request 方法获取个人签名,代码如下
<script setup lang="jsx">
let $page = usePage();
let loadPersonSign = async (event) => {
if (props.disabled) return;
let sign = await getPersonSign();
refData.setRefValue(sign);
};
let _personSign = undefined;
let getPersonSign = async () => {
if (_personSign !== undefined) {
return _personSign;
}
var personId = await getPersonId();
var msg = i18n("加载个人签名出错");
if (personId) {
var url = "/entry/uaa/Users/" + personId + "?extInfo=true";
_personSign = await new Promise((resolve, reject) => {
$page.request({
method: "GET",
url,
header: {},
datatype: "json",
success: (result = {}) => {
if (result && result.data) {
resolve((result && result.data.signature) || null);
} else {
reject();
throw new Error(msg);
}
},
error: (result = {}) => {
reject(result);
throw new Error(msg);
},
complete: (result = {}) => {},
});
});
}
return _personSign;
};
defineExpose({});
</script>
<template>
<SignatureProRender />
</template>
例如:“图表”组件获取页面对象中的配置上下文对象 configContext,代码如下
if ($page.props.configContext) {//没有设置主题,根据门户皮肤,自动设置使用深色模式或浅色模式
let colorTextBase = $page.props.configContext?.theme?.token?.colorTextBase;
let colorBgBase = $page.props.configContext?.theme?.token?.colorBgBase;
if (colorTextBase && !isDarkColor(colorTextBase) && colorBgBase && isDarkColor(colorBgBase)) {
themeName = "dark";
}
}
暴露操作和方法
在运行时 JS 文件中定义的方法,通过 defineExpose 方法向外暴露后,在页面的 JS 文件中方可调用。方法定义如下
方法:
defineExpose({methodName})
参数:
methodName:在运行时 JS 文件中定义的方法的方法名
例如:“对话框”组件的运行时 JS 文件中定义了 open 和 close 方法,用于打开和关闭对话框,并向外暴露,代码如下
let open = (config) => {
state.controlledProps = without(state.controlledProps,"open");
let src = config?.src;
let params = config?.params;
if (src) {
state.controlledProps = without(state.controlledProps,"pagePath");
state.pagePath = src;
}
if(params){
state.controlledProps = without(state.controlledProps,"params");
state.params = params;
}
let event = new CustomEvent("onOpen", {
cancelable: true,
detail: {pagePath: state.pagePath, params: state.params}
});
fireEvent("open", event, () => {
state.pagePath = event.detail.pagePath;
state.params = event.detail.params;
state.open = true;
state.modal = config?.modal || {};
})
}
let close = (event) => {
event = event || new CustomEvent("onClose", {
cancelable: true
})
fireEvent("close", event, () => {
state.open = false;
});
}
defineExpose({
open,
close
})
例如:系统在 /tools/uix-web/vue_addon/core/use/useComp.js 文件的 useVisible 方法中定义了 show 和 hide 两个方法,用于显示和隐藏。“抽屉”组件调用 useVisible 方法获取 show 和 hide 两个方法,并向外暴露,代码如下
let [state, exposeInfo] = useVisible({ props, propName: "open" });
defineExpose(exposeInfo);
获取插槽
在组件设计时定义的插槽,通过 useSlots 方法获取。方法定义如下
方法:
useSlots()
返回值:
插槽
例如:“按钮”组件获取插槽,显示插槽,代码如下
import {useAttrs, useSlots, h} from "vue";
let slots = useSlots();
let ButtonProRender = () => {
return (
<Button {...attrs} {...omittedProps}>
{text || slots}
</Button>
);
};