Skip to content

Commit 6b8a9ab

Browse files
authored
inputMultiple 增加属性inputRules (#115)
* inputMultiple 增加属性inputRules * format * labelTip 增加class参数, 实现labelTip的hover态可以点击content中的链接 * labelTip 增加class参数, 实现labelTip的hover态可以点击content中的链接 * 修改 axios版本号
1 parent 9718a56 commit 6b8a9ab

File tree

12 files changed

+285
-139
lines changed

12 files changed

+285
-139
lines changed

build/webpack.website.dev.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ module.exports = merge(webpackBaseConfig, {
4141

4242
devtool: 'eval-source-map',
4343

44+
resolve: {
45+
alias: {
46+
'@': path.resolve(__dirname, '../website'),
47+
}
48+
},
4449
// 入口
4550
entry: {
4651
main: path.resolve(__dirname, '../website/main'),

package-lock.json

Lines changed: 71 additions & 66 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/fieldGenerator.vue

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,24 @@
2222
:class="itemClasses"
2323
:style="itemStyle"
2424
>
25-
<Icon
26-
v-if="labelTip.icon"
27-
:type="labelTip.icon.name"
28-
:size="labelTip.icon.size"
29-
:color="labelTip.icon.color"
30-
@click="handleIconClick"
31-
@mouseenter.native="handleIconMouseEnter"
32-
@mouseleave.native="handleIconMouseLeave"
33-
/>
34-
<div v-if="contentShow" v-html="labelTip.content.body" />
25+
<div
26+
:class="[labelTipClasses, labelTip.class]"
27+
@mouseenter="handleIconMouseEnter"
28+
@mouseleave="handleIconMouseLeave"
29+
>
30+
<Icon
31+
v-if="labelTip.icon"
32+
:type="labelTip.icon.name"
33+
:size="labelTip.icon.size"
34+
:color="labelTip.icon.color"
35+
@click="handleIconClick"
36+
/>
37+
<div
38+
v-if="contentShow"
39+
:class="labelTipContentClasses"
40+
v-html="labelTip.content.body"
41+
/>
42+
</div>
3543
<component
3644
:is="getFieldCom(field.type)"
3745
:class="classes"
@@ -112,6 +120,12 @@ export default {
112120
itemClasses() {
113121
return `${classPrefix}-form-item`;
114122
},
123+
labelTipClasses() {
124+
return `${classPrefix}-labelTip-wp`;
125+
},
126+
labelTipContentClasses() {
127+
return `${classPrefix}-labelTip-content`;
128+
},
115129
notFormfield() {
116130
return notFormfields.includes(this.field.type);
117131
},
@@ -303,7 +317,7 @@ export default {
303317
handelListItemClick(value) {
304318
this.$emit('on-list-item-click', value);
305319
},
306-
320+
307321
308322
submit(component) {
309323
let field = component.field;

src/fields/fieldInputMultiple.vue

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
<script>
5757
import {Input, Tag} from 'iview';
5858
import {getValue} from '../utils/processValue';
59+
import schema from 'async-validator';
5960
6061
export default {
6162
inject: ['form'],
@@ -97,17 +98,63 @@ export default {
9798
this.handleAdd(e);
9899
}
99100
},
101+
// 通过field.inputRules校验
102+
validator() {
103+
let formItem = this.$parent;
104+
105+
if (typeof this.field.inputRules === 'object') {
106+
let descriptor = {};
107+
descriptor[this.field.model] = this.field.inputRules;
108+
109+
let validator = new schema(descriptor);
110+
let model = {};
111+
112+
model[this.field.model] = this.value;
113+
114+
validator.validate(model, errors => {
115+
if (errors) {
116+
this.validateMessage = errors ? errors[0].message : '';
117+
118+
formItem.validateState = 'error';
119+
formItem.validateMessage = this.validateMessage;
120+
return;
121+
} else {
122+
formItem.validateState = 'success';
123+
this.validateMessage = '';
124+
}
125+
});
126+
} else {
127+
formItem.validateState = 'success';
128+
this.validateMessage = '';
129+
}
130+
},
100131
handleAdd(e) {
101132
if (!this.value) {
102133
this.$Message.warning('请输入数据后添加');
103134
return;
104135
}
105-
if (this.list.indexOf(this.value) === -1) {
106-
this.field.succMessage && this.$Message.success(this.field.succMessage);
107-
this.list.push(this.value);
108-
this.value = '';
109-
this.$emit('on-change', this.field.model, this.list, e, this.field);
136+
if (this.list.indexOf(this.value) !== -1) {
137+
this.$Message.warning(`${this.value}已存在`);
138+
return;
110139
}
140+
if (this.defaultList.indexOf(this.value) !== -1) {
141+
this.$Message.warning(`${this.value}已存在`);
142+
return;
143+
}
144+
145+
if (!this.validateMessage) {
146+
this.addMember(e);
147+
}
148+
},
149+
addMember(e) {
150+
let formItem = this.$parent;
151+
formItem.validateState = 'success';
152+
153+
this.field.succMessage && this.$Message.success(this.field.succMessage);
154+
this.list.push(this.value);
155+
this.value = '';
156+
// this.$set(this.form.model, this.field.model, this.list);
157+
this.$emit('on-change', this.field.model, this.list, e, this.field);
111158
},
112159
handelMemberDelete(i, e) {
113160
this.list.splice(i, 1);
@@ -116,6 +163,7 @@ export default {
116163
},
117164
handleChange(e) {
118165
this.value = e.target.value;
166+
this.validator();
119167
}
120168
}
121169
};

src/style/formGeneraoter.less

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@
2626
line-height: 30px;
2727
}
2828

29+
&-labelTip-wp {
30+
position: relative;
31+
line-height: 36px;
32+
font-size: 22px;
33+
color: #00f;
34+
z-index: 11;
35+
}
36+
2937
&-default-items-box {
3038
width: 90%;
3139
display: inline-block;

website/libs/index.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* 常用工具集
3+
*/
4+
5+
// 返回对象的类型:Object、Array、String、Boolean
6+
export const getType = obj => {
7+
return Object.prototype.toString.call(obj).slice(8, -1);
8+
}
9+
10+
export const isArray = obj => {
11+
return getType(obj) === 'Array'
12+
}

website/page/doc/FieldGenerator/index.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@
144144
color: '#00f'
145145
},
146146
content: {
147+
class: 'customclass'
147148
body: <textarea><div class='example'><span>活动示意图</span></div></textarea>,
148149
ifShow: false
149150
}

website/page/examples/group-form/config.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const fields = [
1919
size: 24
2020
},
2121
content: {
22-
body: '<div class=\'example\'><span></span>What do you want others to call you?</div>',
22+
body: '<div class="example"><span></span>输入框:自定义提示</div>',
2323
ifShow: false
2424
}
2525
}
@@ -31,7 +31,18 @@ export const fields = [
3131
readonly: true,
3232
disabled: true,
3333
placeholder: '请输入用户名',
34-
defaultHide: false
34+
defaultHide: false,
35+
labelTip: {
36+
class: 'inputForbidden',
37+
icon: {
38+
name: 'ios-help-circle-outline',
39+
size: 24
40+
},
41+
content: {
42+
body: '<div class="example"><span></span>用户名:自定义提示</div>',
43+
ifShow: false
44+
}
45+
}
3546
},
3647
{
3748
type: 'Input',
@@ -54,11 +65,17 @@ export const fields = [
5465
type: 'InputMultiple',
5566
label: '多条记录输入框',
5667
model: 'inputMultiple',
57-
placeholder: '',
68+
placeholder: '输入内容必须是英文字母和数字,并且英文字母开头',
5869
required: true,
5970
defaultList: ['默认用户'],
6071
succMessage: '添加成功',
61-
delMessage: '删除成功'
72+
delMessage: '删除成功',
73+
inputRules: {
74+
type: 'string',
75+
required: true,
76+
pattern: /^[A-z]+\d*$/g,
77+
message: '输入内容必须是英文字母和数字,并且英文字母开头'
78+
},
6279
},
6380
{
6481
type: 'TimePickerMultiple',

website/page/examples/group-form/index.vue

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ export default {
9999
.container {
100100
margin: 10px 40px;
101101
width: 90%;
102+
103+
.inputForbidden .ivu-icon-ios-help-circle-outline {
104+
left: -60px;
105+
}
102106
.ivu-icon-ios-help-circle-outline {
103107
position: absolute;
104108
top: 4px;
@@ -115,21 +119,21 @@ export default {
115119
color: #fff;
116120
pointer-events: none;
117121
position: absolute;
118-
top: -38px;
119-
left: -157px;
122+
top: -28px;
123+
left: -120px;
120124
z-index: 2;
121-
word-wrap: break-word;
125+
word-wrap: break-word;
122126
border-radius: 4px;
123127
border: 1px solid #333;
124128
span {
125-
display: block;
126-
width: 0;
127-
height: 0;
128-
border-width: 5px 5px 0;
129-
border-style: solid;
130-
border-color: rgba(0, 0, 0, 0.7) transparent transparent;
131-
position: absolute;
132-
top: 34px;
129+
display: block;
130+
width: 0;
131+
height: 0;
132+
border-width: 5px 5px 0;
133+
border-style: solid;
134+
border-color: rgba(0, 0, 0, 0.7) transparent transparent;
135+
position: absolute;
136+
bottom: -5px;
133137
left: 50%;/* 三角形居中显示 */
134138
margin-left: -5px;/* 三角形居中显示 */
135139
}

website/page/examples/search-form/SearchForm.vue

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
:fields="fields"
88
@on-field-change="handelFieldChange"
99
@on-button-event="handelButtonClick"
10+
@keydown.native.enter.prevent="handelInputPress"
1011
/>
1112
<slot />
1213
<Page
@@ -22,6 +23,9 @@
2223
</template>
2324

2425
<script>
26+
import axios from 'axios';
27+
import {isArray} from '../../../libs';
28+
2529
export default {
2630
props: {
2731
model: {
@@ -49,7 +53,12 @@ export default {
4953
},
5054
data() {
5155
return {
52-
};
56+
isAjax: false
57+
}
58+
},
59+
created() {
60+
},
61+
mounted() {
5362
},
5463
methods: {
5564
// 筛选
@@ -61,11 +70,11 @@ export default {
6170
handelButtonClick() {
6271
this.fetchData();
6372
},
64-
// handelInputPress(e) {
65-
// if (e.keyCode === 13) {
66-
// this.fetchData();
67-
// }
68-
// },
73+
handelInputPress(e) {
74+
if (e.keyCode === 13) {
75+
this.fetchData();
76+
}
77+
},
6978
// 请求数据
7079
fetchData(pn) {
7180
let filterObj = {
@@ -76,11 +85,30 @@ export default {
7685
// 删除空字符串、选择全部的选项
7786
for (let key in this.model) {
7887
let cur = this.model[key];
79-
if (cur !== 'ALL' && cur !== '') {
80-
filterObj[key] = cur;
88+
if (
89+
cur !== 'ALL'
90+
&& cur !== ''
91+
&& !(isArray(cur) && cur.length === 0)
92+
) {
93+
filterObj[key] = typeof cur === 'object' ? JSON.stringify(cur) : cur;
8194
}
8295
}
8396
this.$emit('on-search-field-change', filterObj);
97+
// 如果设置了apiBase,则请求数据
98+
if (this.options.apiBase) {
99+
if (this.isAjax) {
100+
return;
101+
}
102+
this.isAjax = true;
103+
// 模拟异步请求数据
104+
axios.get(this.options.apiBase).then(res => {
105+
this.$emit('on-search-data-change', res);
106+
this.isAjax = false;
107+
}).catch(err => {
108+
this.$emit('on-search-data-error', err);
109+
this.isAjax = false;
110+
})
111+
}
84112
}
85113
},
86114
};

0 commit comments

Comments
 (0)