Showing
4 changed files
with
109 additions
and
31 deletions
| ... | @@ -35,6 +35,7 @@ declare module '@vue/runtime-core' { | ... | @@ -35,6 +35,7 @@ declare module '@vue/runtime-core' { |
| 35 | NutNoticebar: typeof import('@nutui/nutui-taro')['Noticebar'] | 35 | NutNoticebar: typeof import('@nutui/nutui-taro')['Noticebar'] |
| 36 | NutSwiper: typeof import('@nutui/nutui-taro')['Swiper'] | 36 | NutSwiper: typeof import('@nutui/nutui-taro')['Swiper'] |
| 37 | NutSwiperItem: typeof import('@nutui/nutui-taro')['SwiperItem'] | 37 | NutSwiperItem: typeof import('@nutui/nutui-taro')['SwiperItem'] |
| 38 | + NutTextarea: typeof import('@nutui/nutui-taro')['Textarea'] | ||
| 38 | PhoneField: typeof import('./src/components/PhoneField/index.vue')['default'] | 39 | PhoneField: typeof import('./src/components/PhoneField/index.vue')['default'] |
| 39 | PickerField: typeof import('./src/components/PickerField/index.vue')['default'] | 40 | PickerField: typeof import('./src/components/PickerField/index.vue')['default'] |
| 40 | RadioField: typeof import('./src/components/RadioField/index.vue')['default'] | 41 | RadioField: typeof import('./src/components/RadioField/index.vue')['default'] | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2022-08-29 14:31:20 | 2 | * @Date: 2022-08-29 14:31:20 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2023-03-22 09:13:58 | 4 | + * @LastEditTime: 2023-04-03 14:07:03 |
| 5 | - * @FilePath: /data-table/src/components/TextareaField/index.vue | 5 | + * @FilePath: /custom_form/src/components/TextareaField/index.vue |
| 6 | * @Description: 多行文本输入框 | 6 | * @Description: 多行文本输入框 |
| 7 | --> | 7 | --> |
| 8 | <template> | 8 | <template> |
| 9 | <div v-if="HideShow" class="textarea-field-page"> | 9 | <div v-if="HideShow" class="textarea-field-page"> |
| 10 | <div class="label"> | 10 | <div class="label"> |
| 11 | - <span v-if="item.component_props.required"> *</span> | 11 | + <text v-if="item.component_props.required"> *</text> |
| 12 | {{ item.component_props.label }} | 12 | {{ item.component_props.label }} |
| 13 | </div> | 13 | </div> |
| 14 | - <div | 14 | + <!-- <div |
| 15 | v-if="item.component_props.note" | 15 | v-if="item.component_props.note" |
| 16 | v-html="item.component_props.note" | 16 | v-html="item.component_props.note" |
| 17 | style="font-size: 0.9rem; margin-left: 1rem; color: gray; padding-bottom: 0.5rem; padding-top: 0.25rem; white-space: pre-wrap;" | 17 | style="font-size: 0.9rem; margin-left: 1rem; color: gray; padding-bottom: 0.5rem; padding-top: 0.25rem; white-space: pre-wrap;" |
| 18 | - /> | 18 | + /> --> |
| 19 | - <van-field | 19 | + <nut-textarea |
| 20 | - v-model="item.value" | 20 | + v-model="input_value" |
| 21 | - :name="item.name" | ||
| 22 | :type="item.type" | 21 | :type="item.type" |
| 22 | + :border="false" | ||
| 23 | :placeholder="item.component_props.placeholder ? item.component_props.placeholder : '请输入'" | 23 | :placeholder="item.component_props.placeholder ? item.component_props.placeholder : '请输入'" |
| 24 | - :rules="item.rules" | ||
| 25 | - :required="item.component_props.required" | ||
| 26 | :readonly="item.component_props.readonly" | 24 | :readonly="item.component_props.readonly" |
| 27 | - :rows="item.component_props.rows" | 25 | + :max-length="item.component_props.maxlength ? item.component_props.maxlength : null" |
| 28 | - autosize | 26 | + :limit-show="!!item.component_props.maxlength && !item.component_props.readonly" |
| 29 | - :maxlength="item.component_props.maxlength ? item.component_props.maxlength : null" | 27 | + :autosize="{ maxHeight: 200, minHeight: 100 }" |
| 30 | - :show-word-limit="item.component_props.maxlength" | 28 | + style="border: 1px solid #eaeaea; border-radius: 0.25rem; padding: 10px;" |
| 31 | /> | 29 | /> |
| 30 | + <div | ||
| 31 | + v-if="show_error" | ||
| 32 | + style="padding: 5px 20px; color: red; font-size: 12px;" | ||
| 33 | + > | ||
| 34 | + {{ error_msg }} | ||
| 35 | + </div> | ||
| 32 | </div> | 36 | </div> |
| 33 | </template> | 37 | </template> |
| 34 | 38 | ||
| 35 | <script setup> | 39 | <script setup> |
| 40 | +import { ref, computed, watch, onMounted, reactive } from "vue"; | ||
| 41 | + | ||
| 36 | const props = defineProps({ | 42 | const props = defineProps({ |
| 37 | item: Object, | 43 | item: Object, |
| 38 | }); | 44 | }); |
| ... | @@ -40,15 +46,56 @@ const props = defineProps({ | ... | @@ -40,15 +46,56 @@ const props = defineProps({ |
| 40 | const HideShow = computed(() => { | 46 | const HideShow = computed(() => { |
| 41 | return !props.item.component_props.disabled | 47 | return !props.item.component_props.disabled |
| 42 | }) | 48 | }) |
| 49 | + | ||
| 50 | +const emit = defineEmits(["active"]); | ||
| 51 | +const input_value = ref(''); | ||
| 52 | + | ||
| 53 | +// 错误提示 | ||
| 54 | +const show_error = ref(false); | ||
| 55 | +const error_msg = ref(''); | ||
| 56 | + | ||
| 57 | +onMounted(() => { | ||
| 58 | + if (props.item.component_props.default) { | ||
| 59 | + input_value.value = props.item.component_props.default; | ||
| 60 | + } | ||
| 61 | +}) | ||
| 62 | + | ||
| 63 | +watch( | ||
| 64 | + () => input_value.value, | ||
| 65 | + (newValue, oldValue) => { | ||
| 66 | + props.item.value = { | ||
| 67 | + key: "textarea", | ||
| 68 | + filed_name: props.item.key, | ||
| 69 | + value: newValue, | ||
| 70 | + }; | ||
| 71 | + emit("active", props.item.value); | ||
| 72 | + }, | ||
| 73 | + { immediate: true } | ||
| 74 | +); | ||
| 75 | + | ||
| 76 | +// 校验模块 | ||
| 77 | +const validTextarea = () => { | ||
| 78 | + // 必填项 | ||
| 79 | + if (props.item.component_props.required && !input_value.value) { | ||
| 80 | + show_error.value = true; | ||
| 81 | + error_msg.value = '必填项不能为空' | ||
| 82 | + } else { | ||
| 83 | + show_error.value = false; | ||
| 84 | + error_msg.value = '' | ||
| 85 | + } | ||
| 86 | + return !show_error.value; | ||
| 87 | +}; | ||
| 88 | + | ||
| 89 | +defineExpose({ validTextarea }); | ||
| 43 | </script> | 90 | </script> |
| 44 | 91 | ||
| 45 | -<style lang="less" scoped> | 92 | +<style lang="less"> |
| 46 | .textarea-field-page { | 93 | .textarea-field-page { |
| 47 | .label { | 94 | .label { |
| 48 | - padding: 1rem 1rem 0 1rem; | 95 | + padding: 30px 30px 0 30px; |
| 49 | - font-size: 0.9rem; | 96 | + font-size: 26px; |
| 50 | font-weight: bold; | 97 | font-weight: bold; |
| 51 | - span { | 98 | + text { |
| 52 | color: red; | 99 | color: red; |
| 53 | } | 100 | } |
| 54 | } | 101 | } |
| ... | @@ -59,9 +106,22 @@ const HideShow = computed(() => { | ... | @@ -59,9 +106,22 @@ const HideShow = computed(() => { |
| 59 | // border-radius: 0.25rem; | 106 | // border-radius: 0.25rem; |
| 60 | // padding: 0.25rem 0.5rem; | 107 | // padding: 0.25rem 0.5rem; |
| 61 | // } | 108 | // } |
| 62 | -:deep(.van-cell__value) { | 109 | +// :deep(.van-cell__value) { |
| 63 | - border: 1px solid #eaeaea; | 110 | +// border: 1px solid #eaeaea; |
| 64 | - border-radius: 0.25rem; | 111 | +// border-radius: 0.25rem; |
| 65 | - padding: 0.25rem 0.5rem; | 112 | +// padding: 0.25rem 0.5rem; |
| 113 | +// } | ||
| 114 | + | ||
| 115 | +input { | ||
| 116 | + color: #000 !important; | ||
| 117 | +} | ||
| 118 | +.nut-textarea { | ||
| 119 | + padding-left: 35px; | ||
| 120 | + padding-right: 35px; | ||
| 121 | + white-space: pre-wrap; | ||
| 122 | +} | ||
| 123 | +.nut-textarea__limit { | ||
| 124 | + right: 50px; | ||
| 125 | + bottom: 30px; | ||
| 66 | } | 126 | } |
| 67 | </style> | 127 | </style> | ... | ... |
| 1 | import _ from '@/utils/lodash' | 1 | import _ from '@/utils/lodash' |
| 2 | import TextField from '@/components/TextField/index.vue' | 2 | import TextField from '@/components/TextField/index.vue' |
| 3 | -// import TextareaField from '@/components/TextareaField/index.vue' | 3 | +import TextareaField from '@/components/TextareaField/index.vue' |
| 4 | // import RadioField from '@/components/RadioField/index.vue' | 4 | // import RadioField from '@/components/RadioField/index.vue' |
| 5 | // import CheckboxField from '@/components/CheckboxField/index.vue' | 5 | // import CheckboxField from '@/components/CheckboxField/index.vue' |
| 6 | // import PickerField from '@/components/PickerField/index.vue' | 6 | // import PickerField from '@/components/PickerField/index.vue' |
| ... | @@ -75,13 +75,11 @@ export function createComponentType(data) { | ... | @@ -75,13 +75,11 @@ export function createComponentType(data) { |
| 75 | item.name = item.key | 75 | item.name = item.key |
| 76 | item.component = TextField | 76 | item.component = TextField |
| 77 | } | 77 | } |
| 78 | - // if (item.component_props.tag === 'textarea') { | 78 | + if (item.component_props.tag === 'textarea') { |
| 79 | - // item.type = 'textarea' | 79 | + item.type = 'textarea' |
| 80 | - // item.name = item.key | 80 | + item.name = item.key |
| 81 | - // // item.rows = 10; | 81 | + item.component = TextareaField |
| 82 | - // item.autosize = true | 82 | + } |
| 83 | - // item.component = TextareaField | ||
| 84 | - // } | ||
| 85 | // if (item.component_props.tag === 'number') { | 83 | // if (item.component_props.tag === 'number') { |
| 86 | // item.name = item.key | 84 | // item.name = item.key |
| 87 | // item.component = NumberField | 85 | // item.component = NumberField | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2023-03-24 09:19:27 | 2 | * @Date: 2023-03-24 09:19:27 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2023-03-31 18:02:51 | 4 | + * @LastEditTime: 2023-04-03 13:32:11 |
| 5 | * @FilePath: /custom_form/src/pages/table/index.vue | 5 | * @FilePath: /custom_form/src/pages/table/index.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| ... | @@ -127,6 +127,7 @@ const formatData = (data) => { | ... | @@ -127,6 +127,7 @@ const formatData = (data) => { |
| 127 | // 处理没有绑定值的组件的赋值 | 127 | // 处理没有绑定值的组件的赋值 |
| 128 | // 省市区选择,图片上传,文件上传,电子签名,评分组件 | 128 | // 省市区选择,图片上传,文件上传,电子签名,评分组件 |
| 129 | const input = ref([]); | 129 | const input = ref([]); |
| 130 | +const textarea = ref([]); | ||
| 130 | const area_picker = ref([]); | 131 | const area_picker = ref([]); |
| 131 | const image_uploader = ref([]); | 132 | const image_uploader = ref([]); |
| 132 | const file_uploader = ref([]); | 133 | const file_uploader = ref([]); |
| ... | @@ -138,6 +139,9 @@ const setRefMap = (el, item) => { | ... | @@ -138,6 +139,9 @@ const setRefMap = (el, item) => { |
| 138 | if (item.component_props.tag === "input") { | 139 | if (item.component_props.tag === "input") { |
| 139 | input.value.push(el); | 140 | input.value.push(el); |
| 140 | } | 141 | } |
| 142 | + if (item.component_props.tag === "textarea") { | ||
| 143 | + textarea.value.push(el); | ||
| 144 | + } | ||
| 141 | if (item.component_props.tag === "area_picker") { | 145 | if (item.component_props.tag === "area_picker") { |
| 142 | area_picker.value.push(el); | 146 | area_picker.value.push(el); |
| 143 | } | 147 | } |
| ... | @@ -364,6 +368,9 @@ const onActive = (item) => { | ... | @@ -364,6 +368,9 @@ const onActive = (item) => { |
| 364 | if (item.key === "input") { | 368 | if (item.key === "input") { |
| 365 | postData.value[item.filed_name] = item.value; | 369 | postData.value[item.filed_name] = item.value; |
| 366 | } | 370 | } |
| 371 | + if (item.key === "textarea") { | ||
| 372 | + postData.value[item.filed_name] = item.value; | ||
| 373 | + } | ||
| 367 | if (item.key === "area_picker") { | 374 | if (item.key === "area_picker") { |
| 368 | postData.value[item.filed_name] = item.value; | 375 | postData.value[item.filed_name] = item.value; |
| 369 | } | 376 | } |
| ... | @@ -418,6 +425,18 @@ const validOther = () => { | ... | @@ -418,6 +425,18 @@ const validOther = () => { |
| 418 | } | 425 | } |
| 419 | }); | 426 | }); |
| 420 | } | 427 | } |
| 428 | + if (textarea.value) { | ||
| 429 | + // 多行文本 | ||
| 430 | + textarea.value.forEach((item, index) => { | ||
| 431 | + if (!textarea.value[index].validTextarea()) { | ||
| 432 | + valid = { | ||
| 433 | + status: textarea.value[index].validTextarea(), | ||
| 434 | + key: "textarea", | ||
| 435 | + }; | ||
| 436 | + return false; | ||
| 437 | + } | ||
| 438 | + }); | ||
| 439 | + } | ||
| 421 | if (area_picker.value) { | 440 | if (area_picker.value) { |
| 422 | // 省市区地址 | 441 | // 省市区地址 |
| 423 | area_picker.value.forEach((item, index) => { | 442 | area_picker.value.forEach((item, index) => { | ... | ... |
-
Please register or login to post a comment