hookehuyr

✨ feat: 新增日期选择控件

1 +<!--
2 + * @Date: 2022-08-31 11:45:30
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-08-31 13:33:45
5 + * @FilePath: /data-table/src/components/DatePickerField/index.vue
6 + * @Description: 日期选择组件
7 +-->
8 +<template>
9 + <div class="date-picker-field">
10 + <div class="label">{{ item.label }}<span v-if="item.required">&nbsp;*</span></div>
11 + <van-field v-model="item.value" is-link readonly :name="item.key" :required="item.required"
12 + :placeholder="item.placeholder" :rules="item.rules" @click="showPicker = true" />
13 + <van-popup v-model:show="showPicker" position="bottom">
14 + <van-date-picker v-model="currentDate" :title="item.component_props.title"
15 + :min-date="item.component_props.min_date" :max-date="item.component_props.max_date"
16 + :columns-type="item.component_props.columns_type" @confirm="onConfirm" @cancel="showPicker = false" />
17 + </van-popup>
18 + </div>
19 +</template>
20 +
21 +<script setup>
22 +import dayjs from 'dayjs';
23 +
24 +const props = defineProps({
25 + item: Object
26 +})
27 +
28 +const showPicker = ref(false);
29 +const currentDate = ref([]);
30 +
31 +const onConfirm = ({ selectedValues, selectedOptions }) => {
32 + props.item.value = selectedValues[0] + '-' + selectedValues[1];
33 + showPicker.value = false;
34 +};
35 +// console.warn(dayjs().format('YYYY'));
36 +</script>
37 +
38 +<style lang="less" scoped>
39 +.date-picker-field {
40 + .label {
41 + padding: 1rem 1rem 0 1rem;
42 + font-size: 0.9rem;
43 + font-weight: bold;
44 +
45 + span {
46 + color: red;
47 + }
48 + }
49 +}
50 +</style>
...@@ -6,6 +6,7 @@ import RadioField from '@/components/RadioField/index.vue' ...@@ -6,6 +6,7 @@ import RadioField from '@/components/RadioField/index.vue'
6 import CheckboxField from '@/components/CheckboxField/index.vue' 6 import CheckboxField from '@/components/CheckboxField/index.vue'
7 import PickerField from '@/components/PickerField/index.vue' 7 import PickerField from '@/components/PickerField/index.vue'
8 import AreaPickerField from '@/components/AreaPickerField/index.vue' 8 import AreaPickerField from '@/components/AreaPickerField/index.vue'
9 +import DatePickerField from '@/components/DatePickerField/index.vue'
9 10
10 /** 11 /**
11 * 生成自定义组件类型 12 * 生成自定义组件类型
...@@ -16,6 +17,7 @@ import AreaPickerField from '@/components/AreaPickerField/index.vue' ...@@ -16,6 +17,7 @@ import AreaPickerField from '@/components/AreaPickerField/index.vue'
16 * @type checkbox 多选框 CheckboxField 17 * @type checkbox 多选框 CheckboxField
17 * @type picker 单列选择器 PickerField 18 * @type picker 单列选择器 PickerField
18 * @type area_picker 省市区选择器 AreaPickerField 19 * @type area_picker 省市区选择器 AreaPickerField
20 + * @type date_picker 日期选择器 DatePickerField
19 */ 21 */
20 export function createComponentType(data) { 22 export function createComponentType(data) {
21 // 判断类型和使用组件 23 // 判断类型和使用组件
...@@ -24,34 +26,37 @@ export function createComponentType(data) { ...@@ -24,34 +26,37 @@ export function createComponentType(data) {
24 if (item.required) { 26 if (item.required) {
25 item.rules = [{ required: true, message: item.placeholder ? item.placeholder : '必填项不能为空' }] 27 item.rules = [{ required: true, message: item.placeholder ? item.placeholder : '必填项不能为空' }]
26 } 28 }
27 - if (item.component_type === 'text') { 29 + if (item.component_props.name === 'text') {
28 item.type = 'text'; 30 item.type = 'text';
29 item.name = item.key; 31 item.name = item.key;
30 item.component = TextField; 32 item.component = TextField;
31 } 33 }
32 - if (item.component_type === 'textarea') { 34 + if (item.component_props.name === 'textarea') {
33 item.type = 'textarea'; 35 item.type = 'textarea';
34 item.name = item.key; 36 item.name = item.key;
35 item.rows = 2; 37 item.rows = 2;
36 item.autosize = true; 38 item.autosize = true;
37 item.component = TextareaField; 39 item.component = TextareaField;
38 } 40 }
39 - if (item.component_type === 'number') { 41 + if (item.component_props.name === 'number') {
40 item.type = 'number'; 42 item.type = 'number';
41 item.name = item.key; 43 item.name = item.key;
42 item.component = TextField; 44 item.component = TextField;
43 } 45 }
44 - if (item.component_type === 'radio') { 46 + if (item.component_props.name === 'radio') {
45 item.component = RadioField; 47 item.component = RadioField;
46 } 48 }
47 - if (item.component_type === 'checkbox') { 49 + if (item.component_props.name === 'checkbox') {
48 item.component = CheckboxField; 50 item.component = CheckboxField;
49 } 51 }
50 - if (item.component_type === 'picker') { 52 + if (item.component_props.name === 'picker') {
51 item.component = PickerField; 53 item.component = PickerField;
52 } 54 }
53 - if (item.component_type === 'area_picker') { 55 + if (item.component_props.name === 'area_picker') {
54 item.component = AreaPickerField; 56 item.component = AreaPickerField;
55 } 57 }
58 + if (item.component_props.name === 'date_picker') {
59 + item.component = DatePickerField;
60 + }
56 }) 61 })
57 } 62 }
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
2 * @Author: hookehuyr hookehuyr@gmail.com 2 * @Author: hookehuyr hookehuyr@gmail.com
3 * @Date: 2022-05-31 12:06:19 3 * @Date: 2022-05-31 12:06:19
4 * @LastEditors: hookehuyr hookehuyr@gmail.com 4 * @LastEditors: hookehuyr hookehuyr@gmail.com
5 - * @LastEditTime: 2022-08-30 14:33:11 5 + * @LastEditTime: 2022-08-31 13:14:09
6 * @FilePath: /data-table/src/main.js 6 * @FilePath: /data-table/src/main.js
7 * @Description: 7 * @Description:
8 */ 8 */
9 import { createApp } from 'vue'; 9 import { createApp } from 'vue';
10 -import { Button, Image as VanImage, Col, Row, Icon, Form, Field, CellGroup, ConfigProvider, Toast, Uploader, Empty, Tab, Tabs, Overlay, NumberKeyboard, Lazyload, List, PullRefresh, Popup, Picker, Sticky, Stepper, Tag, Swipe, SwipeItem, Dialog, ActionSheet, Loading, Checkbox, Search, NavBar, Collapse, CollapseItem, RadioGroup, Radio, CheckboxGroup, Area } from 'vant'; 10 +import { Button, Image as VanImage, Col, Row, Icon, Form, Field, CellGroup, ConfigProvider, Toast, Uploader, Empty, Tab, Tabs, Overlay, NumberKeyboard, Lazyload, List, PullRefresh, Popup, Picker, Sticky, Stepper, Tag, Swipe, SwipeItem, Dialog, ActionSheet, Loading, Checkbox, Search, NavBar, Collapse, CollapseItem, RadioGroup, Radio, CheckboxGroup, Area, DatePicker } from 'vant';
11 import router from './router'; 11 import router from './router';
12 import App from './App.vue'; 12 import App from './App.vue';
13 // import axios from './utils/axios'; 13 // import axios from './utils/axios';
...@@ -23,6 +23,6 @@ app.config.warnHandler = () => null; ...@@ -23,6 +23,6 @@ app.config.warnHandler = () => null;
23 23
24 app.config.globalProperties.$http = axios; // 关键语句 24 app.config.globalProperties.$http = axios; // 关键语句
25 25
26 -app.use(pinia).use(router).use(Button).use(VanImage).use(Col).use(Row).use(Icon).use(Form).use(Field).use(CellGroup).use(Toast).use(Uploader).use(Empty).use(Tab).use(Tabs).use(Overlay).use(NumberKeyboard).use(Lazyload).use(List).use(PullRefresh).use(Popup).use(Picker).use(Sticky).use(Stepper).use(Tag).use(Swipe).use(SwipeItem).use(Dialog).use(ActionSheet).use(Loading).use(Checkbox).use(Search).use(ConfigProvider).use(NavBar).use(Collapse).use(CollapseItem).use(Radio).use(RadioGroup).use(CheckboxGroup).use(Area); 26 +app.use(pinia).use(router).use(Button).use(VanImage).use(Col).use(Row).use(Icon).use(Form).use(Field).use(CellGroup).use(Toast).use(Uploader).use(Empty).use(Tab).use(Tabs).use(Overlay).use(NumberKeyboard).use(Lazyload).use(List).use(PullRefresh).use(Popup).use(Picker).use(Sticky).use(Stepper).use(Tag).use(Swipe).use(SwipeItem).use(Dialog).use(ActionSheet).use(Loading).use(Checkbox).use(Search).use(ConfigProvider).use(NavBar).use(Collapse).use(CollapseItem).use(Radio).use(RadioGroup).use(CheckboxGroup).use(Area).use(DatePicker);
27 27
28 app.mount('#app'); 28 app.mount('#app');
......
1 <!-- 1 <!--
2 * @Date: 2022-07-18 10:22:22 2 * @Date: 2022-07-18 10:22:22
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2022-08-30 17:55:45 4 + * @LastEditTime: 2022-08-31 13:37:32
5 * @FilePath: /data-table/src/views/index.vue 5 * @FilePath: /data-table/src/views/index.vue
6 * @Description: 首页 6 * @Description: 首页
7 --> 7 -->
...@@ -30,11 +30,13 @@ const mockData = ref([]); ...@@ -30,11 +30,13 @@ const mockData = ref([]);
30 onMounted(() => { 30 onMounted(() => {
31 mockData.value = [{ 31 mockData.value = [{
32 key: 'username', 32 key: 'username',
33 - value: '', 33 + value: 'test',
34 label: '用户名', 34 label: '用户名',
35 placeholder: '请输入用户名', 35 placeholder: '请输入用户名',
36 component: '', 36 component: '',
37 - component_type: 'text', 37 + component_props: {
38 + name: 'text'
39 + },
38 required: true, 40 required: true,
39 }, { 41 }, {
40 key: 'age', 42 key: 'age',
...@@ -42,7 +44,9 @@ onMounted(() => { ...@@ -42,7 +44,9 @@ onMounted(() => {
42 label: '年龄', 44 label: '年龄',
43 placeholder: '请输入年龄', 45 placeholder: '请输入年龄',
44 component: '', 46 component: '',
45 - component_type: 'number', 47 + component_props: {
48 + name: 'number'
49 + },
46 required: false, 50 required: false,
47 }, { 51 }, {
48 key: 'gender', 52 key: 'gender',
...@@ -50,7 +54,9 @@ onMounted(() => { ...@@ -50,7 +54,9 @@ onMounted(() => {
50 label: '性别', 54 label: '性别',
51 placeholder: '', 55 placeholder: '',
52 component: '', 56 component: '',
53 - component_type: 'radio', 57 + component_props: {
58 + name: 'radio'
59 + },
54 options: [{ 60 options: [{
55 key: '男', 61 key: '男',
56 value: '男' 62 value: '男'
...@@ -64,7 +70,9 @@ onMounted(() => { ...@@ -64,7 +70,9 @@ onMounted(() => {
64 label: '兴趣爱好', 70 label: '兴趣爱好',
65 placeholder: '', 71 placeholder: '',
66 component: '', 72 component: '',
67 - component_type: 'checkbox', 73 + component_props: {
74 + name: 'checkbox'
75 + },
68 options: [{ 76 options: [{
69 key: '足球', 77 key: '足球',
70 value: '足球' 78 value: '足球'
...@@ -78,14 +86,18 @@ onMounted(() => { ...@@ -78,14 +86,18 @@ onMounted(() => {
78 label: '留言', 86 label: '留言',
79 placeholder: '请输入留言', 87 placeholder: '请输入留言',
80 component: '', 88 component: '',
81 - component_type: 'textarea', 89 + component_props: {
90 + name: 'textarea'
91 + },
82 }, { 92 }, {
83 key: 'vehicle', 93 key: 'vehicle',
84 - value: '', 94 + value: '自行车',
85 label: '交通工具', 95 label: '交通工具',
86 placeholder: '请选择交通工具', 96 placeholder: '请选择交通工具',
87 component: '', 97 component: '',
88 - component_type: 'picker', 98 + component_props: {
99 + name: 'picker'
100 + },
89 options: [ 101 options: [
90 { text: '自行车', value: '自行车' }, 102 { text: '自行车', value: '自行车' },
91 { text: '汽车', value: '汽车' }, 103 { text: '汽车', value: '汽车' },
...@@ -98,7 +110,20 @@ onMounted(() => { ...@@ -98,7 +110,20 @@ onMounted(() => {
98 city_code: '120101', 110 city_code: '120101',
99 label: '省市区', 111 label: '省市区',
100 placeholder: '请选择省市区', 112 placeholder: '请选择省市区',
101 - component_type: 'area_picker' 113 + component_props: {
114 + name: 'area_picker'
115 + },
116 + }, {
117 + key: 'datetime',
118 + value: [],
119 + label: '日期选择',
120 + placeholder: '请选择日期',
121 + component_props: {
122 + name: 'date_picker',
123 + title: '请选择',
124 + min_date: new Date(),
125 + columns_type: ['year', 'month']
126 + },
102 }]; 127 }];
103 // 生成自定义组件 128 // 生成自定义组件
104 createComponentType(mockData.value) 129 createComponentType(mockData.value)
......