|
|
<template> <view class="u-form-item"> <view class="u-form-item__body" @tap="clickHandler" :style="[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: 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: addUnit(parentData.labelPosition === 'top' ? 0 : (labelWidth || parentData.labelWidth)) }" >{{ message }}</text> </slot> <u-line v-if="borderBottom" :color="message && parentData.errorType === 'border-bottom' ? color.error : propsLine.color" :customStyle="`margin-top: ${message && parentData.errorType === 'message' ? '5px' : 0}`" ></u-line> </view> </template>
<script> import { props } from './props'; import { mpMixin } from '../../libs/mixin/mpMixin'; import { mixin } from '../../libs/mixin/mixin'; import defProps from '../../libs/config/props.js' import color from '../../libs/config/color'; import { addStyle, addUnit, getProperty, setProperty, error } from '../../libs/function/index'; /** * Form 表单 * @description 此组件一般用于表单场景,可以配置Input输入框,Select弹出框,进行表单验证等。 * @tutorial https://ijry.github.io/uview-plus/components/form.html
* @property {String} label input的label提示语 * @property {String} prop 绑定的值 * @property {String} rule 绑定的规则 * @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' }, color: color } }, // 组件创建完成时,将当前实例保存到u-form中
computed: { propsLine() { return defProps.line } }, mounted() { this.init() }, emits: ["click"], methods: { addStyle, addUnit, init() { // 父组件的实例
this.updateParentData() if (!this.parent) { error('u-form-item需要结合u-form组件使用') } }, // 获取父组件的参数
updateParentData() { // 此方法写在mixin中
this.getParentData('u-form'); }, // 移除u-form-item的校验结果
clearValidate() { this.message = null }, // 清空当前的组件的校验结果,并重置为初始值
resetField() { // 找到原始值
const value = getProperty(this.parent.originalModel, this.prop) // 将u-form的model的prop属性链还原原始值
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>
|