uni-ui icon indicating copy to clipboard operation
uni-ui copied to clipboard

关于 from 表单 无法校验的问题

Open 13799433448 opened this issue 3 years ago • 7 comments

环境:

uni-ui: 1.4.14 vue: 3.2.33

问题代码:

  1. 使用 uni-ui 提供的 uni-easyinput 发现无法进行校验
<template>
     <uni-forms ref="baseForm" :modelValue="baseFormData" :rules="customRules" label-width="80" label-align="right">
        <uni-forms-item :label="`${requestLabel}事由:`" name="reason">
                <uni-easyinput type="textarea" v-model="baseFormData.reason" placeholder="事由" />
         </uni-forms-item>
    </uni-forms>
    <button @click="submit" :loading="loading">提交</button>
</template>
<script setup lang="ts">
const baseFormData = reactive<workAttendanceAddDTO>({
  attendanceType: 0, // 申请类型
  projectCode: '',
  approvalEmployeeCode: '', // 审批人code
  approvalEmployeeName: '', // 审批人
  attendanceTimeStart: '',
  attendanceTimeEnd: '',
  reason: '',
});
const customRules = {
  reason: {
      rules: [
        {
          required: true,
          errorMessage: '事由不能为空',
        },
      ],
    }
}
// 提交
function submit() {
  baseForm.value
    .validate()
    .then(async (res: workAttendanceAddDTO) => {
      const { code } = await workAttendanceAdd(res);
      if (code == 0) {
        // 在C页面内 navigateBack,将返回A页面
        uni.navigateBack({
          delta: 1,
        });
      }
    })
    .catch((err: any) => {
      console.log('err', err);
    });
}
</script>

再点击的时候无法触发校验,效果如下: image

  1. 自定义校验组件无法触发校验效果:使用onFieldChange或者setValue都无法触发正确的校验效果 自定义组件(下拉选择):
<template>
  <view class="picker" @click="open">
    {{ activeTitle }}
  </view>
  <view
    class="overlay"
    :class="!show && 'hide'"
    @touchmove.prevent
  >
  <view v-show="show" class="picker-box" :class="[showCloseBtn && 'show-btn', show ? 'fade-Up' : '']">
    <view class="main-desc picker-title">
      {{ title }}
      <uni-icons type="closeempty" size="14" @click="close"></uni-icons>
    </view>
    <view class="picker-list">
      <view
        v-for="item in props.list"
        :key="item[props.valueKey]"
        class="list-item"
        :class="{ 'active': modelValue == item[props.valueKey] }"
        @click="change(item)"
      >
          <slot :item="item">
          {{ item[props.valueLabel] }}
          </slot>
      </view>
    </view>
    <slot name="bottom">
    </slot>
  </view>
  </view>
</template>

<script setup lang="ts">
import { computed, ref, inject } from 'vue';
const  props = defineProps({
  title: {
    type: String,
    default: '请选择',
  },
  list: {
    default: () => new Array<any>(),
  },
  modelValue: {
    type: [Number, String],
    default: undefined,
  },
  immediate: {
    type: Boolean,
    default: true,
  },
  showCloseBtn: {
    type: Boolean,
    default: true,
  },
  // 返回值
  valueKey: {
    type: String,
    default: 'value',
  },
  // 显示值
  valueLabel: {
    type: String,
    default: 'text',
  },
});
const emits = defineEmits(['update:modelValue', 'change']);
// 兼容form 表单
const form = inject<any>('uniForm', null);
const formItem = inject<any>('uniFormItem', null);
// 计算值
const activeTitle = computed(() => {
  const patch = props.list.find(v => props.modelValue === v[props.valueKey]);
  return patch ? patch[props.valueLabel] : '请选择';
});

// 处理点击弹幕
const show = ref(false);

function open(){
  show.value = true;
}
function close(){
  show.value = false;
}

