<script setup>
|
import { computed, inject, ref } from 'vue'
|
const props = defineProps({
|
label: [String],
|
prop: [String],
|
rules: {
|
type: Array,
|
default: []
|
},
|
required: { // 是否必填
|
type: [Boolean, Number, String],
|
default: false
|
},
|
align: { // left | right
|
default: 'right'
|
},
|
direction: {
|
default: 'row'
|
},
|
border: { // 是否有下边框
|
type: Boolean,
|
default: true
|
},
|
|
labelStyle: { // lable样式
|
type: Object,
|
default () {
|
return {}
|
}
|
},
|
})
|
const $parent = inject('$parent')
|
const formRuleRef = ref(null)
|
|
const required = computed(() => props.required || props.rules.length || ($parent.getProps('rules') || {})[props.prop])
|
const modelValue = computed(() => $parent.getModel(props.prop))
|
const showError = computed(() => $parent.getProps('showError'))
|
const itemRules = computed(() => {
|
if (!$parent) return []
|
const parentRules = $parent.getProps('rules') || {}
|
const _rules = parentRules[props.prop] || []
|
const rules = _rules ? [..._rules, ...props.rules] : props.rules
|
return rules.map(rule => {
|
if (!rule.message) {
|
rule.message = `请完善${props.label}`
|
}
|
return rule
|
})
|
})
|
const classes = computed(() => {
|
return {
|
row: props.direction == 'row',
|
col: props.direction == 'col',
|
error: (formRuleRef.value && formRuleRef.value.error && $parent.getProps('showError')),
|
boldLable: $parent.getProps('boldLable'),
|
hasBorder: $parent.getProps('border') && props.border
|
}
|
})
|
|
function check() {
|
return formRuleRef.value.check()
|
}
|
|
function getState(name) {
|
return formRuleRef.value.getState(name)
|
}
|
|
function getValid(name = 'valid') {
|
return getState(name)
|
}
|
|
function reset() {
|
formRuleRef.value.reset()
|
}
|
|
function init() {
|
$parent.addChild({ props, check, getValid, getState, reset })
|
}
|
|
init()
|
</script>
|
|
|
<template>
|
<view class="jc-form-item" :style="$parent.getProps('itemStyle')" :class="classes">
|
<view class="jc-form-item__label" :style="labelStyle" v-if="label">
|
<view class="main">
|
<text class="main__label">{{label}}</text>
|
<text class="main__required" v-if="required">*</text>
|
<slot name="label-desc"></slot>
|
</view>
|
<slot name="label-right"></slot>
|
</view>
|
<view class="jc-form-item__cont" :class="[align]" :style="$parent.getProps('itemContentStyle')">
|
<jc-form-rule ref="formRuleRef" :value="modelValue" :rules="itemRules" :model="$parent.getProps('model')">
|
<slot></slot>
|
<view :style="$parent.getProps('errorStyle')" v-if="showError && formRuleRef && formRuleRef.error">{{formRuleRef.error}}</view>
|
</jc-form-rule>
|
</view>
|
</view>
|
</template>
|
|
<style lang="scss" scoped>
|
.jc-form-item {
|
display: flex;
|
align-items: center;
|
|
&.hasBorder {
|
border-bottom: 1rpx solid RGB(237, 237, 239);
|
// transition: border-color .2s;
|
}
|
|
&.error {
|
border-bottom-color: RGB(234, 88, 11);
|
}
|
|
&.boldLable {
|
.jc-form-item__label {
|
font-size: 30rpx;
|
font-weight: 500;
|
}
|
}
|
|
&__label {
|
display: flex;
|
align-items: center;
|
padding-right: 20rpx;
|
|
.main {
|
flex: 1;
|
|
&__label {}
|
|
&__required {
|
margin-left: .1em;
|
color: RGB(234, 88, 11);
|
}
|
}
|
|
}
|
|
&__cont {
|
width: 100%;
|
|
&.right {
|
text-align: right;
|
}
|
}
|
|
&.row {
|
flex-direction: row;
|
|
.jc-form-item__label {}
|
|
.jc-form-item__cont {
|
flex: 1;
|
}
|
}
|
|
&.col {
|
flex-direction: column;
|
|
.jc-form-item__label {
|
width: 100%;
|
margin: 0 0 20rpx 0;
|
}
|
|
.jc-form-item__cont {}
|
}
|
}
|
</style>
|