u-form-item.vue 5.77 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
<template>
<view class="u-form-item">
<view
class="u-form-item__body"
@tap="clickHandler"
:style="[$u.addStyle(customStyle), {
flexDirection: (labelPosition || 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';
/**
* Form 表单
* @description 此组件一般用于表单场景,可以配置Input输入框,Select弹出框,进行表单验证等。
* @tutorial https://www.uviewui.com/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: [uni.$u.mpMixin, uni.$u.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>