u-form-item.vue
5.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
<template>
<view class="u-form-item">
<view
class="u-form-item__body"
@tap="clickHandler"
:style="[$u.addStyle(customStyle), {
flexDirection: parentData.labelPosition === 'left' ? 'row' : 'column'
}]"
>
<!-- 微信小程序中,将一个参数设置空字符串,结果会变成字符串"true" -->
<slot name="label">
<!-- {{required}} -->
<view
class="u-form-item__body__left"
v-if="required || leftIcon || label"
:style="{
width: $u.addUnit(labelWidth || parentData.labelWidth),
marginBottom: parentData.labelPosition === 'left' ? 0 : '5px',
}"
>
<!-- 为了块对齐 -->
<view class="u-form-item__body__left__content">
<!-- nvue不支持伪元素before -->
<text
v-if="required"
class="u-form-item__body__left__content__required"
>*</text>
<view
class="u-form-item__body__left__content__icon"
v-if="leftIcon"
>
<u-icon
:name="leftIcon"
:custom-style="leftIconStyle"
></u-icon>
</view>
<text
class="u-form-item__body__left__content__label"
:style="[parentData.labelStyle, {
justifyContent: parentData.labelAlign === 'left' ? 'flex-start' : parentData.labelAlign === 'center' ? 'center' : 'flex-end'
}]"
>{{ label }}</text>
</view>
</view>
</slot>
<view class="u-form-item__body__right">
<view class="u-form-item__body__right__content">
<view class="u-form-item__body__right__content__slot">
<slot />
</view>
<view
class="item__body__right__content__icon"
v-if="$slots.right"
>
<slot name="right" />
</view>
</view>
</view>
</view>
<slot name="error">
<text
v-if="!!message && parentData.errorType === 'message'"
class="u-form-item__body__right__message"
:style="{
marginLeft: $u.addUnit(parentData.labelPosition === 'top' ? 0 : (labelWidth || parentData.labelWidth))
}"
>{{ message }}</text>
</slot>
<u-line
v-if="borderBottom"
:color="message && parentData.errorType === 'border-bottom' ? $u.color.error : propsLine.color"
:customStyle="`margin-top: ${message && parentData.errorType === 'message' ? '5px' : 0}`"
></u-line>
</view>
</template>
<script>
import props from './props.js';
import mpMixin from '../../libs/mixin/mpMixin.js';
import mixin from '../../libs/mixin/mixin.js';
/**
* Form 表单
* @description 此组件一般用于表单场景,可以配置Input输入框,Select弹出框,进行表单验证等。
* @tutorial https://ijry.github.io/uview-plus/components/form.html
* @property {String} label input的label提示语
* @property {String} prop 绑定的值
* @property {String | Boolean} borderBottom 是否显示表单域的下划线边框
* @property {String | Number} labelWidth label的宽度,单位px
* @property {String} rightIcon 右侧图标
* @property {String} leftIcon 左侧图标
* @property {String | Object} leftIconStyle 左侧图标的样式
* @property {Boolean} required 是否显示左边的必填星号,只作显示用,具体校验必填的逻辑,请在rules中配置 (默认 false )
*
* @example <u-form-item label="姓名" prop="userInfo.name" borderBottom ref="item1"></u-form-item>
*/
export default {
name: 'u-form-item',
mixins: [mpMixin, mixin, props],
data() {
return {
// 错误提示语
message: '',
parentData: {
// 提示文本的位置
labelPosition: 'left',
// 提示文本对齐方式
labelAlign: 'left',
// 提示文本的样式
labelStyle: {},
// 提示文本的宽度
labelWidth: 45,
// 错误提示方式
errorType: 'message'
}
}
},
// 组件创建完成时,将当前实例保存到u-form中
computed: {
propsLine() {
return uni.$u.props.line
}
},
mounted() {
this.init()
},
methods: {
init() {
// 父组件的实例
this.updateParentData()
if (!this.parent) {
uni.$u.error('u-form-item需要结合u-form组件使用')
}
},
// 获取父组件的参数
updateParentData() {
// 此方法写在mixin中
this.getParentData('u-form');
},
// 移除u-form-item的校验结果
clearValidate() {
this.message = null
},
// 清空当前的组件的校验结果,并重置为初始值
resetField() {
// 找到原始值
const value = uni.$u.getProperty(this.parent.originalModel, this.prop)
// 将u-form的model的prop属性链还原原始值
uni.$u.setProperty(this.parent.model, this.prop, value)
// 移除校验结果
this.message = null
},
// 点击组件
clickHandler() {
this.$emit('click')
}
},
}
</script>
<style lang="scss" scoped>
@import "../../libs/css/components.scss";
.u-form-item {
@include flex(column);
font-size: 14px;
color: $u-main-color;
&__body {
@include flex;
padding: 10px 0;
&__left {
@include flex;
align-items: center;
&__content {
position: relative;
@include flex;
align-items: center;
padding-right: 10rpx;
flex: 1;
&__icon {
margin-right: 8rpx;
}
&__required {
position: absolute;
left: -9px;
color: $u-error;
line-height: 20px;
font-size: 20px;
top: 3px;
}
&__label {
@include flex;
align-items: center;
flex: 1;
color: $u-main-color;
font-size: 15px;
}
}
}
&__right {
flex: 1;
&__content {
@include flex;
align-items: center;
flex: 1;
&__slot {
flex: 1;
/* #ifndef MP */
@include flex;
align-items: center;
/* #endif */
}
&__icon {
margin-left: 10rpx;
color: $u-light-color;
font-size: 30rpx;
}
}
&__message {
font-size: 12px;
line-height: 12px;
color: $u-error;
}
}
}
}
</style>