hookehuyr

✨ feat: 新增手机号输入控件

1 +<!--
2 + * @Date: 2022-09-02 10:46:03
3 + * @LastEditors: hookehuyr hookehuyr@gmail.com
4 + * @LastEditTime: 2022-09-02 11:36:29
5 + * @FilePath: /data-table/src/components/PhoneField/index.vue
6 + * @Description: 文件描述
7 +-->
8 +<template>
9 + <div class="phone-field-page">
10 + <div class="label">{{ item.label }}<span v-if="item.required">&nbsp;*</span></div>
11 + <van-field v-model="item.value" :name="item.name" type="digit" maxlength="11" :placeholder="item.placeholder"
12 + :rules="rules" :required="item.required" :readonly="readonly" @touchstart.stop="show = true"></van-field>
13 + <van-number-keyboard v-model="item.value" :show="show" :maxlength="11" @blur="show = false" />
14 + </div>
15 +</template>
16 +
17 +<script setup>
18 +import { wxInfo } from '@/utils/tools'
19 +
20 +const props = defineProps({
21 + item: Object
22 +});
23 +
24 +// web端判断
25 +const readonly = computed(() => wxInfo().isMobile)
26 +
27 +// 校验函数返回 true 表示校验通过,false 表示不通过
28 +const validator = (val) => {
29 + if (!props.item.required) { // 非必填
30 + return true
31 + } else {
32 + return /1\d{10}/.test(val);
33 + }
34 +};
35 +// 错误提示文案
36 +const validatorMessage = (val, rule) => {
37 + if (!val) {
38 + return '手机号码不能为空';
39 + } else if (!/1\d{10}/.test(val)) {
40 + return '请输入正确手机号码';
41 + }
42 +}
43 +const rules = [{ validator, message: validatorMessage }]
44 +
45 +const show = ref(false);
46 +</script>
47 +
48 +<style lang="less" scoped>
49 + .phone-field-page {
50 + .label {
51 + padding: 1rem 1rem 0 1rem;
52 + font-size: 0.9rem;
53 + font-weight: bold;
54 + span {
55 + color: red;
56 + }
57 + }
58 + }
59 +</style>
...@@ -8,6 +8,7 @@ import PickerField from '@/components/PickerField/index.vue' ...@@ -8,6 +8,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 import DatePickerField from '@/components/DatePickerField/index.vue'
10 import ImageUploaderField from '@/components/ImageUploaderField/index.vue' 10 import ImageUploaderField from '@/components/ImageUploaderField/index.vue'
11 +import PhoneField from '@/components/PhoneField/index.vue'
11 12
12 /** 13 /**
13 * 生成自定义组件类型 14 * 生成自定义组件类型
...@@ -20,6 +21,7 @@ import ImageUploaderField from '@/components/ImageUploaderField/index.vue' ...@@ -20,6 +21,7 @@ import ImageUploaderField from '@/components/ImageUploaderField/index.vue'
20 * @type area_picker 省市区选择器 AreaPickerField 21 * @type area_picker 省市区选择器 AreaPickerField
21 * @type date_picker 日期选择器 DatePickerField 22 * @type date_picker 日期选择器 DatePickerField
22 * @type image_uploader 图片上传 ImageUploaderField 23 * @type image_uploader 图片上传 ImageUploaderField
24 + * @type phone 手机输入框 PhoneField
23 */ 25 */
24 export function createComponentType(data) { 26 export function createComponentType(data) {
25 // 判断类型和使用组件 27 // 判断类型和使用组件
...@@ -63,5 +65,9 @@ export function createComponentType(data) { ...@@ -63,5 +65,9 @@ export function createComponentType(data) {
63 if (item.component_props.name === 'image_uploader') { 65 if (item.component_props.name === 'image_uploader') {
64 item.component = ImageUploaderField; 66 item.component = ImageUploaderField;
65 } 67 }
68 + if (item.component_props.name === 'phone') {
69 + item.name = item.key;
70 + item.component = PhoneField;
71 + }
66 }) 72 })
67 } 73 }
......
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-31 13:37:32 4 + * @LastEditTime: 2022-09-02 11:16:29
5 * @FilePath: /data-table/src/views/index.vue 5 * @FilePath: /data-table/src/views/index.vue
6 * @Description: 首页 6 * @Description: 首页
7 --> 7 -->
...@@ -29,102 +29,121 @@ import { createComponentType } from '@/hooks/useComponentType' ...@@ -29,102 +29,121 @@ import { createComponentType } from '@/hooks/useComponentType'
29 const mockData = ref([]); 29 const mockData = ref([]);
30 onMounted(() => { 30 onMounted(() => {
31 mockData.value = [{ 31 mockData.value = [{
32 - key: 'username', 32 + key: 'phone',
33 - value: 'test',
34 - label: '用户名',
35 - placeholder: '请输入用户名',
36 - component: '',
37 - component_props: {
38 - name: 'text'
39 - },
40 - required: true,
41 - }, {
42 - key: 'age',
43 value: '', 33 value: '',
44 - label: '年龄', 34 + label: '手机号',
45 - placeholder: '请输入年龄', 35 + placeholder: '请输入手机号',
46 - component: '',
47 - component_props: {
48 - name: 'number'
49 - },
50 - required: false,
51 - }, {
52 - key: 'gender',
53 - value: '',
54 - label: '性别',
55 - placeholder: '',
56 - component: '',
57 - component_props: {
58 - name: 'radio'
59 - },
60 - options: [{
61 - key: '男',
62 - value: '男'
63 - }, {
64 - key: '女',
65 - value: '女'
66 - }]
67 - }, {
68 - key: 'hobby',
69 - value: [],
70 - label: '兴趣爱好',
71 - placeholder: '',
72 component: '', 36 component: '',
73 component_props: { 37 component_props: {
74 - name: 'checkbox' 38 + name: 'phone'
75 }, 39 },
76 - options: [{
77 - key: '足球',
78 - value: '足球'
79 - }, {
80 - key: '篮球',
81 - value: '篮球'
82 - }]
83 - }, {
84 - key: 'message',
85 - value: 'zzz',
86 - label: '留言',
87 - placeholder: '请输入留言',
88 - component: '',
89 - component_props: {
90 - name: 'textarea'
91 - },
92 - }, {
93 - key: 'vehicle',
94 - value: '自行车',
95 - label: '交通工具',
96 - placeholder: '请选择交通工具',
97 - component: '',
98 - component_props: {
99 - name: 'picker'
100 - },
101 - options: [
102 - { text: '自行车', value: '自行车' },
103 - { text: '汽车', value: '汽车' },
104 - { text: '地铁', value: '地铁' },
105 - ],
106 required: true, 40 required: true,
107 - }, { 41 + },
108 - key: 'city', 42 + // {
109 - value: '天津市/天津市/和平区', 43 + // key: 'username',
110 - city_code: '120101', 44 + // value: 'test',
111 - label: '省市区', 45 + // label: '用户名',
112 - placeholder: '请选择省市区', 46 + // placeholder: '请输入用户名',
113 - component_props: { 47 + // component: '',
114 - name: 'area_picker' 48 + // component_props: {
115 - }, 49 + // name: 'text'
116 - }, { 50 + // },
117 - key: 'datetime', 51 + // required: true,
118 - value: [], 52 + // },
119 - label: '日期选择', 53 + // {
120 - placeholder: '请选择日期', 54 + // key: 'age',
121 - component_props: { 55 + // value: '',
122 - name: 'date_picker', 56 + // label: '年龄',
123 - title: '请选择', 57 + // placeholder: '请输入年龄',
124 - min_date: new Date(), 58 + // component: '',
125 - columns_type: ['year', 'month'] 59 + // component_props: {
126 - }, 60 + // name: 'number'
127 - }, { 61 + // },
62 + // required: false,
63 + // },
64 + // {
65 + // key: 'gender',
66 + // value: '',
67 + // label: '性别',
68 + // placeholder: '',
69 + // component: '',
70 + // component_props: {
71 + // name: 'radio'
72 + // },
73 + // options: [{
74 + // key: '男',
75 + // value: '男'
76 + // }, {
77 + // key: '女',
78 + // value: '女'
79 + // }]
80 + // },
81 + // {
82 + // key: 'hobby',
83 + // value: [],
84 + // label: '兴趣爱好',
85 + // placeholder: '',
86 + // component: '',
87 + // component_props: {
88 + // name: 'checkbox'
89 + // },
90 + // options: [{
91 + // key: '足球',
92 + // value: '足球'
93 + // }, {
94 + // key: '篮球',
95 + // value: '篮球'
96 + // }]
97 + // },
98 + // {
99 + // key: 'message',
100 + // value: 'zzz',
101 + // label: '留言',
102 + // placeholder: '请输入留言',
103 + // component: '',
104 + // component_props: {
105 + // name: 'textarea'
106 + // },
107 + // },
108 + // {
109 + // key: 'vehicle',
110 + // value: '自行车',
111 + // label: '交通工具',
112 + // placeholder: '请选择交通工具',
113 + // component: '',
114 + // component_props: {
115 + // name: 'picker'
116 + // },
117 + // options: [
118 + // { text: '自行车', value: '自行车' },
119 + // { text: '汽车', value: '汽车' },
120 + // { text: '地铁', value: '地铁' },
121 + // ],
122 + // required: true,
123 + // },
124 + // {
125 + // key: 'city',
126 + // value: '天津市/天津市/和平区',
127 + // city_code: '120101',
128 + // label: '省市区',
129 + // placeholder: '请选择省市区',
130 + // component_props: {
131 + // name: 'area_picker'
132 + // },
133 + // },
134 + // {
135 + // key: 'datetime',
136 + // value: [],
137 + // label: '日期选择',
138 + // placeholder: '请选择日期',
139 + // component_props: {
140 + // name: 'date_picker',
141 + // title: '请选择',
142 + // min_date: new Date(),
143 + // columns_type: ['year', 'month']
144 + // },
145 + // },
146 + {
128 key: 'imageUploader', 147 key: 'imageUploader',
129 value: '', 148 value: '',
130 label: '图片上传', 149 label: '图片上传',
......