hookehuyr

✨ feat(下拉框控件): 样式调整和功能调整

...@@ -36,6 +36,8 @@ declare module '@vue/runtime-core' { ...@@ -36,6 +36,8 @@ declare module '@vue/runtime-core' {
36 NutInput: typeof import('@nutui/nutui-taro')['Input'] 36 NutInput: typeof import('@nutui/nutui-taro')['Input']
37 NutNoticebar: typeof import('@nutui/nutui-taro')['Noticebar'] 37 NutNoticebar: typeof import('@nutui/nutui-taro')['Noticebar']
38 NutOverlay: typeof import('@nutui/nutui-taro')['Overlay'] 38 NutOverlay: typeof import('@nutui/nutui-taro')['Overlay']
39 + NutPicker: typeof import('@nutui/nutui-taro')['Picker']
40 + NutPopup: typeof import('@nutui/nutui-taro')['Popup']
39 NutRadio: typeof import('@nutui/nutui-taro')['Radio'] 41 NutRadio: typeof import('@nutui/nutui-taro')['Radio']
40 NutRadioGroup: typeof import('@nutui/nutui-taro')['RadioGroup'] 42 NutRadioGroup: typeof import('@nutui/nutui-taro')['RadioGroup']
41 NutSwiper: typeof import('@nutui/nutui-taro')['Swiper'] 43 NutSwiper: typeof import('@nutui/nutui-taro')['Swiper']
......
1 <!-- 1 <!--
2 * @Date: 2022-08-30 13:46:51 2 * @Date: 2022-08-30 13:46:51
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2023-03-03 21:11:24 4 + * @LastEditTime: 2023-04-06 13:34:46
5 - * @FilePath: /data-table/src/components/PickerField/index.vue 5 + * @FilePath: /custom_form/src/components/PickerField/index.vue
6 * @Description: 单列选择器组件 6 * @Description: 单列选择器组件
7 --> 7 -->
8 <template> 8 <template>
9 <div v-if="HideShow" class="picker-field-page"> 9 <div v-if="HideShow" class="picker-field-page">
10 <div class="label"> 10 <div class="label">
11 - <span v-if="item.component_props.required">&nbsp;*</span> 11 + <text v-if="item.component_props.required">&nbsp;*</text>
12 {{ item.component_props.label }} 12 {{ item.component_props.label }}
13 </div> 13 </div>
14 - <van-field 14 + <div style="margin: 10px 20px;">
15 - v-model="picker_value" 15 + <nut-input
16 - is-link 16 + v-model="picker_value"
17 - readonly 17 + is-link
18 - :name="item.key" 18 + readonly
19 - :required="item.component_props.required" 19 + :label="item.key"
20 - :placeholder="item.component_props.placeholder" 20 + :required="item.component_props.required"
21 - :rules="item.rules" 21 + :placeholder="item.component_props.placeholder"
22 - @click="showPicker = true" 22 + @click-input="onClick()"
23 - :border="false" 23 + :border="false"
24 - /> 24 + style="padding: 0px;"
25 + >
26 + <template #right> <RectRight color="#eaeaea"></RectRight></template>
27 + </nut-input>
28 + <div
29 + v-if="show_error"
30 + style="padding: 5px; color: red; font-size: 12px;"
31 + >
32 + {{ error_msg }}
33 + </div>
34 + </div>
25 <!-- <van-field v-if="has_add_info" :name="add_info_name" v-model="add_info" label="" placeholder="请输入补充信息" :border="false" style="border: 1px solid #eaeaea;border-radius: 0.25rem; padding: 0.25rem 0.5rem; margin-top: 0.25rem;" /> --> 35 <!-- <van-field v-if="has_add_info" :name="add_info_name" v-model="add_info" label="" placeholder="请输入补充信息" :border="false" style="border: 1px solid #eaeaea;border-radius: 0.25rem; padding: 0.25rem 0.5rem; margin-top: 0.25rem;" /> -->
26 - <van-popup v-model:show="showPicker" position="bottom"> 36 + <nut-popup v-model:visible="showPicker" position="bottom">
27 - <van-picker 37 + <nut-picker
28 :columns="item.component_props.options" 38 :columns="item.component_props.options"
29 @confirm="onConfirm" 39 @confirm="onConfirm"
30 @cancel="showPicker = false" 40 @cancel="showPicker = false"
31 /> 41 />
32 - </van-popup> 42 + </nut-popup>
33 </div> 43 </div>
34 </template> 44 </template>
35 45
36 <script setup> 46 <script setup>
47 +import { ref, computed, watch, onMounted, reactive } from "vue";
48 +import { RectRight } from '@nutui/icons-vue-taro';
49 +
37 const props = defineProps({ 50 const props = defineProps({
38 item: Object, 51 item: Object,
39 }); 52 });
...@@ -59,12 +72,21 @@ const selectedValues = ref(""); ...@@ -59,12 +72,21 @@ const selectedValues = ref("");
59 const showPicker = ref(false); 72 const showPicker = ref(false);
60 const picker_value = ref(props.item.component_props.default); 73 const picker_value = ref(props.item.component_props.default);
61 74
75 +const onClick = () => {
76 + showPicker.value = true;
77 +}
78 +
62 const onConfirm = ({ selectedOptions }) => { 79 const onConfirm = ({ selectedOptions }) => {
63 picker_value.value = selectedOptions[0]?.value; 80 picker_value.value = selectedOptions[0]?.value;
64 showPicker.value = false; 81 showPicker.value = false;
65 // 触发点自定义监听事件,配合规则显示隐藏其他字段 82 // 触发点自定义监听事件,配合规则显示隐藏其他字段
66 - props.item.value = { key: props.item.key, value: picker_value.value, type: "picker" }; 83 + props.item.value = {
84 + key: "picker",
85 + filed_name: props.item.key,
86 + value: picker_value.value,
87 + };
67 emit("active", props.item.value); 88 emit("active", props.item.value);
89 + validPicker();
68 // if (add_info_key.value === props.item.value) { 90 // if (add_info_key.value === props.item.value) {
69 // has_add_info.value = true; 91 // has_add_info.value = true;
70 // } 92 // }
...@@ -73,26 +95,58 @@ const onConfirm = ({ selectedOptions }) => { ...@@ -73,26 +95,58 @@ const onConfirm = ({ selectedOptions }) => {
73 const HideShow = computed(() => { 95 const HideShow = computed(() => {
74 return !props.item.component_props.disabled 96 return !props.item.component_props.disabled
75 }) 97 })
98 +
99 +// 错误提示
100 +const show_error = ref(false);
101 +const error_msg = ref('');
102 +
103 +// 校验模块
104 +const validPicker = () => {
105 + // 必填项
106 + if (props.item.component_props.required && !picker_value.value) {
107 + show_error.value = true;
108 + error_msg.value = '必填项不能为空'
109 + } else {
110 + show_error.value = false;
111 + error_msg.value = ''
112 + }
113 + return !show_error.value;
114 +};
115 +
116 +defineExpose({ validPicker, id: props.item.key });
76 </script> 117 </script>
77 118
78 -<style lang="less" scoped> 119 +<style lang="less">
79 .picker-field-page { 120 .picker-field-page {
80 - margin: 1rem;
81 .label { 121 .label {
82 - // padding: 1rem 1rem 0 0; 122 + padding: 30px 30px 0 30px;
83 - font-size: 0.9rem; 123 + font-size: 26px;
84 font-weight: bold; 124 font-weight: bold;
85 - 125 + text {
86 - span {
87 color: red; 126 color: red;
88 } 127 }
128 +
129 + .note-wrapper {
130 + font-size: 24px;
131 + margin-left: 30px;
132 + color: gray;
133 + padding-bottom: 15px;
134 + padding-top: 7px;
135 + white-space: pre-wrap;
136 + }
89 } 137 }
90 -}
91 138
92 -:deep(.van-cell--clickable) { 139 + .nut-input {
93 - border: 1px solid #eaeaea; 140 + padding: 10px;
94 - border-radius: 0.25rem; 141 + border: 1px solid #eaeaea;
95 - padding: 0.25rem 0.5rem; 142 + border-radius: 8px;
96 - margin-top: 0.5rem; 143 + }
97 } 144 }
145 +
146 +// :deep(.van-cell--clickable) {
147 +// border: 1px solid #eaeaea;
148 +// border-radius: 0.25rem;
149 +// padding: 0.25rem 0.5rem;
150 +// margin-top: 0.5rem;
151 +// }
98 </style> 152 </style>
......
...@@ -3,7 +3,7 @@ import TextField from '@/components/TextField/index.vue' ...@@ -3,7 +3,7 @@ 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'
7 // import AreaPickerField from '@/components/AreaPickerField/index.vue' 7 // import AreaPickerField from '@/components/AreaPickerField/index.vue'
8 // import DatePickerField from '@/components/DatePickerField/index.vue' 8 // import DatePickerField from '@/components/DatePickerField/index.vue'
9 // import TimePickerField from '@/components/TimePickerField/index.vue' 9 // import TimePickerField from '@/components/TimePickerField/index.vue'
...@@ -90,9 +90,9 @@ export function createComponentType(data) { ...@@ -90,9 +90,9 @@ export function createComponentType(data) {
90 if (item.component_props.tag === 'checkbox') { 90 if (item.component_props.tag === 'checkbox') {
91 item.component = CheckboxField 91 item.component = CheckboxField
92 } 92 }
93 - // if (item.component_props.tag === 'select') { 93 + if (item.component_props.tag === 'select') {
94 - // item.component = PickerField 94 + item.component = PickerField
95 - // } 95 + }
96 // if (item.component_props.tag === 'address') { 96 // if (item.component_props.tag === 'address') {
97 // item.component = AreaPickerField 97 // item.component = AreaPickerField
98 // } 98 // }
......
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-04-04 18:09:30 4 + * @LastEditTime: 2023-04-06 13:37:04
5 * @FilePath: /custom_form/src/pages/table/index.vue 5 * @FilePath: /custom_form/src/pages/table/index.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
...@@ -131,6 +131,7 @@ const textarea = ref([]); ...@@ -131,6 +131,7 @@ const textarea = ref([]);
131 const radio = ref([]); 131 const radio = ref([]);
132 const checkbox = ref([]); 132 const checkbox = ref([]);
133 const multi_rule = ref([]); 133 const multi_rule = ref([]);
134 +const picker = ref([]);
134 const area_picker = ref([]); 135 const area_picker = ref([]);
135 const image_uploader = ref([]); 136 const image_uploader = ref([]);
136 const file_uploader = ref([]); 137 const file_uploader = ref([]);
...@@ -154,6 +155,9 @@ const setRefMap = (el, item) => { ...@@ -154,6 +155,9 @@ const setRefMap = (el, item) => {
154 if (item.component_props.tag === "multi_rule") { 155 if (item.component_props.tag === "multi_rule") {
155 multi_rule.value.push(el); 156 multi_rule.value.push(el);
156 } 157 }
158 + if (item.component_props.tag === "select") {
159 + picker.value.push(el);
160 + }
157 if (item.component_props.tag === "area_picker") { 161 if (item.component_props.tag === "area_picker") {
158 area_picker.value.push(el); 162 area_picker.value.push(el);
159 } 163 }
...@@ -425,8 +429,8 @@ const onActive = (item) => { ...@@ -425,8 +429,8 @@ const onActive = (item) => {
425 if (item.type === "rate") { 429 if (item.type === "rate") {
426 postData.value = _.assign(postData.value, { [item.key]: item.value }); 430 postData.value = _.assign(postData.value, { [item.key]: item.value });
427 } 431 }
428 - if (item.type === "picker") { // 下拉框控件 432 + if (item.key === "picker") { // 下拉框控件
429 - postData.value = _.assign(postData.value, { [item.key]: item.value }); 433 + postData.value = Object.assign(postData.value, { [item.filed_name]: item.value });
430 } 434 }
431 // 检查规则,会影响字段显示 435 // 检查规则,会影响字段显示
432 checkRules(); 436 checkRules();
...@@ -504,6 +508,19 @@ const validOther = () => { ...@@ -504,6 +508,19 @@ const validOther = () => {
504 } 508 }
505 }); 509 });
506 } 510 }
511 + if (picker.value) {
512 + // 下拉框
513 + picker.value.forEach((item, index) => {
514 + if (!picker.value[index].validPicker()) {
515 + valid = {
516 + status: picker.value[index].validPicker(),
517 + key: "picker",
518 + id: picker.value[index]?.id
519 + };
520 + return false;
521 + }
522 + });
523 + }
507 if (area_picker.value) { 524 if (area_picker.value) {
508 // 省市区地址 525 // 省市区地址
509 area_picker.value.forEach((item, index) => { 526 area_picker.value.forEach((item, index) => {
......