hookehuyr

组件注释调整优化

<!--
* @Date: 2022-08-30 14:32:11
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-09-07 16:05:51
* @LastEditTime: 2022-11-21 14:32:24
* @FilePath: /data-table/src/components/AreaPickerField/index.vue
* @Description: 文件描述
* @Description: 省市区选择控件
-->
<template>
<div class="area-picker-field">
<div class="label">{{ item.label }}<span v-if="item.required">&nbsp;*</span></div>
<van-field v-model="item.value" is-link readonly :name="item.key" :required="item.required"
:placeholder="item.placeholder" :rules="item.rules" @click="showPicker = true" :border="false" />
<van-field name="address" v-model="item.address" placeholder="详细地址" :border="false" />
<van-field
v-model="item.value"
is-link
readonly
:name="item.key"
:required="item.required"
:placeholder="item.placeholder"
:rules="item.rules"
@click="showPicker = true"
:border="false"
/>
<van-field
name="address"
v-model="item.address"
placeholder="详细地址"
:border="false"
/>
<van-popup v-model:show="showPicker" position="bottom">
<van-area name="city_code" v-model="item.city_code" title="" :area-list="areaList" @confirm="onConfirm"
@cancel="showPicker = false" />
<van-area
name="city_code"
v-model="item.city_code"
title=""
:area-list="areaList"
@confirm="onConfirm"
@cancel="showPicker = false"
/>
</van-popup>
</div>
</template>
<script setup>
import { areaList } from '@vant/area-data';
import { areaList } from "@vant/area-data";
const props = defineProps({
item: Object
item: Object,
});
const address = ref('')
const address = ref("");
const showPicker = ref(false);
const fieldValue = ref('');
const fieldValue = ref("");
const onConfirm = ({ selectedOptions }) => {
props.item.value = selectedOptions.map((option) => option.text).join('/');
props.item.value = selectedOptions.map((option) => option.text).join("/");
props.item.city_code = selectedOptions[2]?.value;
showPicker.value = false;
};
......
<!--
* @Date: 2022-09-14 11:00:01
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-09-14 14:24:41
* @LastEditTime: 2022-11-21 14:38:06
* @FilePath: /data-table/src/components/CalendarField/index.vue
* @Description: 文件描述
* @Description: 日历选择控件
-->
<template>
<div class="calendar-page">
<div class="label">
{{ item.component_props.label
}}<span v-if="item.component_props.required">&nbsp;*</span>
{{ item.component_props.label }}
<span v-if="item.component_props.required">&nbsp;*</span>
</div>
<van-field
v-model="item.value"
......
<!--
* @Date: 2022-08-30 11:34:19
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-11-08 08:01:23
* @LastEditTime: 2022-11-21 14:42:00
* @FilePath: /data-table/src/components/CheckboxField/index.vue
* @Description: 文件描述
* @Description: 多项选择控件
-->
<template>
<div class="checkbox-field-page">
<div class="label">
{{ item.label }}
<span v-if="item.component_props.required" style="color: red">&nbsp;*</span>
<span v-if="item.component_props.max" style="color: gray"
>(最多可选数:&nbsp;{{ item.component_props.max }})</span
>
<span v-if="item.component_props.max" style="color: gray">
(最多可选数:&nbsp;{{ item.component_props.max }})
</span>
</div>
<van-field :name="item.key" :rules="item.rules" :border="false">
<template #input>
......
<!--
* @Date: 2022-08-31 11:45:30
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-09-07 13:52:57
* @LastEditTime: 2022-11-21 14:43:16
* @FilePath: /data-table/src/components/DatePickerField/index.vue
* @Description: 日期选择组件
-->
<template>
<div class="date-picker-field">
<div class="label">
{{ item.component_props.label
}}<span v-if="item.component_props.required">&nbsp;*</span>
{{ item.component_props.label }}
<span v-if="item.component_props.required">&nbsp;*</span>
</div>
<van-field
v-model="item.value"
......
<!--
* @Date: 2022-09-08 15:02:45
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-09-16 15:04:37
* @LastEditTime: 2022-11-21 14:47:52
* @FilePath: /data-table/src/components/DateTimePickerField/index.vue
* @Description: 文件描述
* @Description: 日期时间选择器
-->
<template>
<div class="datetime-picker">
......
<!--
* @Date: 2022-09-14 14:44:30
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-09-14 14:55:53
* @LastEditTime: 2022-11-21 14:49:52
* @FilePath: /data-table/src/components/IdentityField/index.vue
* @Description: 文件描述
* @Description: 身份证输入控件
-->
<template>
<div class="identity-page">
<div class="label">{{ item.component_props.label }}<span v-if="item.component_props.required">&nbsp;*</span></div>
<van-field v-model="item.value" :name="item.name" :placeholder="item.component_props.placeholder"
:rules="rules" :required="item.component_props.required" readonly @touchstart.stop="show = true" :border="false">
<div class="label">
{{ item.component_props.label
}}<span v-if="item.component_props.required">&nbsp;*</span>
</div>
<van-field
v-model="item.value"
:name="item.name"
:placeholder="item.component_props.placeholder"
:rules="rules"
:required="item.component_props.required"
readonly
@touchstart.stop="show = true"
:border="false"
>
</van-field>
<van-number-keyboard
v-model="item.value"
......@@ -25,7 +36,7 @@
<script setup>
const props = defineProps({
item: Object
item: Object,
});
const show = ref(false);
......@@ -33,8 +44,9 @@ const show = ref(false);
// 校验函数返回 true 表示校验通过,false 表示不通过
// 身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X
const validator = (val) => {
if (!props.item.component_props.required) { // 非必填
return true
if (!props.item.component_props.required) {
// 非必填
return true;
} else {
return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(val);
}
......@@ -42,12 +54,12 @@ const validator = (val) => {
// 错误提示文案
const validatorMessage = (val, rule) => {
if (!val) {
return '身份证号码不能为空';
return "身份证号码不能为空";
} else if (!/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(val)) {
return '请输入正确身份证号码';
return "请输入正确身份证号码";
}
}
const rules = [{ validator, message: validatorMessage }]
};
const rules = [{ validator, message: validatorMessage }];
const onInput = (value) => {};
const onDelete = () => {};
......
<!--
* @Date: 2022-08-31 16:16:49
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-09-07 13:56:29
* @LastEditTime: 2022-11-21 14:54:30
* @FilePath: /data-table/src/components/ImageUploaderField/index.vue
* @Description: 文件描述
* @Description: 图片上传控件
-->
<template>
<div class="image-uploader-field">
<div class="label">{{ item.label }}<span v-if="item.required">&nbsp;*</span></div>
<div style="padding: 1rem;">
<van-uploader upload-icon="add" :before-read="beforeRead" :after-read="afterRead" v-model="fileList"
:multiple="item.component_props.multiple" />
<div style="padding: 1rem">
<van-uploader
upload-icon="add"
:before-read="beforeRead"
:after-read="afterRead"
v-model="fileList"
:multiple="item.component_props.multiple"
/>
</div>
<div class="type-text">上传格式:{{ type_text }}</div>
</div>
......@@ -22,33 +27,37 @@
* @param name[String] 组件名称
* @param image_type[Array] 图片上传类型
* @param multiple[Boolean] 图片多选
*/
import { Toast } from 'vant';
import _ from 'lodash'
import { v4 as uuidv4 } from 'uuid';
import { qiniuTokenAPI, qiniuUploadAPI, saveFileAPI } from '@/api/common'
*/
import { Toast } from "vant";
import _ from "lodash";
import { v4 as uuidv4 } from "uuid";
import { qiniuTokenAPI, qiniuUploadAPI, saveFileAPI } from "@/api/common";
const props = defineProps({
item: Object
})
item: Object,
});
const type_text = computed(() => {
return props.item.component_props.image_type.join('/')
})
return props.item.component_props.image_type.join("/");
});
// 上传前置处理
const beforeRead = (file) => {
const image_types = _.map(props.item.component_props.image_type, item => `image/${item}`)
const image_types = _.map(
props.item.component_props.image_type,
(item) => `image/${item}`
);
let flag = true;
if (_.isArray(file)) { // 多张图片
const types = _.difference(_.uniq(_.map(file, item => item.type)), image_types); // 数组返回不能上传的类型
if (_.isArray(file)) {
// 多张图片
const types = _.difference(_.uniq(_.map(file, (item) => item.type)), image_types); // 数组返回不能上传的类型
if (types.length) {
flag = false;
Toast('请上传指定格式图片');
Toast("请上传指定格式图片");
}
} else {
if (!_.includes(image_types, file.type)) {
Toast('请上传指定格式图片');
Toast("请上传指定格式图片");
flag = false;
}
}
......@@ -58,28 +67,41 @@ const beforeRead = (file) => {
const afterRead = async (file) => {
// 此时可以自行将文件上传至服务器
let affix = uuidv4();
let base64url = file.content.slice(file.content.indexOf(',') + 1); // 截取前缀的base64 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAnoAAAJeCAYAA.......
let base64url = file.content.slice(file.content.indexOf(",") + 1); // 截取前缀的base64 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAnoAAAJeCAYAA.......
// 获取七牛token
const { token, key, code } = await qiniuTokenAPI({ filename: `${affix}_image_upload`, file: base64url });
const { token, key, code } = await qiniuTokenAPI({
filename: `${affix}_image_upload`,
file: base64url,
});
if (code) {
const config = {
headers: {
'Content-Type': 'application/octet-stream',
'Authorization': 'UpToken ' + token, // UpToken后必须有一个 ' '(空格)
}
}
"Content-Type": "application/octet-stream",
Authorization: "UpToken " + token, // UpToken后必须有一个 ' '(空格)
},
};
// 上传七牛服务器
const { filekey, hash, image_info } = await qiniuUploadAPI('http://upload.qiniup.com/putb64/-1/key/' + key, base64url, config)
const { filekey, hash, image_info } = await qiniuUploadAPI(
"http://upload.qiniup.com/putb64/-1/key/" + key,
base64url,
config
);
if (filekey) {
// 保存图片
const { data } = await saveFileAPI({ filekey, hash, format: image_info.format, height: image_info.height, width: image_info.width });
const { data } = await saveFileAPI({
filekey,
hash,
format: image_info.format,
height: image_info.height,
width: image_info.width,
});
console.warn(data.src);
}
}
};
const fileList = ref([
{ url: 'https://fastly.jsdelivr.net/npm/@vant/assets/leaf.jpeg' },
{ url: "https://fastly.jsdelivr.net/npm/@vant/assets/leaf.jpeg" },
// Uploader 根据文件后缀来判断是否为图片文件
// 如果图片 URL 中不包含类型信息,可以添加 isImage 标记来声明
// { url: 'https://cloud-image', isImage: true },
......
<!--
* @Date: 2022-09-02 10:46:03
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-11-18 11:08:29
* @LastEditTime: 2022-11-21 14:59:02
* @FilePath: /data-table/src/components/PhoneField/index.vue
* @Description: 文件描述
* @Description: 手机输入框
-->
<template>
<div class="phone-field-page">
......
<!--
* @Date: 2022-08-30 11:34:19
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-09-16 17:40:39
* @LastEditTime: 2022-11-21 15:15:51
* @FilePath: /data-table/src/components/RadioField/index.vue
* @Description: 文件描述
* @Description: 单项选择控件
-->
<template>
<div class="radio-field-page">
......
<!--
* @Date: 2022-09-08 15:47:54
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-09-08 16:20:11
* @LastEditTime: 2022-11-21 15:16:10
* @FilePath: /data-table/src/components/RatePickerField/index.vue
* @Description: 文件描述
* @Description: 评分选择控件
-->
<template>
<div class="rate-field">
......
......@@ -7,24 +7,34 @@
-->
<template>
<div class="text-field-page">
<div class="label">{{ item.component_props.label }}<span v-if="item.component_props.required">&nbsp;*</span></div>
<van-field v-model="item.value"
:name="item.name" :type="item.type" :placeholder="item.component_props.placeholder"
:rules="item.rules" :required="item.required"
:readonly="item.component_props.readonly" :disabled="item.component_props.disabled"
<div class="label">
{{ item.component_props.label
}}<span v-if="item.component_props.required">&nbsp;*</span>
</div>
<van-field
v-model="item.value"
:name="item.name"
:type="item.type"
:placeholder="item.component_props.placeholder"
:rules="item.rules"
:required="item.required"
:readonly="item.component_props.readonly"
:disabled="item.component_props.disabled"
:input-align="item.component_props.align"
clearable :border="false" />
clearable
:border="false"
/>
</div>
</template>
<script setup>
const props = defineProps({
item: Object
})
item: Object,
});
</script>
<style lang="less" scoped>
.text-field-page {
.text-field-page {
.label {
padding: 1rem 1rem 0 1rem;
font-size: 0.9rem;
......@@ -33,5 +43,5 @@ const props = defineProps({
color: red;
}
}
}
}
</style>
......
<!--
* @Date: 2022-08-31 11:45:30
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2022-09-08 10:06:46
* @LastEditTime: 2022-11-21 15:21:56
* @FilePath: /data-table/src/components/TimePickerField/index.vue
* @Description: 日期选择组件
* @Description: 时间选择组件
-->
<template>
<div class="time-picker-field">
......
......@@ -57,11 +57,6 @@ export function createComponentType(data) {
item.autosize = true;
item.component = TextareaField;
}
// if (item.component_props.name === 'number') {
// item.type = 'number';
// item.name = item.key;
// item.component = TextField;
// }
if (item.component_props.name === 'number') {
item.name = item.key;
item.component = NumberField;
......