hookehuyr

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

<!--
* @Date: 2022-09-02 10:46:03
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-09-02 11:36:29
* @FilePath: /data-table/src/components/PhoneField/index.vue
* @Description: 文件描述
-->
<template>
<div class="phone-field-page">
<div class="label">{{ item.label }}<span v-if="item.required">&nbsp;*</span></div>
<van-field v-model="item.value" :name="item.name" type="digit" maxlength="11" :placeholder="item.placeholder"
:rules="rules" :required="item.required" :readonly="readonly" @touchstart.stop="show = true"></van-field>
<van-number-keyboard v-model="item.value" :show="show" :maxlength="11" @blur="show = false" />
</div>
</template>
<script setup>
import { wxInfo } from '@/utils/tools'
const props = defineProps({
item: Object
});
// web端判断
const readonly = computed(() => wxInfo().isMobile)
// 校验函数返回 true 表示校验通过,false 表示不通过
const validator = (val) => {
if (!props.item.required) { // 非必填
return true
} else {
return /1\d{10}/.test(val);
}
};
// 错误提示文案
const validatorMessage = (val, rule) => {
if (!val) {
return '手机号码不能为空';
} else if (!/1\d{10}/.test(val)) {
return '请输入正确手机号码';
}
}
const rules = [{ validator, message: validatorMessage }]
const show = ref(false);
</script>
<style lang="less" scoped>
.phone-field-page {
.label {
padding: 1rem 1rem 0 1rem;
font-size: 0.9rem;
font-weight: bold;
span {
color: red;
}
}
}
</style>
......@@ -8,6 +8,7 @@ import PickerField from '@/components/PickerField/index.vue'
import AreaPickerField from '@/components/AreaPickerField/index.vue'
import DatePickerField from '@/components/DatePickerField/index.vue'
import ImageUploaderField from '@/components/ImageUploaderField/index.vue'
import PhoneField from '@/components/PhoneField/index.vue'
/**
* 生成自定义组件类型
......@@ -20,6 +21,7 @@ import ImageUploaderField from '@/components/ImageUploaderField/index.vue'
* @type area_picker 省市区选择器 AreaPickerField
* @type date_picker 日期选择器 DatePickerField
* @type image_uploader 图片上传 ImageUploaderField
* @type phone 手机输入框 PhoneField
*/
export function createComponentType(data) {
// 判断类型和使用组件
......@@ -63,5 +65,9 @@ export function createComponentType(data) {
if (item.component_props.name === 'image_uploader') {
item.component = ImageUploaderField;
}
if (item.component_props.name === 'phone') {
item.name = item.key;
item.component = PhoneField;
}
})
}
......
<!--
* @Date: 2022-07-18 10:22:22
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-08-31 13:37:32
* @LastEditTime: 2022-09-02 11:16:29
* @FilePath: /data-table/src/views/index.vue
* @Description: 首页
-->
......@@ -29,102 +29,121 @@ import { createComponentType } from '@/hooks/useComponentType'
const mockData = ref([]);
onMounted(() => {
mockData.value = [{
key: 'username',
value: 'test',
label: '用户名',
placeholder: '请输入用户名',
component: '',
component_props: {
name: 'text'
},
required: true,
}, {
key: 'age',
value: '',
label: '年龄',
placeholder: '请输入年龄',
component: '',
component_props: {
name: 'number'
},
required: false,
}, {
key: 'gender',
key: 'phone',
value: '',
label: '性别',
placeholder: '',
component: '',
component_props: {
name: 'radio'
},
options: [{
key: '男',
value: '男'
}, {
key: '女',
value: '女'
}]
}, {
key: 'hobby',
value: [],
label: '兴趣爱好',
placeholder: '',
component: '',
component_props: {
name: 'checkbox'
},
options: [{
key: '足球',
value: '足球'
}, {
key: '篮球',
value: '篮球'
}]
}, {
key: 'message',
value: 'zzz',
label: '留言',
placeholder: '请输入留言',
component: '',
component_props: {
name: 'textarea'
},
}, {
key: 'vehicle',
value: '自行车',
label: '交通工具',
placeholder: '请选择交通工具',
label: '手机号',
placeholder: '请输入手机号',
component: '',
component_props: {
name: 'picker'
name: 'phone'
},
options: [
{ text: '自行车', value: '自行车' },
{ text: '汽车', value: '汽车' },
{ text: '地铁', value: '地铁' },
],
required: true,
}, {
key: 'city',
value: '天津市/天津市/和平区',
city_code: '120101',
label: '省市区',
placeholder: '请选择省市区',
component_props: {
name: 'area_picker'
},
}, {
key: 'datetime',
value: [],
label: '日期选择',
placeholder: '请选择日期',
component_props: {
name: 'date_picker',
title: '请选择',
min_date: new Date(),
columns_type: ['year', 'month']
},
}, {
// {
// key: 'username',
// value: 'test',
// label: '用户名',
// placeholder: '请输入用户名',
// component: '',
// component_props: {
// name: 'text'
// },
// required: true,
// },
// {
// key: 'age',
// value: '',
// label: '年龄',
// placeholder: '请输入年龄',
// component: '',
// component_props: {
// name: 'number'
// },
// required: false,
// },
// {
// key: 'gender',
// value: '',
// label: '性别',
// placeholder: '',
// component: '',
// component_props: {
// name: 'radio'
// },
// options: [{
// key: '男',
// value: '男'
// }, {
// key: '女',
// value: '女'
// }]
// },
// {
// key: 'hobby',
// value: [],
// label: '兴趣爱好',
// placeholder: '',
// component: '',
// component_props: {
// name: 'checkbox'
// },
// options: [{
// key: '足球',
// value: '足球'
// }, {
// key: '篮球',
// value: '篮球'
// }]
// },
// {
// key: 'message',
// value: 'zzz',
// label: '留言',
// placeholder: '请输入留言',
// component: '',
// component_props: {
// name: 'textarea'
// },
// },
// {
// key: 'vehicle',
// value: '自行车',
// label: '交通工具',
// placeholder: '请选择交通工具',
// component: '',
// component_props: {
// name: 'picker'
// },
// options: [
// { text: '自行车', value: '自行车' },
// { text: '汽车', value: '汽车' },
// { text: '地铁', value: '地铁' },
// ],
// required: true,
// },
// {
// key: 'city',
// value: '天津市/天津市/和平区',
// city_code: '120101',
// label: '省市区',
// placeholder: '请选择省市区',
// component_props: {
// name: 'area_picker'
// },
// },
// {
// key: 'datetime',
// value: [],
// label: '日期选择',
// placeholder: '请选择日期',
// component_props: {
// name: 'date_picker',
// title: '请选择',
// min_date: new Date(),
// columns_type: ['year', 'month']
// },
// },
{
key: 'imageUploader',
value: '',
label: '图片上传',
......