// 事件触发
const change = (data: any) => {
  emits('update:modelValue', data[props.valueKey]);
  emits('change', data);
  if (props.immediate) {
    show.value = false;
  }
  if (form && formItem) {
    // console.log(formItem);
    const { name } = formItem;
    console.log(name);
    // formItem.onFieldChange(name, data[props.valueKey]);
    formItem.setValue(name, data[props.valueKey]);
  }
};
</script>

<style lang="scss" scoped>
@keyframes faseDown {
  from {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }

  to {
    -webkit-transform: translate3d(0, 100%, 0);
    transform: translate3d(0, 100%, 0);
  }
}

@keyframes fadeUp {
  from {
    -webkit-transform: translate3d(0, 100%, 0);
    transform: translate3d(0, 100%, 0);
  }

  to {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}

@keyframes height {
  from {
    max-height: 0;
  }

  to {
    max-height: 900rpx;
  }
}

.picker {
  display: flex;
  align-items: center;
  padding: 0 10px;
  height: 35px;
  border-radius: 4px;
  border: 1px solid #E4E7ED;
  color: #666;
  font-size: 14px;
}


.picker-box {
  transition: height 1s;
  border-radius: 8px 8px 0px 0px;
  background: #fff;
  z-index: 1001;
  position: fixed;
  overflow: hidden;
  width: 100%;
  max-height: 900rpx;
  left: 0;
  bottom: 0;
  color: #2f3437;

  &.fade-Up {
    animation-name: fadeUp;
    animation-duration: 0.3s;
  }

  &.fase-down {
    animation-name: faseDown;
    animation-duration: 0.3s;
  }

  &.show-btn {
    padding-bottom: 130rpx;
  }

  .picker-title {
    padding: 10px;
    font-weight: bold;
    border: 1px solid #f2f2f2;
    display: flex;
    justify-content: space-between;
  }

  .picker-list {
    padding: 0 10px;
    max-height: 300px;
    overflow-y: auto;

    .list-item {
      display: flex;
      justify-content: space-between;
      align-items: center;
      font-size: 14px;
      padding: 10px 0;
      color: #606266;

      &:not(:last-child) {
        border-bottom: 1px solid #f2f2f2;
      }

    }
    .active {
      color: #299bcb;
    }
  }
}
.overlay {
  z-index: 999;
  position: fixed;
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  background: rgba(0, 0, 0, 0.5);
  transition: all 1s;
  &.hide {
    display: none !important;
  }
}
</style>

13799433448 avatar Jul 25 '22 03:07 13799433448

baseFormData 是在那里定义的 ?

mehaotian avatar Jul 25 '22 06:07 mehaotian

baseFormData 是在那里定义的 ? 父组件·中定义的

const baseFormData = reactive<workAttendanceAddDTO>({
  attendanceType: 0, // 申请类型
  projectCode: '',
  approvalEmployeeCode: '', // 审批人code
  approvalEmployeeName: '', // 审批人
  attendanceTimeStart: '',
  attendanceTimeEnd: '',
  reason: '',
});

13799433448 avatar Jul 25 '22 07:07 13799433448

我看你的代码也没有 baseFormData 导入或引入的地方啊?

mehaotian avatar Jul 25 '22 07:07 mehaotian

我看你的代码也没有 baseFormData 导入或引入的地方啊?

重新更新了一下 代码

13799433448 avatar Jul 25 '22 07:07 13799433448

组件是 npm 安装的吗 ?什么版本的 ?

mehaotian avatar Jul 25 '22 07:07 mehaotian

组件是 npm 安装的吗 ?什么版本的 ?

npm 安装 uni-ui: 1.4.14

13799433448 avatar Jul 25 '22 07:07 13799433448

出问题的是什么版本 ? 现在都 1.4.20 了

mehaotian avatar Jul 25 '22 07:07 mehaotian

长时间未响应,问题暂时关闭; 若后续依然有问题,可reopen这个issue。

codexu avatar Sep 08 '22 10:09 codexu