Open 02020 opened 3 years ago
/**
* iview-卡片标题
* @param {*} title
* @param {*} extra
*/
export const Card = ({ title, extra, child }) => ({
component: 'Card',
child: [
title && toSlot('title', title, [['click', 'click-title']]),
extra && toSlot('extra', extra, [['click', 'click-extra']]),
child,
],
});
/**
* iview-折叠面板
* @param {*} value
*/
export const Collapse = (value = []) => (child) => ({
key: 'temp',
component: 'Collapse',
props: {
value,
},
on: ['on-change', ['input', 'input-collapse']],
child: child,
});
/**
* iview-折叠面板-项
* @param {*} name
* @param {*} title
*/
export const Panel = ({ name = '', child, title = '标题' }, index) => ({
component: 'Panel',
props: { name: name + '_' + index },
child: [title, toSlot('content', child)],
});
/**
* iview-折叠面板-项
* @param {*} name
* @param {*} title
*/
export const PanelC = (name, title, index) => (child) =>
Panel({ name, child, title }, index);
/**
* iview-列表
* @param {*} props
*/
export const List = (props) => (child) => ({
component: 'List',
style: props.style,
class: props.class,
props: {
itemLayout: 'vertical',
...props,
},
child: child,
});
/**
* iview-列表-列表项
* @param {*} param0
*/
export const ListItem = ({ action, extra, avatar, title, description }) => {
return {
component: 'ListItem',
child: [
{ slot: 'action', child: action }, // 只能这样配置
{ slot: 'extra', child: extra, on: [['click', 'click-extra']] }, // 只能这样配置
{
component: 'ListItemMeta',
child: [
{
slot: 'avatar',
child: avatar,
},
{ slot: 'title', child: title },
{ slot: 'description', child: description },
],
},
],
};
};
/**
*
* @param {*} cb
* @param {*} option 默认配置
* @param {*} f 对默认配置option进行处理
* @returns {Array} [option, option]
* @demo 渲染本级
*/
export const fMap = (f, cb = (x) => x) => (list) => cb(list.map(f));
/**
* iview-图标
* @param {*} type
* @param {*} size
* @param {*} color
*/
export const Icon = (props) => {
const { type, size = 30, color = '#2d8cf0' } = props;
return {
key: props.key || props.name,
class: props.class,
attrs: {
title: props.title,
},
component: 'Icon',
on: [['click', 'icon-click']],
props: {
type,
size,
color,
},
};
};
/**
* iview-图标-主要供map函数使用
* @param {*} size
* @param {*} color
*/
export const IconC = (size = 30, color = '#2d8cf0') => ({ title, type }) =>
Icon({ title, type, size, color });
/**
* 带卡片样式的折叠面板
* @param {*} props
*/
export const toCollapseCard = (props) =>
fMap(
(x, index) => fMap(Card, PanelC(x.name, x.title, index))(x.child),
Collapse(props.value)
);
/**
* 折叠面板
* @param {*} props
*/
export const toCollapse = (props) => fMap(Panel, Collapse(props.value));
/**
* 列表
* @param {*} fStyle
*/
export const toList = (props, fStyle) =>
fMap((x) => ListItem(fStyle(x)), List(props));
// 组件的配置清单,供Render使用
export const toSlot = (name, child, on = []) => ({
slot: name,
child: child,
on,
});
/**
*
* @param {*} item
* @param {*} _class
*/
const toStyle = (item, _class = '') => (child) => {
return {
class: (item.class || item) + _class,
style: item.style,
child: child,
};
};
/**
* 1-表格
* @param {*} param0
*/
export const toETable = ({ table, row, col }) =>
fMap(toRow({ row, col }), toStyle(table));
/**
* 2-表格-行
* @param {*} param0
*/
export const toRow = ({ row, col }) => fMap(toCol(col), toStyle(row));
/**
* 3-表格-列
* 待完善与优化
* @param {*} col
*/
export const toCol = (col) => (cell) => {
// 数据格式转换, x为数组
const [key, _class, child] = cell;
return {
on: ['click'],
key,
style: col.style,
class: col.class || col + _class,
child,
};
};
<template>
<div>
<to-render :f="null" :schema="schema" @cmd="onCMD" />
<hr style="margin: 20px 0" />
<to-render
:f="dataOne.f"
:props="dataOne.props"
:schema="dataOne.schema"
@cmd="onCMD"
/>
</div>
</template>
<script>
import { toRender, toFunctional, toETable } from '../';
// 构造demo数据
const rowData = [
['a', 'bg-green-500', '01室'],
['b', 'bg-red-500', '02室'],
['c', 'bg-blue-500', '03室'],
];
const floor = (r) => (x) => {
const xx = [...x];
xx[2] = r + xx[2];
return xx;
};
const dataC = (r) => rowData.map(floor(r));
// 配置样式
const style = {
table: {
class: 'border border-blue-500',
style: { width: '500px' },
},
row: 'grid grid-cols-6',
col: 'text-sm font-semibold text-center py-2 m-px text-white ',
};
export default {
components: { toRender: toRender() },
data() {
return {
schema: toETable(style)([dataC(6), dataC(5)]),
dataOne: {
f: toETable,
on: this.onCMD,
props: style,
schema: [dataC(6), dataC(5)],
},
};
},
methods: {
onCMD(name, ...args) {
console.log('onCMD:' + name, ...args);
},
},
};
</script>
<template>
<div>
<e-render :props="dataOne.props" :on="dataOne.on" :schema="dataOne.schema">
</e-render>
<hr style="margin: 20px 0" />
<e-table
:props="dataTable.props"
:on="dataTable.on"
:schema="dataTable.schema"
>
</e-table>
<Button @click="onClick">点击</Button>
</div>
</template>
<script>
import { toRender, toFunctional, toComponent, toCollapse, toETable } from '../';
// 构造demo数据
const rowData = [
['a', 'bg-green-500', '01室'],
['b', 'bg-red-500', '02室'],
['c', 'bg-blue-500', '03室'],
];
const floor = (r) => (x) => {
const xx = [...x];
xx[2] = r + xx[2];
return xx;
};
const dataC = (r) => rowData.map(floor(r));
// 配置样式
const style = {
table: {
class: 'border border-blue-500',
style: { width: '500px' },
},
row: 'grid grid-cols-6',
col: 'text-sm font-semibold text-center py-2 m-px text-white ',
};
export default {
components: {
'e-render': toComponent(toCollapse),
'e-table': toComponent(toETable),
},
data() {
return {
dataOne: {
f: toCollapse,
on: this.onCMD,
props: {
key: 'ddd',
},
schema: [{ name: 'dd', child: 'ss', title: '我是标题-1' }],
},
dataTable: {
on: this.onCMD,
props: style,
schema: [dataC(6), dataC(5)],
},
};
},
methods: {
onCMD(name, ...args) {
console.log('onCMD:' + name, ...args);
},
onClick() {
// this.dataOne.schema[0].title = '我是标题-' + +new Date();
this.dataTable.schema = [dataC(4)]
},
},
};
</script>
<template>
<div>
<to-render :f="null" :schema="schema" :on="onCMD" @cmd="onCMD" />
<Button @click="onClickSchema">schema</Button>
<hr style="margin: 20px 0" />
<to-render
:f="dataOne.f"
:props="dataOne.props"
:on="dataOne.on"
:schema="dataOne.schema"
@cmd="onCMD"
/>
<Button @click="onClick">点击</Button>
<hr style="margin: 20px 0" />
</div>
</template>
<script>
import { toRender, toFunctional, toComponent, toCollapse } from '../';
const schema = {
component: 'Collapse',
on: ['on-change'],
child: [
{
component: 'Panel',
child: [
'我是标题-1',
{
slot: 'content',
child: 'slot="content"是组件[Panel-slot]中的组件名 ',
},
],
},
{
component: 'Panel',
child: [
'我是标题-2',
{
slot: 'content',
child: '这里是内容, 可以放组件',
},
],
},
],
};
export default {
components: {
toRender: toRender(),
},
data() {
return {
schema: schema,
dataOne: {
f: toCollapse,
on: this.onCMD,
props: {
key: 'ddd',
},
schema: [
{ name: 'dd', child: 'ss', title: '我是标题-1' },
{ name: 'dd', child: 'ss', title: '我是标题-2' },
{ name: 'dd', child: 'ss', title: '我是标题-3' },
],
},
};
},
methods: {
onCMD(name, ...args) {
console.log('onCMD:' + name, ...args);
},
onClickSchema() {
this.schema.child[0].child[0] = '我是标题-' + +new Date();
},
onClick() {
this.dataOne.schema[0].title = '我是标题-' + +new Date();
},
},
};
</script>
<template>
<div>
<to-render v-bind="dataOne"> </to-render>
<hr style="margin: 20px 0" />
<to-render v-bind="dataSchema"> </to-render>
<Button @click="onClick">点击</Button>
</div>
</template>
<script>
import { toRender, toCollapseCard, toETable, toRow } from '../';
// 构造demo数据
const rowData = [
['a', 'bg-green-500', '01室'],
['b', 'bg-red-500', '02室'],
['c', 'bg-blue-500', '03室'],
];
const floor = (r) => (x) => {
const xx = [...x];
xx[2] = r + xx[2];
return xx;
};
const dataC = (r) => rowData.map(floor(r));
// 配置样式
const style = {
table: {
class: 'border border-blue-500',
style: { width: '500px' },
},
row: 'grid grid-cols-6',
col: 'text-sm font-semibold text-center py-2 m-px text-white ',
};
// 数据组装
const schema = [
{
name: 'a',
title: '分组-标题1',
child: [
{
title: '标题1',
child: toETable(style)([dataC(6), dataC(5)]),
},
{
title: '标题2',
extra: '离开',
child: toETable(style)([dataC(6), dataC(5)]),
},
],
},
{
name: 'b',
title: '分组-标题2',
child: [{ title: '标题1', extra: '离开', child: toRow(style)(dataC(8)) }],
},
];
const Icon = {
component: 'Icon',
props: {
type: 'md-cart',
size: '22',
},
};
const schemaFull = {
component: 'Collapse',
on: ['on-change'],
props: {
value: 'c',
},
child: [
{
component: 'Panel',
props: { name: 'c' },
child: [
'我是标题',
{
slot: 'content',
child: [
{
component: 'Card',
child: [
{ slot: 'title', child: toRow(style)(dataC(1)) },
{
slot: 'extra',
on: [['click', 'click-title']],
child: Icon,
},
toETable(style)([dataC(6), dataC(5)]),
'---',
toETable(style)([dataC(8), dataC(7)]),
],
},
'---',
{
component: 'Card',
child: [
{ slot: 'title', child: toRow(style)(dataC(2)) },
{
slot: 'extra',
child: Icon,
on: [['click', 'click-title']],
},
toETable(style)([dataC(5), dataC(4)]),
],
},
],
},
],
},
],
};
export default {
components: { toRender: toRender() },
data() {
return {
dataOne: {
f: toCollapseCard,
on: this.onCMD,
props: {
value: 'a_0',
},
schema: schema,
},
dataSchema: {
f: null,
on: this.onCMD,
props: {
key: 'ddd',
},
schema: schemaFull,
},
};
},
methods: {
onCMD(name, ...args) {
console.log('onCMD:' + name, ...args);
},
onClick() {
this.flag = !this.flag;
this.dataOne.props = {
value: this.flag ? 'b_1' : 'a_0',
};
},
},
};
</script>
schemaRender
根据数据结构 schema,执行渲染