@neatui/vue 2.10.0 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
const props: any = withDefaults(defineProps<Props>(), {
|
|
120
120
|
modelValue: '',
|
|
121
121
|
options: () => [],
|
|
122
|
-
tools:
|
|
122
|
+
tools: false,
|
|
123
123
|
spare: '当前没有可选项',
|
|
124
124
|
search: false,
|
|
125
125
|
pagination: false,
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
verify: false,
|
|
144
144
|
prefix: () => [],
|
|
145
145
|
suffix: () => [],
|
|
146
|
-
interacted: false
|
|
146
|
+
interacted: false,
|
|
147
147
|
});
|
|
148
148
|
|
|
149
149
|
const change = ({ value = '' }: any = {}) => {
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
} else {
|
|
166
166
|
return props.options;
|
|
167
167
|
}
|
|
168
|
-
})
|
|
168
|
+
}),
|
|
169
169
|
});
|
|
170
170
|
// 选择
|
|
171
171
|
const select = (item: any = {}) => {
|
|
@@ -195,7 +195,7 @@
|
|
|
195
195
|
select,
|
|
196
196
|
remove,
|
|
197
197
|
change,
|
|
198
|
-
cancel
|
|
198
|
+
cancel,
|
|
199
199
|
});
|
|
200
200
|
</script>
|
|
201
201
|
. .
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<label ui-form="@a type:switch" class="lh-ls">
|
|
3
3
|
<input type="checkbox" name="form2" :checked="value ? true : false" />
|
|
4
|
-
<slot
|
|
4
|
+
<slot>
|
|
5
|
+
<span>{{ text }}</span>
|
|
6
|
+
</slot>
|
|
5
7
|
</label>
|
|
6
8
|
</template>
|
|
7
9
|
|
|
@@ -16,106 +18,70 @@
|
|
|
16
18
|
// 值
|
|
17
19
|
modelValue: {
|
|
18
20
|
type: [Number, Boolean],
|
|
19
|
-
default: false
|
|
21
|
+
default: false,
|
|
20
22
|
},
|
|
21
23
|
// 类型
|
|
22
24
|
type: {
|
|
23
25
|
type: String,
|
|
24
|
-
default: 'text'
|
|
26
|
+
default: 'text',
|
|
27
|
+
},
|
|
28
|
+
text: {
|
|
29
|
+
type: String,
|
|
30
|
+
default: '',
|
|
25
31
|
},
|
|
26
32
|
// 提示文案
|
|
27
33
|
tips: {
|
|
28
34
|
type: String,
|
|
29
|
-
default: ''
|
|
35
|
+
default: '',
|
|
30
36
|
},
|
|
31
37
|
// 内容占位
|
|
32
38
|
placeholder: {
|
|
33
39
|
type: String,
|
|
34
|
-
default: ''
|
|
40
|
+
default: '',
|
|
35
41
|
},
|
|
36
42
|
// 最大长度
|
|
37
43
|
maxlength: {
|
|
38
44
|
type: Number,
|
|
39
|
-
default: null
|
|
45
|
+
default: null,
|
|
40
46
|
},
|
|
41
47
|
// 最小长度
|
|
42
48
|
minlength: {
|
|
43
49
|
type: Number,
|
|
44
|
-
default: null
|
|
50
|
+
default: null,
|
|
45
51
|
},
|
|
46
52
|
// 是否禁用
|
|
47
53
|
disabled: {
|
|
48
54
|
type: Boolean,
|
|
49
|
-
default: false
|
|
55
|
+
default: false,
|
|
50
56
|
},
|
|
51
57
|
// 是否中读
|
|
52
58
|
readonly: {
|
|
53
59
|
type: Boolean,
|
|
54
|
-
default: false
|
|
60
|
+
default: false,
|
|
55
61
|
},
|
|
56
62
|
// 是否显示清除按钮
|
|
57
63
|
clearable: {
|
|
58
64
|
type: Boolean,
|
|
59
|
-
default: true
|
|
65
|
+
default: true,
|
|
60
66
|
},
|
|
61
67
|
// 校验规则
|
|
62
68
|
rules: {
|
|
63
69
|
type: Array,
|
|
64
|
-
default: () => []
|
|
70
|
+
default: () => [],
|
|
65
71
|
},
|
|
66
72
|
// 是否是示校验图标
|
|
67
73
|
verify: {
|
|
68
74
|
type: Boolean,
|
|
69
|
-
default: false
|
|
75
|
+
default: false,
|
|
70
76
|
},
|
|
71
77
|
prefix: {
|
|
72
78
|
type: Array as PropType<any[]>,
|
|
73
|
-
default: () => []
|
|
79
|
+
default: () => [],
|
|
74
80
|
},
|
|
75
81
|
suffix: {
|
|
76
82
|
type: Array as PropType<any[]>,
|
|
77
|
-
default: () => []
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
const ready: any = ref(0);
|
|
82
|
-
const state: any = computed(() => {
|
|
83
|
-
if (ready.value) {
|
|
84
|
-
// 提示文案
|
|
85
|
-
let tips = '';
|
|
86
|
-
// 错误类型
|
|
87
|
-
let type = '';
|
|
88
|
-
// 验证结果
|
|
89
|
-
let verify = '';
|
|
90
|
-
if (props.modelValue) {
|
|
91
|
-
// 有值
|
|
92
|
-
const res: any = props.rules?.some((rule: any) => {
|
|
93
|
-
const yes = rule.validator && !rule.validator(props.modelValue);
|
|
94
|
-
tips = rule.msg;
|
|
95
|
-
type = rule.type;
|
|
96
|
-
return yes;
|
|
97
|
-
});
|
|
98
|
-
verify = res ? 'no' : 'ok';
|
|
99
|
-
} else {
|
|
100
|
-
// 无值
|
|
101
|
-
const res: any = props.rules?.some((rule: any) => {
|
|
102
|
-
tips = rule.msg;
|
|
103
|
-
type = rule.type;
|
|
104
|
-
return rule.required;
|
|
105
|
-
});
|
|
106
|
-
verify = res ? 'no' : '';
|
|
107
|
-
}
|
|
108
|
-
if (verify !== 'no' && props.tips) {
|
|
109
|
-
tips = props.tips;
|
|
110
|
-
}
|
|
111
|
-
// 是否显示提示
|
|
112
|
-
const ontips = verify === 'no' && tips ? 'show' : '';
|
|
113
|
-
// 状态颜色
|
|
114
|
-
const co = verify === 'no' ? 'co:' + type : props.co ? 'co:' + props.co : '';
|
|
115
|
-
return { tips, ontips, verify, co };
|
|
116
|
-
} else {
|
|
117
|
-
return {};
|
|
118
|
-
}
|
|
83
|
+
default: () => [],
|
|
84
|
+
},
|
|
119
85
|
});
|
|
120
86
|
|
|
121
87
|
const value = ref(props.modelValue);
|
|
@@ -124,12 +90,6 @@
|
|
|
124
90
|
() => props.modelValue,
|
|
125
91
|
(newValue) => {
|
|
126
92
|
value.value = newValue;
|
|
127
|
-
}
|
|
93
|
+
},
|
|
128
94
|
);
|
|
129
|
-
|
|
130
|
-
onMounted(() => {
|
|
131
|
-
setTimeout(() => {
|
|
132
|
-
ready.value = 1;
|
|
133
|
-
}, 300);
|
|
134
|
-
});
|
|
135
95
|
</script>
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
:col-fixed-side="col.fixed || 'l'"
|
|
88
88
|
:data-field="col.field"
|
|
89
89
|
>
|
|
90
|
-
<slot :name="col.field" :col="col" :item="item" :idx="idx"><TableRender :
|
|
90
|
+
<slot :name="col.field" :col="col" :item="item" :idx="idx"><TableRender :node="col" :data="item" /></slot>
|
|
91
91
|
</td>
|
|
92
92
|
</template>
|
|
93
93
|
<td v-if="slots.operate" col-fixed="r" class="ar"><slot name="operate" :item="item" :idx="idx"></slot></td>
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
<tr v-if="!col.__close">
|
|
128
128
|
<td class="nowrap vt n-ss">{{ col.label }}:</td>
|
|
129
129
|
<td class="n-ss">
|
|
130
|
-
<TableRender :
|
|
130
|
+
<TableRender :node="col" :data="item" />
|
|
131
131
|
</td>
|
|
132
132
|
</tr>
|
|
133
133
|
</template>
|
|
@@ -167,14 +167,14 @@
|
|
|
167
167
|
field: string | (() => string);
|
|
168
168
|
width?: string | (() => string);
|
|
169
169
|
fixed?: string | (() => string);
|
|
170
|
-
thead?: object | (() => object);
|
|
171
|
-
tbody?: object | (() => object);
|
|
172
170
|
paths?: string | (() => string);
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
171
|
+
thead?: Record<string, any> | ((data: any) => Record<string, any>);
|
|
172
|
+
tbody?: Record<string, any> | ((data: any) => Record<string, any>);
|
|
173
|
+
model?: string | any[] | ((data: any) => string | any[]);
|
|
174
|
+
enums?: any[] | ((data: any) => any[]);
|
|
175
|
+
rules?: any[] | ((data: any) => any[]);
|
|
176
|
+
event?: Record<string, any> | ((data: any) => Record<string, any>);
|
|
177
|
+
attrs?: Record<string, any> | ((data: any) => Record<string, any>);
|
|
178
178
|
value?: any | (() => any);
|
|
179
179
|
clear?: boolean | (() => boolean);
|
|
180
180
|
order?: 0 | 1 | 2 | number | (() => 0 | 1 | 2 | number);
|
|
@@ -268,6 +268,11 @@
|
|
|
268
268
|
state.__last = 0;
|
|
269
269
|
state.table = deepcopy(props.table || [])
|
|
270
270
|
?.map((col: TableColumn, idx: number) => {
|
|
271
|
+
// 标题处理
|
|
272
|
+
if (isFunction(col.label)) {
|
|
273
|
+
col.label = col.label(props.lists);
|
|
274
|
+
}
|
|
275
|
+
|
|
271
276
|
// 表头属性处理
|
|
272
277
|
col.thead ??= {};
|
|
273
278
|
col.thead.class = (col.thead.class || '').split(/\s+/);
|
|
@@ -1,61 +1,43 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<template v-if="isArray(
|
|
3
|
-
<div
|
|
4
|
-
<TableRender v-for="(sub, idx) in
|
|
2
|
+
<template v-if="isArray(node.child)">
|
|
3
|
+
<div v-bind="attrs" v-on="event" v-memo="[node.child, data]">
|
|
4
|
+
<TableRender v-for="(sub, idx) in node.child" :key="idx" :node="sub" :data="data" />
|
|
5
5
|
</div>
|
|
6
6
|
</template>
|
|
7
|
-
<template v-else-if="
|
|
8
|
-
<IFollowView>
|
|
9
|
-
<TableRender :
|
|
7
|
+
<template v-else-if="node.popup">
|
|
8
|
+
<IFollowView v-memo="[node.popup, data]">
|
|
9
|
+
<TableRender :node="{ ...node, popup: null }" :data="data" />
|
|
10
10
|
<template #tips>
|
|
11
|
-
<TableRender :
|
|
11
|
+
<TableRender :node="isFunction(node.popup) ? node.popup(data) : node.popup" :data="data" />
|
|
12
12
|
</template>
|
|
13
13
|
</IFollowView>
|
|
14
14
|
</template>
|
|
15
15
|
<template v-else>
|
|
16
|
-
<div v-if="
|
|
17
|
-
<
|
|
16
|
+
<div v-if="model.value" v-bind="attrs" v-on="event">
|
|
17
|
+
<div v-if="model.value === 'image'" ui-cover="1:1" v-bind="model.attrs">
|
|
18
|
+
<div class="pa full bg-case-ls r-sm ot-no ol-no" :class="state.isloaded ? 'o-no' : 'o-ms'" ui-flex="col cm"><i ui-load="@d"></i></div>
|
|
19
|
+
<img ref="img" class="r-sm" :src="value" @load="state.isloaded = 1" />
|
|
20
|
+
</div>
|
|
21
|
+
<label v-else-if="model.value === 'switch'" ui-form="@a type:switch" @click.prevent>
|
|
22
|
+
<input type="checkbox" :checked="value" />
|
|
23
|
+
<span v-if="model.attrs?.label">{{ model.attrs?.label }}</span>
|
|
24
|
+
</label>
|
|
18
25
|
</div>
|
|
19
|
-
<div v-else
|
|
26
|
+
<div v-else v-bind="attrs" v-on="event" v-html="value"></div>
|
|
20
27
|
</template>
|
|
21
28
|
</template>
|
|
22
29
|
<script lang="ts" setup>
|
|
23
|
-
import { computed } from 'vue';
|
|
24
|
-
import { isFunction, isArray, isObject,
|
|
30
|
+
import { computed, onMounted, reactive, ref } from 'vue';
|
|
31
|
+
import { isFunction, isArray, isObject, isString, findEnumName } from '@fekit/utils';
|
|
25
32
|
import { useRoute, useRouter } from 'vue-router';
|
|
26
33
|
import TableRender from './TableRender.vue';
|
|
27
34
|
import { IFollowView } from '../../basic';
|
|
28
35
|
|
|
29
|
-
const DefaultImage =
|
|
30
|
-
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKYAAACmBAMAAACipulEAAAAHlBMVEXMzMz////z8/Pf39/Z2dnS0tLq6urk5OTu7u74+PjCLuPVAAABxUlEQVRo3u2YsUsDMRSHX9Wzupn22qObVxAd7SCuV1BwvGrVtQcqjlYQHFVEVzv575qklReE9urlFTL8vqUvQz+Se3m5yyMAAAAAAAAAAAAAsFIu7rvz+DiqprxSi7itotxQi8kqOHslzqbHNAUnul3q/PJYutzi01Jn47/KSBm+jxep8yopSojqgklaV5qRDor5zsMKTru4gazTJmEtfKcyQU3Waf/UE3bGXPb7p5fDRwmnuhkWyvJEhmt/JzOiKZtyzph+6Us5O1zY0UTI2TKy5+4nl5W/M9PpT00NmEDG2dbDgiMR5w7R1ix84brycz7oyfGU6yLO3HmIGUUSzoY9m3jxqYAzsRuIt9VYwBm7Z1OTB57Owt1XfQFn649zEOg8YzctiYyz6Wpizxzxcmtunb5K1JGtR65TkdrMiCazsMOHnZ9zlx9ozHXq5XTfyBnr/ZwdPTy30Z6OJr5OfhOf6d934tPZ15mQJjrJSVN4O3mi/NEg5GzkNCVKBZy8estYeTuZdmbuDYWScDIHd29KSTmZEJ26GsUvxpEqJw/gDrvMXTuInsASvYsgeizlvaBAelZlvTUAAAAAAAAAAAAAsEp+AEDOpCBEwOONAAAAAElFTkSuQmCC';
|
|
31
|
-
|
|
32
|
-
// 通过枚举值查找枚举名
|
|
33
|
-
const findEnumName = (enums: any, val: any, join: boolean | string = ' Ι ') => {
|
|
34
|
-
// 转换核心
|
|
35
|
-
const _core = (v: any) => {
|
|
36
|
-
const { label = v }: any = enums.find(({ value = '' }: any) => value == v) || {};
|
|
37
|
-
return label;
|
|
38
|
-
};
|
|
39
|
-
// 判断枚举字典是否可用
|
|
40
|
-
if (enums && enums.find) {
|
|
41
|
-
// 兼容多种入参类型
|
|
42
|
-
if (isArray(val)) {
|
|
43
|
-
// 数组
|
|
44
|
-
const arr = val.map((i: any) => _core(i));
|
|
45
|
-
return join ? arr.join(join) : arr;
|
|
46
|
-
} else {
|
|
47
|
-
return _core(val);
|
|
48
|
-
}
|
|
49
|
-
} else {
|
|
50
|
-
return val;
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
36
|
const route = useRoute();
|
|
55
37
|
const router = useRouter();
|
|
56
38
|
|
|
57
39
|
const props: any = defineProps({
|
|
58
|
-
|
|
40
|
+
node: {
|
|
59
41
|
type: Object,
|
|
60
42
|
default: () => ({}),
|
|
61
43
|
},
|
|
@@ -65,47 +47,95 @@
|
|
|
65
47
|
},
|
|
66
48
|
});
|
|
67
49
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
50
|
+
const img = ref<HTMLImageElement | null>(null);
|
|
51
|
+
onMounted(() => {
|
|
52
|
+
if (img.value) {
|
|
53
|
+
state.isloaded = img.value.complete && img.value.naturalWidth > 0 ? 1 : 0;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const state: any = reactive({
|
|
58
|
+
isloaded: 0,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// 属性处理
|
|
62
|
+
const attrs = computed(() => {
|
|
63
|
+
const a = props.node.attrs;
|
|
64
|
+
let attrs = isFunction(a) ? a?.(props.data) : a;
|
|
65
|
+
|
|
66
|
+
// 确保 attrs 存在
|
|
67
|
+
if (!attrs) attrs = {};
|
|
68
|
+
else attrs = { ...attrs };
|
|
69
|
+
|
|
70
|
+
// 处理 class 属性
|
|
71
|
+
if (attrs.class) {
|
|
72
|
+
attrs.class = attrs.class.split(/\s+/);
|
|
73
|
+
if (!attrs.class.some((c: string) => c === 'wrap' || c === 'nowrap')) {
|
|
74
|
+
attrs.class.push('nowrap');
|
|
77
75
|
}
|
|
78
|
-
} else
|
|
79
|
-
|
|
76
|
+
} else {
|
|
77
|
+
attrs.class = ['nowrap'];
|
|
80
78
|
}
|
|
81
|
-
return obj;
|
|
82
|
-
};
|
|
83
79
|
|
|
84
|
-
|
|
80
|
+
return attrs;
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// 模型处理
|
|
84
|
+
const model: any = computed(() => {
|
|
85
|
+
const m = props.node.model;
|
|
86
|
+
if (!m) return { value: '', attrs: {} };
|
|
87
|
+
|
|
88
|
+
const model = isFunction(m) ? m(props.data) : m;
|
|
85
89
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
let value = '';
|
|
91
|
+
let attrs = {};
|
|
92
|
+
if (isString(model)) {
|
|
93
|
+
value = model;
|
|
94
|
+
} else if (isArray(model)) {
|
|
95
|
+
value = model[0] ?? '';
|
|
96
|
+
attrs = isObject(model[1]) ? model[1] : {};
|
|
97
|
+
}
|
|
98
|
+
value = value.toString().toLowerCase();
|
|
99
|
+
|
|
100
|
+
return { value, attrs };
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// 枚举处理
|
|
104
|
+
const enums = computed(() => {
|
|
105
|
+
const e = props.node.enums;
|
|
106
|
+
return isFunction(e) ? e(props.data) : e;
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// 数值处理
|
|
110
|
+
const value = computed(() => {
|
|
111
|
+
const n = props?.node;
|
|
112
|
+
const v = props?.data?.[n.field];
|
|
113
|
+
return n?.value !== null && n?.value !== undefined
|
|
114
|
+
? isFunction(n?.value)
|
|
115
|
+
? n?.value(props?.data)
|
|
116
|
+
: n?.value
|
|
117
|
+
: findEnumName(enums.value, v) !== null && findEnumName(enums.value, v) !== undefined
|
|
118
|
+
? findEnumName(enums.value, v)
|
|
93
119
|
: '‐‐';
|
|
94
|
-
};
|
|
120
|
+
});
|
|
95
121
|
|
|
96
|
-
// 事件处理
|
|
97
|
-
const event
|
|
98
|
-
|
|
99
|
-
if (
|
|
100
|
-
|
|
101
|
-
|
|
122
|
+
// 事件处理 (直接使用 computed)
|
|
123
|
+
const event = computed(() => {
|
|
124
|
+
let e = props.node.event;
|
|
125
|
+
if (isFunction(e)) {
|
|
126
|
+
e = e(props.data);
|
|
127
|
+
}
|
|
128
|
+
const events: any = {};
|
|
129
|
+
if (isObject(e)) {
|
|
130
|
+
for (const key in e) {
|
|
131
|
+
const fun = e[key];
|
|
102
132
|
if (isFunction(fun)) {
|
|
103
|
-
|
|
104
|
-
return fun({ data, route, router }, ...args);
|
|
133
|
+
events[key] = (...args: any) => {
|
|
134
|
+
return fun({ data: props.data, route, router }, ...args);
|
|
105
135
|
};
|
|
106
136
|
}
|
|
107
137
|
}
|
|
108
138
|
}
|
|
109
|
-
return
|
|
110
|
-
};
|
|
139
|
+
return events;
|
|
140
|
+
});
|
|
111
141
|
</script>
|