hookehuyr

✨ feat(评分控件): 自定义表单钩子函数改造

<!--
* @Date: 2023-03-29 13:09:02
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-03-29 13:22:01
* @FilePath: /data-table/src/components/RatePickerField/MyComponent.vue
* @Description: 文件描述
-->
<template>
<div style="width: 100%;">
<van-rate
v-model="rate_value"
:count="props.component_props.data_length"
:readonly="props.component_props.readonly"
:color="styleColor.baseColor"
style="padding: 1rem"
/>
<van-divider />
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useCustomFieldValue } from '@vant/use';
import { styleColor } from "@/constant.js";
// 获取父组件传值
const props = inject('props');
const rate_value = ref(props.component_props.default);
// 此处传入的值会替代 Field 组件内部的 value
useCustomFieldValue(() => rate_value.value);
</script>
<style lang="less" scoped>
</style>
<!--
* @Date: 2022-09-08 15:47:54
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-03-27 17:14:53
* @LastEditTime: 2023-03-29 13:27:43
* @FilePath: /data-table/src/components/RatePickerField/index.vue
* @Description: 评分选择控件
-->
......@@ -11,27 +11,16 @@
<span v-if="item.component_props.required">&nbsp;*</span>
{{ item.component_props.label }}
</div>
<van-rate
v-model="rate_value"
:count="item.component_props.data_length"
:readonly="item.component_props.readonly"
:color="styleColor.baseColor"
@change="onChange"
style="padding: 1rem"
/>
<div
v-if="show_empty"
class="van-field__error-message"
style="padding: 0 1rem 1rem 1rem"
>
评分不能为空
</div>
<van-divider />
<van-field :name="item.name" :rules="rules">
<template #input>
<my-component />
</template>
</van-field>
</div>
</template>
<script setup>
import { styleColor } from "@/constant.js";
import MyComponent from './MyComponent.vue';
const props = defineProps({
item: Object,
......@@ -40,31 +29,26 @@ const props = defineProps({
const HideShow = computed(() => {
return !props.item.component_props.disabled
})
const emit = defineEmits(["active"]);
const show_empty = ref(false);
const rate_value = ref(props.item.component_props.default);
const onChange = (value) => {
props.item.value = { key: props.item.key, value, type: "rate" };
emit("active", props.item.value);
};
onMounted(() => {
props.item.value = { key: props.item.key, value: rate_value.value, type: "rate" };
emit("active", props.item.value);
});
// 注入子组件属性
provide('props', props.item);
const validRate = () => {
// 必填项
if (props.item.component_props.required && !rate_value.value) {
show_empty.value = true;
// 规则校验
const required = props.item.component_props.required;
const validator = (val) => {
if (required && !+val) {
return false;
} else {
show_empty.value = false;
return true;
}
return !show_empty.value;
};
defineExpose({ validRate });
// 错误提示文案
const validatorMessage = (val, rule) => {
if (required && !+val) {
return "必填项不能为空";
}
};
const rules = [{ validator, message: validatorMessage }];
</script>
<style lang="less" scoped>
......
<!--
* @Date: 2022-07-18 10:22:22
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-03-27 18:30:02
* @LastEditTime: 2023-03-29 13:19:06
* @FilePath: /data-table/src/views/index.vue
* @Description: 首页
-->
......@@ -22,7 +22,7 @@
<div v-if="PHeader.label" class="table-title" v-html="PHeader.label" />
<div v-if="PHeader.description" class="table-desc" v-html="PHeader.description" />
<van-config-provider :theme-vars="themeVars">
<van-form @submit="onSubmit" scroll-to-error="true">
<van-form @submit="onSubmit" :scroll-to-error="true">
<van-cell-group :border="false">
<component v-for="(item, index) in formData" :id="item.key" :ref="(el) => setRefMap(el, item)" :key="index"
:is="item.component" :item="item" @active="onActive" />
......@@ -175,12 +175,6 @@ const setRefMap = (el, item) => {
if (item.component_props.tag === "sign") {
sign.value.push(el);
}
if (item.component_props.tag === "rate_picker") {
rate_picker.value.push(el);
}
if (item.component_props.tag === "appointment") {
appointment.value.push(el);
}
}
};
......@@ -250,6 +244,7 @@ onMounted(async () => {
};
}
formData.value = formatData(page_form);
// TAG: mock数据
mockData.value = [
{
key: "field_1",
......@@ -442,15 +437,9 @@ const onActive = (item) => {
if (item.key === "sign") {
postData.value[item.filed_name] = item.value;
}
if (item.type === "rate") {
postData.value = _.assign(postData.value, { [item.key]: item.value });
}
if (item.type === "picker") { // 下拉框控件
postData.value = _.assign(postData.value, { [item.key]: item.value });
}
if (item.type === "appointment") { // 预约控件
postData.value = _.assign(postData.value, { [item.key]: item.value });
}
if (item.type === "radio") { // 单选控件
postData.value = _.assign(postData.value, { [item.key]: item.affix ? item.affix : item.value });
}
......@@ -523,30 +512,6 @@ const validOther = () => {
}
});
}
if (rate_picker.value) {
// 评分组件
rate_picker.value.forEach((item, index) => {
if (!rate_picker.value[index].validRate()) {
valid = {
status: rate_picker.value[index].validRate(),
key: "rate_picker",
};
return false;
}
});
}
if (appointment.value) {
// 预约时间控件
appointment.value.forEach((item, index) => {
if (!appointment.value[index].validAppointment()) {
valid = {
status: appointment.value[index].validAppointment(),
key: "appointment",
};
return false;
}
});
}
return valid;
};
......