diff --git a/CHANGELOG.md b/CHANGELOG.md
index e4ac9164039f75c6eb2a033daa73f440af5630a3..06bf6ec5b45e2988a8b75e1c0ffc6a9b1e10de9f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -44,6 +44,8 @@
- 新增树部件加载更多和节点绘制器
- 标签编辑器支持转化为代码项文本
- 表单视图消息支持直接内容展示,无效配置为对象格式
+- 新增加载更多按钮,用于多数据、卡片加载更多模式使用
+- 编辑表单支持分组锚点、表单项锚点,锚点位置支持右侧中间、右上角、右下角
### Change
@@ -85,6 +87,8 @@
- 优化搜索栏组件样式,不直接使用基础css变量,组件定义专属变量
- 统一处理界面行为按钮按钮类型、按钮行为级别、按钮样式
- 优化多数据选择编辑器的呈现样式
+- 多数据、卡片通用逻辑提取,支持滚动加载loading、加载完成提示、分组锚点
+- 多数据、卡片变量样式规范调整,部件统一使用useListRender
### Fixed
diff --git a/src/common/add-more/add-more.scss b/src/common/add-more/add-more.scss
new file mode 100644
index 0000000000000000000000000000000000000000..eee6a2efc7dc37320f9ddb931078e37bdb008c89
--- /dev/null
+++ b/src/common/add-more/add-more.scss
@@ -0,0 +1,14 @@
+$add-more: (
+ color-bg: getCssVar(color, fill, 0),
+ color-text: getCssVar(color, primary),
+);
+@include b('add-more') {
+ @include set-component-css-var('add-more', $add-more);
+ width: 100%;
+ .van-button {
+ width: 100%;
+ border: none;
+ background-color: getCssVar(add-more, color-bg);
+ color: getCssVar(add-more, color-text);
+ }
+}
diff --git a/src/common/add-more/add-more.tsx b/src/common/add-more/add-more.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..9721ea58c3fb76a510ea37f2b170fe1104684134
--- /dev/null
+++ b/src/common/add-more/add-more.tsx
@@ -0,0 +1,20 @@
+import { defineComponent } from 'vue';
+import { useNamespace } from '@ibiz-template/vue3-util';
+import './add-more.scss';
+
+export const IBizAddMore = defineComponent({
+ name: 'IBizAddMore',
+ setup() {
+ const ns = useNamespace('add-more');
+ return { ns };
+ },
+ render() {
+ return (
+
+
+ {ibiz.i18n.t('control.common.loadMore')}
+
+
+ );
+ },
+});
diff --git a/src/common/index.ts b/src/common/index.ts
index 6a116581efc03bba0af63e7865641aec59a02ca9..dfd6b5ddf8c42a75614cd89363c5d178cc253f21 100644
--- a/src/common/index.ts
+++ b/src/common/index.ts
@@ -31,6 +31,7 @@ import { IBizSplit } from './split/split';
import { IBizSplitTrigger } from './split-trigger/split-trigger';
import { IBizMdAdvanedSearchfrom } from './md-advaned-searchform/md-advaned-searchform';
import { IBizAddBtn } from './add-btn/add-btn';
+import { IBizAddMore } from './add-more/add-more';
export * from './col/col';
export * from './row/row';
@@ -38,10 +39,12 @@ export * from './keep-alive/keep-alive';
export * from './md-sort-setting/md-sort-setting';
export * from './md-advaned-searchform/md-advaned-searchform';
export * from './add-btn/add-btn';
+export * from './add-more/add-more';
export const IBizCommonComponents = {
install: (v: App): void => {
v.component(IBizAddBtn.name!, IBizAddBtn);
+ v.component(IBizAddMore.name!, IBizAddMore);
v.component(IBizMdAdvanedSearchfrom.name!, IBizMdAdvanedSearchfrom);
v.component(IBizSplit.name!, IBizSplit);
v.component(IBizSplitTrigger.name!, IBizSplitTrigger);
diff --git a/src/control/data-view/data-view.scss b/src/control/data-view/data-view.scss
index 2faf3ee74be8792e4e2193718eb212fdb1e60c63..5d99d07eb8a4a467edf1ad13028a81beeb1a5efa 100644
--- a/src/control/data-view/data-view.scss
+++ b/src/control/data-view/data-view.scss
@@ -1,26 +1,20 @@
$control-dataview: (
- text-color: getCssVar(color, text, 0),
- item-padding: getCssVar(spacing, base-tight) getCssVar(spacing, base),
- padding: getCssVar(spacing, tight),
- item-gap: getCssVar(spacing, base, tight),
- item-bg-color: transparent,
- active-text-color: getCssVar(color, primary),
- active-bg-color: getCssVar(color, primary, light, default),
- group-font-size: getCssVar(font-size, header-6),
- group-bg-color: getCssVar(color, bg, 0),
- group-text-color: getCssVar(color, text, 1),
- group-header-padding: getCssVar(spacing, base),
- group-padding: 0 getCssVar(spacing, tight),
- group-anchor-bg-color: getCssVar(color, bg, 1),
- group-anchor-border-radius: getCssVar(border, radius, small),
- group-anchor-right: getCssVar('spacing', 'tight'),
- group-anchor-item-padding: getCssVar('spacing', 'tight') getCssVar('spacing', 'base'),
- item-shadow: getCssVar(shadow, elevated),
- button-padding: getCssVar(spacing, tight) 0,
- button-bg: getCssVar(color, fill, 0),
- button-active-bg: getCssVar(color, fill, 2),
- button-color: getCssVar(color, primary),
- add-border: 2px dashed getCssVar(color, border),
+ // Color
+ color-text: getCssVar(color, text, 0),
+ color-bg: getCssVar(color, bg, 0),
+ color-item-active: getCssVar(color, primary, light, default),
+ color-group-bg: getCssVar(color, bg, 0),
+ color-group-text: getCssVar(color, text, 1),
+ // Spacing
+ spacing-item-padding: getCssVar(spacing, base-tight) getCssVar(spacing, base),
+ spacing-padding: getCssVar(spacing, tight) getCssVar(spacing, base),
+ spacing-item-gap: getCssVar(spacing, base, tight),
+ spacing-group-padding: getCssVar(spacing, tight) getCssVar(spacing, base),
+ // Font
+ font-group-fontSize: getCssVar(font-size, header-6),
+ font-group-lineHeight: getCssVar(height-control, default),
+ // Other
+ shadow: getCssVar(shadow, elevated),
);
@include b(control-dataview) {
@@ -32,73 +26,79 @@ $control-dataview: (
@include e(content-container) {
height: 100%;
width: 100%;
- padding: getCssVar(control-dataview, padding);
- overflow-y: auto;
}
@include e(content) {
display: flex;
flex-wrap: wrap;
- height: 100%;
- gap: getCssVar(control-dataview, item-gap);
+ max-height: 100%;
+ gap: getCssVar(control-dataview, spacing-item-gap);
+ overflow-y: auto;
+ padding: getCssVar(control-dataview, spacing-padding);
- @include when(enable-anchor) {
- height: 100%;
+ .van-list__loading,.van-list__finished-text,.van-list__error-text {
+ width: 100%;
}
}
@include e(row) {
gap: 0;
+ margin: calc(-1 * getCssVar(control-dataview, spacing-item-gap)/ 2);
.#{bem(control-dataview, item-col)} {
- padding: calc(getCssVar(control-dataview, item-gap) / 2);
+ padding: calc(getCssVar(control-dataview, spacing-item-gap) / 2);
}
}
- @include when(enable-page) {
+ @include when(enable-pagination) {
display: flex;
flex-direction: column;
.#{bem(control-dataview, content-container)} {
flex: auto;
+ height: 0;
}
.#{bem(control-dataview, pagination)} {
flex: none;
}
}
- @include when(enable-pagination) {
+ @include when(hidden-finished) {
+ // 启用分页时隐藏列表加载完成提示
+ .van-list__finished-text {
+ display: none;
+ }
+ }
+
+ @include when(enable-group) {
.#{bem(control-dataview, content)} {
- height: auto;
+ padding: 0;
+ }
+ .#{bem(control-dataview-group, item)} {
+ padding: getCssVar(control-dataview, spacing-padding);
}
}
- @include e(load-more) {
- padding: getCssVar(control-dataview, button-padding);
- .van-button {
- width: 100%;
- border: none;
- background-color: getCssVar(control-dataview, button-bg);
- color: getCssVar(control-dataview, button-color);
- &:active {
- background-color: getCssVar(control-dataview, button-active-bg);
- }
+ @include e(anchor) {
+ width: 100%;
+ .van-index-anchor {
+ padding: 0;
}
}
}
@include b(control-dataview-item) {
flex: none;
- padding: getCssVar(control-dataview, item-padding);
- box-shadow: getCssVar(control-dataview, item-shadow);
- background-color: getCssVar(control-dataview, item-bg-color);
- color: getCssVar(control-dataview, text-color);
+ padding: getCssVar(control-dataview, spacing-item-padding);
+ box-shadow: getCssVar(control-dataview, shadow);
+ color: getCssVar(control-dataview, color-text);
+ background-color: getCssVar(control-dataview, color-bg);
width: 100%;
@include when(active) {
- background-color: getCssVar(control-dataview,
- item-active-color
- );
+ background-color: getCssVar(control-dataview, color-item-active);
}
>.van-card {
- padding: 0
+ padding: 0;
+ background-color: transparent;
+ color: inherit;
}
}
@@ -109,77 +109,21 @@ $control-dataview: (
@include e('container') {
width: 100%;
height: 100%;
- padding: getCssVar(control-dataview, group-padding);
- overflow-y: auto;
}
@include e(item) {
display: flex;
flex-direction: column;
- gap: getCssVar(control-dataview, item-gap);
+ gap: getCssVar(control-dataview, spacing-item-gap);
}
// 分组标题样式
@include e('caption') {
- padding: getCssVar(control-dataview, group-header-padding);
- font-size: getCssVar(control-dataview, group-font-size);
- color: getCssVar(control-dataview, group-text-color);
- background-color: getCssVar(control-dataview, group-bg-color);
- }
-
- // 分组锚点容器样式
- @include e('anchor-container') {
- position: absolute;
- right: getCssVar(control-dataview, group-anchor-right);
- top: 45%;
- transform: translateY(-50%);
- border-radius: getCssVar(control-dataview, group-anchor-border-radius);
- overflow: hidden;
- display: flex;
- flex-direction: column;
- background-color: getCssVar(control-dataview, group-anchor-bg-color);
- box-shadow:
- getCssVar(control-dataview, box-shadow-inner),
- getCssVar(control-dataview, box-shadow-outer);
- }
-
- // 分组锚点项样式
- @include e('anchor-item') {
- width: 100%;
- text-align: center;
- padding: getCssVar(control-dataview, group-anchor-item-padding);
-
- @include when(active) {
- color: getCssVar(control-dataview, active-text-color);
- background-color: getCssVar(control-dataview, active-bg-color);
- }
- }
-}
-
-// 分组锚点容器样式
-@include e('anchor-container') {
- position: absolute;
- right: getCssVar(control-dataview, group-anchor-right);
- top: 45%;
- transform: translateY(-50%);
- border-radius: getCssVar(control-dataview, group-anchor-border-radius);
- overflow: hidden;
- display: flex;
- flex-direction: column;
- background-color: getCssVar(control-dataview, group-anchor-bg-color);
- box-shadow:
- getCssVar(control-dataview, item-shadow);
-}
-
-// 分组锚点项样式
-@include e('anchor-item') {
- width: 100%;
- text-align: center;
- padding: getCssVar(control-dataview, group-anchor-item-padding);
-
- @include when(active) {
- color: getCssVar(control-dataview, active-text-color);
- background-color: getCssVar(control-dataview, active-bg-color);
+ padding: getCssVar(control-dataview, spacing-group-padding);
+ font-size: getCssVar(control-dataview, font-group-fontSize);
+ line-height: getCssVar(control-dataview, font-group-lineHeight);
+ color: getCssVar(control-dataview, color-group-text);
+ background-color: getCssVar(control-dataview, color-group-bg);
}
}
diff --git a/src/control/data-view/data-view.tsx b/src/control/data-view/data-view.tsx
index 1d28739e80d57f3f0311dd390719e6625d31fa5d..3e0cb60b1edadfd69d7c7ce1882f9f0d49e941f7 100644
--- a/src/control/data-view/data-view.tsx
+++ b/src/control/data-view/data-view.tsx
@@ -1,17 +1,15 @@
import { useControlController, useNamespace } from '@ibiz-template/vue3-util';
-import { computed, defineComponent, PropType, ref, VNode, watch } from 'vue';
+import { defineComponent, PropType, VNode } from 'vue';
import {
IDEDataView,
ILayoutPanel,
IUIActionGroupDetail,
} from '@ibiz/model-core';
import {
- ControlVO,
DataViewControlController,
IControlProvider,
} from '@ibiz-template/runtime';
-import { createUUID } from 'qx-util';
-import { usePagination } from '../../util';
+import { useListRender, usePagination } from '../../util';
import './data-view.scss';
export const DataViewControl = defineComponent({
@@ -58,106 +56,16 @@ export const DataViewControl = defineComponent({
(...args) => new DataViewControlController(...args),
);
const ns = useNamespace(`control-${c.model.controlType!.toLowerCase()}`);
-
- const isUpdating = ref(false);
-
- const scrollContainer = ref();
-
- // 是否可以加载更多
- const isLodeMoreDisabled = computed(() => {
- if (c.model.enablePagingBar === true) {
- return true;
- }
- if (c.model.pagingMode !== 2) {
- return true;
- }
- return (
- c.state.items.length >= c.state.total ||
- c.state.isLoading ||
- c.state.total <= c.state.size
- );
- });
-
- const scrollKey = createUUID();
- const selectScrollKey = ref();
-
- // 处理分组锚点项点击
- const handleGroupAnchorClick = (_id: string) => {
- // 获取目标元素和滚动容器
- const targetElement = document.getElementById(_id);
- const el = scrollContainer.value;
-
- if (targetElement && el) {
- const targetTop = targetElement.offsetTop;
- const containerTop = el.offsetTop;
- const relativePosition = targetTop - containerTop;
-
- // 基于滚动容器进行滚动
- el.scrollTo({
- top: relativePosition,
- behavior: 'smooth',
- });
- selectScrollKey.value = _id;
- }
- };
-
- // 本地数据模式
- const initSimpleData = (): void => {
- if (!props.data) {
- return;
- }
- c.state.items = (props.data as IData[]).map(item => new ControlVO(item));
- c.afterLoad({}, c.state.items);
- };
-
- // 添加动画帧,反正加载多次
- c.evt.on('onLoadSuccess', () => {
- isUpdating.value = true;
- window.requestAnimationFrame(() => {
- isUpdating.value = false;
- });
- selectScrollKey.value = '';
- });
-
- c.evt.on('onCreated', async () => {
- if (props.isSimple) {
- initSimpleData();
- c.state.isSimple = true;
- c.state.isLoaded = true;
- }
- });
-
- watch(
- () => props.data,
- () => {
- if (props.isSimple) {
- initSimpleData();
- }
- },
- {
- deep: true,
- },
- );
+ const {
+ enableLoadMore,
+ renderNoData,
+ renderAddItem,
+ renderScrollList,
+ renderGroup,
+ } = useListRender(props, c, ns);
const { onPageChange } = usePagination(c);
- // 是否显示数据伸缩图标
- // 如果未开启分组,并且加载模式为【加载更多】,并且已经加载过一次更多,则为 true
- const showCollapseOrExpandIcon = computed(() => {
- return !c.model.enableGroup && c.model.pagingMode === 3;
- });
-
- const renderAddBtn = (group?: IData) => {
- if (!c.enableNew) {
- return;
- }
- return (
- c.onClickNew(event, group?.key)}
- >
- );
- };
-
// 绘制项布局面板
const renderPanelItem = (item: IData, modelData: ILayoutPanel): VNode => {
const { context, params } = c;
@@ -198,35 +106,6 @@ export const DataViewControl = defineComponent({
);
};
- const renderNoData = (): VNode | undefined => {
- // 未加载不显示无数据
- const { isLoaded } = c.state;
- if (!isLoaded) {
- return;
- }
- const ctrlModel = c.model.controls?.find(item => {
- return item.name === `${c.model.name!}_quicktoolbar`;
- });
- if (ctrlModel) {
- return (
-
- );
- }
- return (
- isLoaded && (
-
- )
- );
- };
-
const renderDefaultItem = (item: IData) => {
return (
@@ -265,10 +144,9 @@ export const DataViewControl = defineComponent({
Object.assign(
cardStyle,
ns.cssVarBlock({
- 'item-bg-color': `${item.bgcolor || ''}`,
- 'item-font-color': `${item.fontcolor || ''}`,
- 'item-hover-color': `${item.hovercolor || ''}`,
- 'item-active-color': `${item.activecolor || ''}`,
+ 'color-bg': `${item.bgcolor || ''}`,
+ 'color-text': `${item.fontcolor || ''}`,
+ 'color-item-active': `${item.activecolor || ''}`,
}),
);
return (
@@ -282,13 +160,10 @@ export const DataViewControl = defineComponent({
);
};
- const renderContent = (items: IData[], group?: IData) => {
- if (!items.length) {
- return renderNoData();
- }
+ const renderContent = (items: IData[]) => {
const { cardColMD } = c.model;
if (cardColMD) {
- return [
+ return (
{items.map(item => {
return (
@@ -297,110 +172,40 @@ export const DataViewControl = defineComponent({
);
})}
- ,
- renderAddBtn(group),
- ];
+
+ );
}
return [
...items.map(item => {
return renderCard(item);
}),
- renderAddBtn(group),
];
};
- const renderGroup = () => {
- const showGroupAnchor = c.state.groups.length > 1 && c.showGroupAnchor;
- return [
-
-
- {c.state.groups.map((group, index) => {
- const _id = `group-${scrollKey}-${index}`;
- return [
-
- {group.caption}
-
,
-
- {renderContent(group.children, group)}
-
,
- ];
- })}
-
- {showGroupAnchor ? (
-
- {c.state.groups.map((group, index) => {
- const _id = `group-${scrollKey}-${index}`;
- return (
-
handleGroupAnchorClick(_id)}
- class={[
- ns.be('group', 'anchor-item'),
- ns.is('active', selectScrollKey.value === _id),
- ]}
- >
- {group.caption}
-
- );
- })}
-
- ) : null}
-
,
- ];
+ const renderDefault = () => {
+ const result = [];
+ result.push(renderContent(c.state.items));
+ if (c.enableNew) {
+ result.push(renderAddItem());
+ }
+ return result;
};
- // 绘制卡片内容
+ // 绘制列表内容
const renderMDContent = () => {
- const showGroupAnchor = c.state.groups.length > 1 && c.showGroupAnchor;
- return (
- c.loadMore()}
- >
- {c.enableGroup ? renderGroup() : renderContent(c.state.items)}
-
- );
- };
-
- // 加载更多
- const loadMoreIcon = () => {
- return (
-
- c.loadMore()}>
- {ibiz.i18n.t('control.common.loadMore')}
-
-
- );
- };
-
- // 分页模式为点击加载时并且当前数量小于总数
- const renderLoadMore = () => {
- let icon = null;
- const loadMore =
- c.state.items.length < c.state.total && c.state.total > c.state.size;
- if (showCollapseOrExpandIcon.value && loadMore) {
- icon = loadMoreIcon();
- }
- return icon;
+ const slots = c.enableGroup
+ ? renderGroup({ children: renderContent })
+ : renderDefault();
+ return renderScrollList(slots);
};
return {
c,
ns,
- scrollContainer,
- showCollapseOrExpandIcon,
+ enableLoadMore,
onPageChange,
renderNoData,
renderMDContent,
- renderLoadMore,
};
},
render() {
@@ -409,17 +214,20 @@ export const DataViewControl = defineComponent({
return (
- {this.c.state.isCreated && this.renderMDContent()}
- {this.renderLoadMore()}
+ {this.c.state.isCreated &&
+ (this.c.state.items.length > 0
+ ? this.renderMDContent()
+ : this.renderNoData())}
{enablePagingBar ? (
=
@@ -63,6 +63,9 @@ export const EditFormControl: ReturnType =
const filter = ref(undefined);
+ // 所有启用了锚点的表单项
+ const anchorList: Ref = ref([]);
+
if (props.isSimple) {
if (props.simpleDataIndex || props.simpleDataIndex === 0) {
c.setSimpleDataIndex(props.simpleDataIndex);
@@ -99,6 +102,7 @@ export const EditFormControl: ReturnType =
const detail = c.details[key];
detail.state = reactive(detail.state);
});
+ anchorList.value = c.anchorData;
});
const handleInput = debounce(
@@ -110,12 +114,18 @@ export const EditFormControl: ReturnType =
{ leading: true },
);
- return { c, ns, filter, handleInput };
+ return {
+ c,
+ ns,
+ filter,
+ handleInput,
+ anchorList,
+ };
},
render() {
- const { enableItemFilter } = this.c.model;
- return (
+ const { enableItemFilter, showFormNavBar } = this.c.model;
+ const content = (
{enableItemFilter && (
=
);
+ if (showFormNavBar) {
+ const { navBarSysCss, navBarPos } = this.c.model;
+ const items = this.anchorList.filter(
+ (item: IData) => item.pageId === this.c.state.activeTab,
+ );
+ return (
+ x.title)}
+ sticky={false}
+ class={[
+ this.ns.e('anchor'),
+ navBarSysCss,
+ this.ns.em('anchor', navBarPos?.toLowerCase()),
+ ]}
+ >
+ {content}
+
+ );
+ }
+ return content;
},
});
diff --git a/src/control/form/form-detail/form-group-panel/form-group-panel.tsx b/src/control/form/form-detail/form-group-panel/form-group-panel.tsx
index 08abbd07c7bf29edb7d9bf62bed974f5c9d9330a..6df6fdaa3ad58b0b34a2d348747c47f1a70b4d8e 100644
--- a/src/control/form/form-detail/form-group-panel/form-group-panel.tsx
+++ b/src/control/form/form-detail/form-group-panel/form-group-panel.tsx
@@ -46,6 +46,7 @@ export const FormGroupPanel = defineComponent({
},
render() {
const { state } = this.controller;
+ const { enableAnchor } = this.modelData;
const defaultSlots: VNode[] = this.$slots.default?.() || [];
const content = (
@@ -147,7 +148,11 @@ export const FormGroupPanel = defineComponent({
class={[classArr, this.ns.is('loading', this.controller.state.loading)]}
onClick={(event: MouseEvent) => this.controller.onClick(event)}
>
- {header}
+ {enableAnchor ? (
+ {header}
+ ) : (
+ header
+ )}
{content}
{footer}
{this.controller.state.loading ? (
diff --git a/src/control/form/form-detail/form-item/form-item-container/form-item-container.tsx b/src/control/form/form-detail/form-item/form-item-container/form-item-container.tsx
index 019a5f615b211966a487b93e20c155f5ed3e997c..5e1818362569e15fb04619ff070e5fb1a6986540 100644
--- a/src/control/form/form-detail/form-item/form-item-container/form-item-container.tsx
+++ b/src/control/form/form-detail/form-item/form-item-container/form-item-container.tsx
@@ -99,6 +99,7 @@ export const IBizFormItemContainer = defineComponent({
};
const renderLabel = () => {
+ const { enableAnchor } = c.model;
return (
)}
- {c.labelCaption}
+ {enableAnchor ? (
+
+ {c.labelCaption}
+
+ ) : (
+ {c.labelCaption}
+ )}
);
},
diff --git a/src/control/list/list/list.tsx b/src/control/list/list/list.tsx
index 92d8cea0e223d7ad1f4195d7dcb83edce6cd6b97..c36814657118b1842653bb024f75a994cb6b00f5 100644
--- a/src/control/list/list/list.tsx
+++ b/src/control/list/list/list.tsx
@@ -2,8 +2,8 @@ import { IDEList } from '@ibiz/model-core';
import { defineComponent, PropType, ref } from 'vue';
import { useControlController, useNamespace } from '@ibiz-template/vue3-util';
import { IControlProvider, ListController } from '@ibiz-template/runtime';
-import { useListRender } from '../list-render-util';
import './list.scss';
+import { useListRender } from '../../../util';
export const ListControl = defineComponent({
name: 'IBizListControl',
diff --git a/src/control/list/md-ctrl/md-ctrl.scss b/src/control/list/md-ctrl/md-ctrl.scss
index 8e21dfb3caaf99cff9f6cd93007672fad0d9e724..9a01c116c29881021fe5c6141add21b77450b2ea 100644
--- a/src/control/list/md-ctrl/md-ctrl.scss
+++ b/src/control/list/md-ctrl/md-ctrl.scss
@@ -1,139 +1,108 @@
$control-mobmdctrl: (
- font-size: getCssVar(font-size, regular),
- text-color: getCssVar(color, text, 0),
- border-color: getCssVar(color, border),
- active-text-color: getCssVar(color, primary),
- active-bg-color: getCssVar(color, primary, light, default),
- padding: getCssVar(spacing, tight) getCssVar(spacing, base),
- overflow: getCssVar(control, overflow),
- box-shadow-inner: 0 0 0 rgba(0 0 0 / 30%),
- box-shadow-outer: 0 rem(4px) rem(14px) rgba(0 0 0 / 10%),
- img-width: getCssVar(width-icon, extra-large),
- img-height: getCssVar(width-icon, extra-large),
- img-radius: getCssVar(border-radius, extra-small),
- img-padding: getCssVar(spacing, tight),
- item-font-color: getCssVar(color, text, 0),
- item-bg-color: getCssVar(color, bg, 2),
- item-under-line-right: getCssVar(spacing, base),
- item-under-line-left: getCssVar(spacing, base),
- item-right-padding: 0 getCssVar('spacing', 'tight') 0 0 ,
- group-font-size: getCssVar(font-size, header-6),
- group-bg-color: getCssVar(color, bg, 0),
- group-text-color: getCssVar(color, text, 1),
- group-padding: getCssVar(spacing, base),
- group-anchor-bg-color: getCssVar(color, bg, 1),
- group-anchor-active-bg-color: getCssVar(color, primary, light, default),
- group-anchor-color: getCssVar(color, primary),
- group-anchor-border-radius: getCssVar(border, radius, small),
- group-anchor-right: getCssVar('spacing', 'tight'),
- group-anchor-item-padding: getCssVar(spacing, base-tight) getCssVar(spacing, base),
- group-anchor-max-width: 120px,
- more-padding: getCssVar(spacing, tight) getCssVar(spacing, base),
- more-bg: getCssVar(color, fill, 0),
- more-active-bg: getCssVar(color, fill, 2),
- more-color: getCssVar(color, primary),
- pagination-height: getCssVar('height-control', 'large'),
- simplelist-height: 250px,
+ // Color
+ color-text: getCssVar(color, text, 0),
+ color-active-bg: getCssVar(color, primary, light, default),
+ color-item-bg: getCssVar(color, bg, 2),
+ color-group-bg: getCssVar(color, bg, 0),
+ color-group-text: getCssVar(color, text, 1),
+ // Width/Height
+ width-img: getCssVar(width-icon, extra-large),
+ height-img: getCssVar(width-icon, extra-large),
+ // Spacing
+ spacing-item-padding: getCssVar(spacing, tight) getCssVar(spacing, base),
+ spacing-group-padding: getCssVar(spacing, tight) getCssVar(spacing, base),
+ spacing-img-padding: getCssVar(spacing, tight),
+ spacing-checkbox-gap: getCssVar('spacing', 'tight'),
+ spacing-border-padding: getCssVar(spacing, base),
+ // Radius
+ radius-img: getCssVar(border-radius, extra-small),
+ // Font
+ font-fontSize: getCssVar(font-size, regular),
+ font-group-fontSize: getCssVar(font-size, header-6),
+ font-group-lineHeight: getCssVar(height-control, default),
);
@include b(control-mobmdctrl) {
@include set-component-css-var(control-mobmdctrl, $control-mobmdctrl);
height: 100%;
- overflow: getCssVar(control-mobmdctrl, overflow);
position: relative;
// 列表容器样式
@include e(content) {
width: 100%;
- height: 99%;
+ height: 100%;
+ overflow-y: auto;
@include when(show-under-line) {
- // 列表项下划线样式
- .#{bem(control-mobmdctrl-item)},
- .#{bem(control-mobmdctrl-select-item)} {
- position: relative;
- &::after {
- position: absolute;
- box-sizing: border-box;
- content: '';
- pointer-events: none;
- right: getCssVar(control-mobmdctrl, item-under-line-right);
- bottom: 0;
- left: getCssVar(control-mobmdctrl, item-under-line-left);
- border-bottom: 1px solid getCssVar(control-mobmdctrl, border-color);
- transform: scaleY(0.5);
- display: block;
- }
+ .van-hairline--bottom:after {
+ left: calc(-50% + getCssVar(control-mobmdctrl, spacing-border-padding)*2);
+ right: calc(-50% + getCssVar(control-mobmdctrl, spacing-border-padding)*2);
}
}
+ .#{bem(add-more)} {
+ padding: getCssVar(control-mobmdctrl, spacing-item-padding);
+ }
}
// 启用分页,列表内容区需减去分页高度。分页时内容区出滚动条,避免滚动时页码偏移
@include when(enable-page) {
+ display: flex;
+ flex-direction: column;
.#{bem(control-mobmdctrl, content)} {
- height: calc(100% - getCssVar(control-mobmdctrl, pagination-height));
- overflow-y: auto;
+ flex: auto;
+ height: 0;
+ }
+ .#{bem(control-mobmdctrl, pagination)} {
+ flex: none;
}
}
- // 启用加载更多时,部件整体高度应该由列表内容加上加载更多高度撑起来,继承父元素高度会导致滚动异常
- @include when(load-more) {
- height: auto;
- }
-
- // 启用分组时,应该由列表内容区出滚动条,避免滚动时锚点偏移
- @include when(enable-anchor) {
- .#{bem(control-mobmdctrl, content)} {
- overflow-y: auto;
+ @include when(hidden-finished) {
+ // 启用分页时隐藏列表加载完成提示
+ .van-list__finished-text {
+ display: none;
}
}
- // 加载更多样式
-@include e(load-more) {
- padding: getCssVar(control-mobmdctrl, more-padding);
- .van-button {
- width: 100%;
- border: none;
- background-color: getCssVar(control-mobmdctrl, more-bg);
- color: getCssVar(control-mobmdctrl, more-color);
- &:active {
- background-color: getCssVar(control-mobmdctrl, more-active-bg);
+ // 分组锚点容器样式
+ @include e('anchor') {
+ .van-index-anchor {
+ padding: 0;
}
}
}
-}
// 列表项样式
@include b(control-mobmdctrl-item) {
// 部件为选择模式时,右侧复选框间距
@include e(right) {
- padding: getCssVar(control-mobmdctrl, item-right-padding);
+ margin-right: getCssVar(control-mobmdctrl, spacing-checkbox-gap);
}
// 增加权重,避免ui组件本身样式影响
&.#{bem(control-mobmdctrl-item)} {
- background-color: getCssVar(control-mobmdctrl, item-bg-color);
- color: getCssVar(control-mobmdctrl, item-font-color);
+ background-color: getCssVar(control-mobmdctrl, color-item-bg);
+ color: getCssVar(control-mobmdctrl, color-text);
height: auto;
- font-size: getCssVar(control-mobmdctrl, font-size);
- padding: getCssVar(control-mobmdctrl, padding);
+ font-size: getCssVar(control-mobmdctrl, font-fontSize);
+ padding: getCssVar(control-mobmdctrl, spacing-item-padding);
}
// 列表项选中样式
@include when(active) {
&.#{bem(control-mobmdctrl-item)} {
- background-color: getCssVar(control-mobmdctrl, item-active-color);
+ background-color: getCssVar(control-mobmdctrl, color-active-bg);
}
}
}
// 列表项左侧图片样式,默认绘制并且项数据image存在路径值时生效
@include b(control-mobmdctrl-image) {
- width: getCssVar(control-mobmdctrl, img-width);
- height: getCssVar(control-mobmdctrl, img-height);
- margin-right: getCssVar(control-mobmdctrl, img-padding);
- border-radius: getCssVar(control-mobmdctrl, img-radius);
+ width: getCssVar(control-mobmdctrl, width-img);
+ height: getCssVar(control-mobmdctrl, height-img);
+ margin-right: getCssVar(control-mobmdctrl, spacing-img-padding);
+ border-radius: getCssVar(control-mobmdctrl, radius-img);
}
// 分组样式
@@ -145,40 +114,11 @@ $control-mobmdctrl: (
// 分组标题样式
@include e('caption') {
- padding: getCssVar(control-mobmdctrl, group-padding);
- font-size: getCssVar(control-mobmdctrl, group-font-size);
- color: getCssVar(control-mobmdctrl, group-text-color);
- background-color: getCssVar(control-mobmdctrl, group-bg-color);
- }
-
- // 分组锚点容器样式
- @include e('anchor-container') {
- position: absolute;
- right: getCssVar(control-mobmdctrl, group-anchor-right);
- top: 45%;
- transform: translateY(-50%);
- border-radius: getCssVar(control-mobmdctrl, group-anchor-border-radius);
- overflow: hidden;
- font-size: getCssVar(control-mobmdctrl, font-size);
- max-width: getCssVar(control-mobmdctrl, group-anchor-max-width);
- display: flex;
- flex-direction: column;
- background-color: getCssVar(control-mobmdctrl, group-anchor-bg-color);
- box-shadow:
- getCssVar(control-mobmdctrl, box-shadow-inner),
- getCssVar(control-mobmdctrl, box-shadow-outer);
- }
-
- // 分组锚点项样式
- @include e('anchor-item') {
- width: 100%;
- text-align: center;
- padding: getCssVar(control-mobmdctrl, group-anchor-item-padding);
-
- @include when(active) {
- color: getCssVar(control-mobmdctrl, group-anchor-color);
- background-color: getCssVar(control-mobmdctrl, group-anchor-active-bg-color);
- }
+ padding: getCssVar(control-mobmdctrl, spacing-group-padding);
+ font-size: getCssVar(control-mobmdctrl, font-group-fontSize);
+ line-height: getCssVar(control-mobmdctrl, font-group-lineHeight);
+ color: getCssVar(control-mobmdctrl, color-group-text);
+ background-color: getCssVar(control-mobmdctrl, color-group-bg);
}
}
@@ -187,18 +127,20 @@ $control-mobmdctrl: (
display: flex;
align-items: center;
justify-content: space-between;
- color: getCssVar(control-mobmdctrl, item-font-color);
- background-color: getCssVar(control-mobmdctrl, item-bg-color);
- padding: getCssVar(control-mobmdctrl, padding);
+ padding: getCssVar(control-mobmdctrl, spacing-item-padding);
@include e(left) {
- padding: getCssVar(control-mobmdctrl, item-right-padding);
+ margin-right: getCssVar(control-mobmdctrl, spacing-checkbox-gap);
+ }
+ @include when(active) {
+ background-color: getCssVar(control-mobmdctrl, color-active-bg);
}
.#{bem(control-mobmdctrl-item)} {
flex: 1;
padding: 0;
width: auto;
+ // 隐藏边框
&.#{bem(control-mobmdctrl-item)}::after {
display: none;
}
diff --git a/src/control/list/md-ctrl/md-ctrl.tsx b/src/control/list/md-ctrl/md-ctrl.tsx
index b3b5a7776de5d54edd6e2c40cd6c9e2ca3e139b8..b291d2b07ddd9fda554b47f1efbbce7929034b94 100644
--- a/src/control/list/md-ctrl/md-ctrl.tsx
+++ b/src/control/list/md-ctrl/md-ctrl.tsx
@@ -1,6 +1,5 @@
import { useControlController, useNamespace } from '@ibiz-template/vue3-util';
-import { computed, defineComponent, PropType, ref, watch } from 'vue';
-import { debounce } from 'lodash-es';
+import { defineComponent, PropType } from 'vue';
import {
IDEMobMDCtrl,
IDETBUIActionItem,
@@ -11,11 +10,8 @@ import {
MDCtrlController,
IMobMDCtrlRowState,
getAllUIActionItems,
- ControlVO,
} from '@ibiz-template/runtime';
-import { createUUID } from 'qx-util';
-import { useListRender } from '../list-render-util';
-import { convertBtnType, usePagination } from '../../../util';
+import { convertBtnType, useListRender, usePagination } from '../../../util';
import './md-ctrl.scss';
export const MDCtrlControl = defineComponent({
@@ -74,122 +70,17 @@ export const MDCtrlControl = defineComponent({
setup(props) {
const c = useControlController((...args) => new MDCtrlController(...args));
const ns = useNamespace(`control-${c.model.controlType!.toLowerCase()}`);
- const { renderItem, renderNoData, renderLoadMore, renderAddItem } =
- useListRender(props, c, ns);
-
- const listRef = ref();
-
- const isUpdating = ref(false);
-
- // 不分页 0 分页栏 1 滚动加载 2 加载更多 3
- // 是否可以加载更多
- const isLodeMoreDisabled = computed(() => {
- if (c.model.enablePagingBar === true) {
- return true;
- }
- if (c.model.pagingMode !== 2) {
- return true;
- }
- return (
- c.state.items.length >= c.state.total ||
- c.state.isLoading ||
- c.state.total <= c.state.size
- );
- });
-
- // 本地数据模式
- const initSimpleData = (): void => {
- if (!props.data) {
- return;
- }
- c.state.items = (props.data as IData[]).map(item => new ControlVO(item));
- c.afterLoad({}, c.state.items as ControlVO[]);
- };
-
- c.evt.on('onCreated', async () => {
- if (props.isSimple) {
- initSimpleData();
- c.state.isSimple = true;
- c.state.isLoaded = true;
- }
- });
-
- watch(
- () => props.data,
- () => {
- if (props.isSimple) {
- initSimpleData();
- }
- },
- {
- deep: true,
- },
- );
+ const {
+ enableLoadMore,
+ renderItem,
+ renderNoData,
+ renderAddItem,
+ renderScrollList,
+ renderGroup,
+ } = useListRender(props, c, ns);
const { onPageChange } = usePagination(c);
- // 排序值
- const sortVal = computed(() => {
- if (c.state.sortQuery) {
- const [key, order] = c.state.sortQuery.split(',');
- return { key, order };
- }
- return null;
- });
-
- // 处理排序配置回调
- const onSortChange = (sort: { key: string; order: 'asc' | 'desc' }) => {
- c.setSort(sort.key, sort.order);
- c.load({ isInitialLoad: true });
- };
-
- // 加载更多
- const debounceLoadMore = debounce(async () => {
- c.loadMore();
- }, 500);
-
- const scrollKey = createUUID();
- const selectScrollKey = ref();
-
- // 处理分组锚点项点击
- const handleGroupAnchorClick = (_id: string) => {
- // 获取目标元素和滚动容器
- const targetElement = document.getElementById(_id);
- const listDom = listRef.value?.$el;
-
- if (targetElement && listDom) {
- const targetTop = targetElement.offsetTop;
- const containerTop = listDom.offsetTop;
- const relativePosition = targetTop - containerTop;
-
- // 基于滚动容器进行滚动
- listDom.scrollTo({
- top: relativePosition,
- behavior: 'smooth',
- });
- selectScrollKey.value = _id;
- }
- };
-
- const onLoadMore = () => {
- debounceLoadMore();
- };
-
- // 添加动画帧,反正加载多次
- c.evt.on('onLoadSuccess', () => {
- isUpdating.value = true;
- window.requestAnimationFrame(() => {
- isUpdating.value = false;
- });
- selectScrollKey.value = '';
- });
-
- // 是否显示数据伸缩图标
- // 如果未开启分组,并且加载模式为【加载更多】,并且已经加载过一次更多,则为 true
- const showCollapseOrExpandIcon = computed(() => {
- return !c.model.enableGroup && c.model.pagingMode === 3;
- });
-
// 左滑界面行为组
const leftSlidingActionGroup = c.model.deuiactionGroup;
// 右滑界面行为组
@@ -254,7 +145,7 @@ export const MDCtrlControl = defineComponent({
const renderDefault = () => {
const result = [];
result.push(
- c.state.items.map((item: IData) => {
+ ...c.state.items.map((item: IData) => {
return renderDefaultItem(item);
}),
);
@@ -264,91 +155,44 @@ export const MDCtrlControl = defineComponent({
return result;
};
- const renderGroup = () => {
- const showGroupAnchor = c.state.groups.length > 1 && c.showGroupAnchor;
- return [
-
-
- {c.state.groups.map((group, index) => {
- const _id = `group-${scrollKey}-${index}`;
- return (
-
-
{group.caption}
- {group.children.map(item => {
- return renderDefaultItem(item.data);
- })}
- {c.enableNew ? renderAddItem(group) : null}
-
- );
- })}
-
- {showGroupAnchor ? (
-
- {c.state.groups.map((group, index) => {
- const _id = `group-${scrollKey}-${index}`;
- return (
-
handleGroupAnchorClick(_id)}
- class={[
- ns.be('group', 'anchor-item'),
- ns.is('active', selectScrollKey.value === _id),
- ]}
- >
- {group.caption}
-
- );
- })}
-
- ) : null}
-
,
- ];
+ const renderGroupChildren = (children: IData[]) => {
+ return children.map(item => {
+ return renderDefaultItem(item.data);
+ });
};
// 绘制列表内容
const renderMDContent = () => {
- return (
- onLoadMore()}
- >
- {c.enableGroup ? renderGroup() : renderDefault()}
-
- );
+ const slots = c.enableGroup
+ ? renderGroup({ children: renderGroupChildren })
+ : renderDefault();
+ return renderScrollList(slots);
};
return {
c,
ns,
- listRef,
+ enableLoadMore,
renderMDContent,
renderNoData,
- showCollapseOrExpandIcon,
onPageChange,
- renderLoadMore,
- sortVal,
- onSortChange,
};
},
render() {
- const enablePagingBar =
- this.c.model.enablePagingBar && this.c.model.pagingMode === 1;
+ const enablePagingBar = this.c.model.enablePagingBar;
return (
{this.c.state.isCreated &&
@@ -366,7 +210,6 @@ export const MDCtrlControl = defineComponent({
onChange={this.onPageChange}
>
) : null}
- {this.showCollapseOrExpandIcon && this.renderLoadMore()}
);
},
diff --git a/src/locale/en/index.ts b/src/locale/en/index.ts
index f1155eaf4a094fdb490d6f12e79c93e7c6cb3d64..b585af818759d78f33d7b72e91e541f69ae96ab8 100644
--- a/src/locale/en/index.ts
+++ b/src/locale/en/index.ts
@@ -79,7 +79,9 @@ export default {
// 部件
control: {
common: {
- loadMore: 'Load more',
+ loadMore: 'Load more...',
+ loadFinish: 'I have made it to the end',
+ loadError: 'Loading failed. Click to reload',
addbtn: 'Add',
},
appmenu: {
@@ -88,7 +90,6 @@ export default {
customNav: 'Customize Navigation',
save: 'Save',
},
- dataView: { end: 'The end~' },
form: {
noSupportDetailType:
'Form detail type not supported: {detailType} or corresponding provider cannot be found',
diff --git a/src/locale/zh-CN/index.ts b/src/locale/zh-CN/index.ts
index c3f0a3cc236e44b064ff4c80b2b0fcb5528e3a8d..1196bf57c993efdbf7406e17c784f449b9a7a507 100644
--- a/src/locale/zh-CN/index.ts
+++ b/src/locale/zh-CN/index.ts
@@ -63,10 +63,11 @@ export default {
// 部件
control: {
common: {
- loadMore: '加载更多',
+ loadMore: '加载更多...',
+ loadFinish: '我已经到底啦',
+ loadError: '加载失败,点击重新加载',
addbtn: '新增',
},
- dataView: { end: '我已经到底啦~' },
appmenu: {
more: '更多',
bottomNav: '底部导航',
@@ -111,7 +112,6 @@ export default {
list: {
expand: '展开',
selectedData: '选中数据',
- end: '我已经到底啦~',
},
searchBar: {
confirm: '确认',
diff --git a/src/util/index.ts b/src/util/index.ts
index 4fc48e9be04b00be0308ea430c7a0eb14c143b30..f5a33d7d79703a4f9920115e8925e1021bc91b4a 100644
--- a/src/util/index.ts
+++ b/src/util/index.ts
@@ -13,3 +13,4 @@ export * from './store';
export { usePopstateListener } from './use-popstate-util/use-popstate-util';
export { QrcodeUtil } from './qrcode-util/qrcode-util';
export { convertBtnType } from './button-util/button-util';
+export { useListRender } from './list-util/list-render-util';
diff --git a/src/control/list/list-render-util.tsx b/src/util/list-util/list-render-util.tsx
similarity index 40%
rename from src/control/list/list-render-util.tsx
rename to src/util/list-util/list-render-util.tsx
index 37e584e55e9f05e0a6d2ff5f0789e2ed578727fc..bdc82f78fbbe369cbaef929331aa85101d7b8e16 100644
--- a/src/control/list/list-render-util.tsx
+++ b/src/util/list-util/list-render-util.tsx
@@ -1,34 +1,91 @@
import { Namespace } from '@ibiz-template/core';
-import { ListController, MDCtrlController } from '@ibiz-template/runtime';
-import { VNode } from 'vue';
-import { ILayoutPanel } from '@ibiz/model-core';
+import {
+ ControlVO,
+ MDControlController,
+ MDCtrlController,
+} from '@ibiz-template/runtime';
+import { computed, Ref, ref, VNode, watch } from 'vue';
+import { IDEMobMDCtrl, ILayoutPanel } from '@ibiz/model-core';
import { JSX } from 'vue/jsx-runtime';
-/**
- * 列表绘制工具
- *
- * @author zk
- * @date 2023-12-06 03:12:00
- * @export
- * @param {IData} props
- * @param {(IMobMDCtrlController | IListController)} c
- * @param {Namespace} ns
- * @return {*} {({
- * renderItem: (row: IData) => VNode | undefined;
- * render: () => VNode | null;
- * renderNoData: () => VNode | undefined;
- * })}
- */
export function useListRender(
props: IData,
- c: MDCtrlController | ListController,
+ c: MDControlController,
ns: Namespace,
): {
+ enableLoadMore: Ref;
renderItem: (row: IData) => VNode | undefined;
renderNoData: () => VNode | undefined;
renderLoadMore: () => JSX.Element | null;
renderAddItem: (group?: IData) => JSX.Element | null;
+ renderScrollList: (slots: IData) => JSX.Element | null;
+ renderGroup: (slots: IData) => JSX.Element;
} {
+ const {
+ name,
+ enablePagingBar,
+ pagingMode,
+ controlStyle,
+ itemLayoutPanel,
+ controls = [],
+ emptyText,
+ emptyTextLanguageRes,
+ } = c.model as IDEMobMDCtrl;
+
+ // 是否加载失败,用于列表下拉加载失败时点击重新加载
+ const isLoadError = ref(false);
+
+ // 是否加载完成,用于判断数据加载(启用分页栏或加载更多时禁用滚动加载)
+ const isLodeFinished = ref(enablePagingBar === true || pagingMode === 3);
+
+ // 是否加载更多,根据已加载数据与总数据条数判断
+ const enableLoadMore = computed(() => {
+ return c.state.items.length < c.state.total && c.state.total > c.state.size;
+ });
+
+ // 加载完成后计算是否存在剩余数据
+ c.evt.on('onLoadSuccess', () => {
+ if (!enablePagingBar && pagingMode !== 3) {
+ isLodeFinished.value =
+ c.state.items.length >= c.state.total || c.state.total <= c.state.size;
+ }
+ });
+
+ c.evt.on('onLoadError', () => {
+ isLoadError.value = true;
+ // 加载失败时重新加载当前页
+ c.state.curPage -= 1;
+ });
+
+ // 本地数据模式
+ const initSimpleData = (): void => {
+ if (!props.data) {
+ return;
+ }
+ c.state.items = (props.data as IData[]).map(item => new ControlVO(item));
+ c.afterLoad({}, c.state.items as ControlVO[]);
+ };
+
+ c.evt.on('onCreated', async () => {
+ if (props.isSimple) {
+ initSimpleData();
+ c.state.isSimple = true;
+ c.state.isLoaded = true;
+ }
+ });
+
+ watch(
+ () => props.data,
+ () => {
+ if (props.isSimple) {
+ initSimpleData();
+ }
+ },
+ {
+ deep: true,
+ },
+ );
+
const isSelect = (row: IData) => {
const findIndex = c.state.selectedData.findIndex(data => {
return data.srfkey === row.srfkey;
@@ -47,10 +104,9 @@ export function useListRender(
Object.assign(
cardStyle,
ns.cssVarBlock({
- 'item-bg-color': `${row.bgcolor || ''}`,
- 'item-font-color': `${row.fontcolor || ''}`,
- 'item-hover-color': `${row.hovercolor || ''}`,
- 'item-active-color': `${row.activecolor || ''}`,
+ 'color-bg': `${row.bgcolor || ''}`,
+ 'color-text': `${row.fontcolor || ''}`,
+ 'color-item-active': `${row.activecolor || ''}`,
}),
);
return cardStyle;
@@ -94,6 +150,9 @@ export function useListRender(
const { context, params } = c;
const itemClass = calcItemClass(item);
const itemStyle = calcItemStyle(item);
+ if (controlStyle !== 'EXTVIEW1') {
+ itemClass.push('van-hairline--bottom');
+ }
const content = (
+
{
- const panel = c.model.itemLayoutPanel;
- return props.modelData.name !== 'simplelist' && panel
- ? renderPanelItem(row, panel)
+ return props.modelData.name !== 'simplelist' && itemLayoutPanel
+ ? renderPanelItem(row, itemLayoutPanel)
: renderItemContent(row);
};
@@ -137,8 +195,8 @@ export function useListRender(
if (!isLoaded) {
return;
}
- const ctrlModel = c.model.controls?.find(item => {
- return item.name === `${c.model.name!}_quicktoolbar`;
+ const ctrlModel = controls.find(item => {
+ return item.name === `${name!}_quicktoolbar`;
});
if (ctrlModel) {
return (
@@ -153,47 +211,114 @@ export function useListRender(
return (
isLoaded && (
)
);
};
- // 加载更多
- const loadMoreIcon = () => {
- return (
-
- c.loadMore()}>
- {ibiz.i18n.t('control.common.loadMore')}
-
-
- );
- };
-
- // 分页模式为点击加载时并且当前数量小于总数
+ // 分页模式为加载更多时并且当前数量小于总数
const renderLoadMore = () => {
let icon = null;
- const loadMore =
- c.state.items.length < c.state.total && c.state.total > c.state.size;
- if (loadMore) {
- icon = loadMoreIcon();
+ if (pagingMode === 3 && enableLoadMore.value) {
+ icon = c.loadMore()}>;
}
return icon;
};
// 添加项
const renderAddItem = (group?: IData) => {
+ if (!(c as MDCtrlController).enableNew) {
+ return null;
+ }
+ return (
+ {
+ (c as MDCtrlController).onClickNew(event, group?.key);
+ }}
+ >
+ );
+ };
+
+ const renderScrollList = (slots: IData) => {
+ if (!c.state.isLoaded) {
+ return null;
+ }
return (
-
-
{
- c.onClickNew(event, group?.key);
- }}
- >
+
c.loadMore()}
+ >
+ {slots}
+ {renderLoadMore()}
+
+ );
+ };
+
+ const renderGroup = (slots: IData) => {
+ const showGroupAnchor =
+ c.state.groups.length > 1 && (c as MDCtrlController).showGroupAnchor;
+ const content = (
+
+
+ {c.state.groups.map(group => {
+ let header = (
+
{group.caption}
+ );
+ if (showGroupAnchor) {
+ header = (
+
+ {header}
+
+ );
+ }
+ return (
+
+ {header}
+
+ {slots.children && slots.children(group.children)}
+ {renderAddItem(group)}
+
+
+ );
+ })}
+
);
+ if (showGroupAnchor) {
+ const indexList = c.state.groups.map(x => x.caption);
+ return (
+
+ {content}
+
+ );
+ }
+ return content;
};
- return { renderNoData, renderItem, renderLoadMore, renderAddItem };
+ return {
+ enableLoadMore,
+ renderNoData,
+ renderItem,
+ renderLoadMore,
+ renderAddItem,
+ renderScrollList,
+ renderGroup,
+ };
}