Showing
5 changed files
with
191 additions
and
7 deletions
src/components/TableField/index.vue
0 → 100644
| 1 | +<!-- | ||
| 2 | + * @Date: 2022-08-29 14:31:20 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2022-08-29 16:44:53 | ||
| 5 | + * @FilePath: /data-table/src/components/TableField/index.vue | ||
| 6 | + * @Description: 文件描述 | ||
| 7 | +--> | ||
| 8 | +<template> | ||
| 9 | + <van-field v-if="item.component_type === 'radio'" :name="item.key" :label="item.label"> | ||
| 10 | + <template #input> | ||
| 11 | + <van-radio-group v-model="item.value" direction="horizontal"> | ||
| 12 | + <van-radio v-for="x in item.sub" :key="index" :name="x.key">{{ x.value }}</van-radio> | ||
| 13 | + </van-radio-group> | ||
| 14 | + </template> | ||
| 15 | + </van-field> | ||
| 16 | + <van-field v-else v-model="item.value" :name="item.name" :label="item.label" :type="item.type" | ||
| 17 | + :placeholder="item.placeholder" :rules="item.rules" :required="item.required" :autosize="item.autosize" | ||
| 18 | + :row="item.row" /> | ||
| 19 | +</template> | ||
| 20 | + | ||
| 21 | +<script setup> | ||
| 22 | +const props = defineProps({ | ||
| 23 | + item: Object | ||
| 24 | +}) | ||
| 25 | +</script> | ||
| 26 | + | ||
| 27 | +<style lang="less" scoped> | ||
| 28 | +</style> |
src/components/TextField/index.vue
0 → 100644
| 1 | +<!-- | ||
| 2 | + * @Date: 2022-08-29 14:31:20 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2022-08-30 10:15:20 | ||
| 5 | + * @FilePath: /data-table/src/components/TextField/index.vue | ||
| 6 | + * @Description: 单行文本输入框 | ||
| 7 | +--> | ||
| 8 | +<template> | ||
| 9 | + <div class="text-field-page"> | ||
| 10 | + <div class="label">{{ item.label }}<span v-if="item.required"> *</span></div> | ||
| 11 | + <van-field v-model="item.value" :name="item.name" :type="item.type" :placeholder="item.placeholder" | ||
| 12 | + :rules="item.rules" :required="item.required" /> | ||
| 13 | + </div> | ||
| 14 | +</template> | ||
| 15 | + | ||
| 16 | +<script setup> | ||
| 17 | +const props = defineProps({ | ||
| 18 | + item: Object | ||
| 19 | +}) | ||
| 20 | +</script> | ||
| 21 | + | ||
| 22 | +<style lang="less" scoped> | ||
| 23 | + .text-field-page { | ||
| 24 | + .label { | ||
| 25 | + padding: 1rem 1rem 0 1rem; | ||
| 26 | + font-size: 0.9rem; | ||
| 27 | + font-weight: bold; | ||
| 28 | + span { | ||
| 29 | + color: red; | ||
| 30 | + } | ||
| 31 | + } | ||
| 32 | + } | ||
| 33 | +</style> |
src/components/TextareaField/index.vue
0 → 100644
| 1 | +<!-- | ||
| 2 | + * @Date: 2022-08-29 14:31:20 | ||
| 3 | + * @LastEditors: hookehuyr hookehuyr@gmail.com | ||
| 4 | + * @LastEditTime: 2022-08-30 10:18:18 | ||
| 5 | + * @FilePath: /data-table/src/components/TextareaField/index.vue | ||
| 6 | + * @Description: 多行文本输入框 | ||
| 7 | +--> | ||
| 8 | +<template> | ||
| 9 | + <div class="textarea-field-page"> | ||
| 10 | + <div class="label">{{ item.label }}<span v-if="item.required"> *</span></div> | ||
| 11 | + <van-field v-model="item.value" :name="item.name" :type="item.type" :placeholder="item.placeholder" | ||
| 12 | + :rules="item.rules" :required="item.required" rows="2" autosize /> | ||
| 13 | + </div> | ||
| 14 | +</template> | ||
| 15 | + | ||
| 16 | +<script setup> | ||
| 17 | +const props = defineProps({ | ||
| 18 | + item: Object | ||
| 19 | +}) | ||
| 20 | +</script> | ||
| 21 | + | ||
| 22 | +<style lang="less" scoped> | ||
| 23 | + .textarea-field-page { | ||
| 24 | + .label { | ||
| 25 | + padding: 1rem 1rem 0 1rem; | ||
| 26 | + font-size: 0.9rem; | ||
| 27 | + font-weight: bold; | ||
| 28 | + span { | ||
| 29 | + color: red; | ||
| 30 | + } | ||
| 31 | + } | ||
| 32 | + } | ||
| 33 | +</style> |
src/hooks/useComponentType.js
0 → 100644
| 1 | +import _ from 'lodash' | ||
| 2 | +import TableField from '@/components/TableField/index.vue' | ||
| 3 | +import TextField from '@/components/TextField/index.vue' | ||
| 4 | +import TextareaField from '@/components/TextareaField/index.vue' | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * 生成自定义组件类型 | ||
| 8 | + * @param {*} data | ||
| 9 | + * @type text 单行文本 TextField | ||
| 10 | + * @type textarea 多行文本 TextareaField | ||
| 11 | + */ | ||
| 12 | +export function createComponentType(data) { | ||
| 13 | + // 判断类型和使用组件 | ||
| 14 | + _.each(data, (item, index) => { | ||
| 15 | + if (item.component_type === 'text') { | ||
| 16 | + item.type = 'text'; | ||
| 17 | + item.name = item.key; | ||
| 18 | + item.component = TextField; | ||
| 19 | + } | ||
| 20 | + if (item.component_type === 'textarea') { | ||
| 21 | + item.type = 'textarea'; | ||
| 22 | + item.name = item.key; | ||
| 23 | + item.component = TextareaField; | ||
| 24 | + } | ||
| 25 | + // // 单选框 | ||
| 26 | + // if (item.component_type === 'radio') { | ||
| 27 | + // item.name = 'radio'; | ||
| 28 | + // item.component = TableField; | ||
| 29 | + // } | ||
| 30 | + }) | ||
| 31 | +} |
| 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-25 10:10:29 | 4 | + * @LastEditTime: 2022-08-30 10:18:56 |
| 5 | - * @FilePath: /front/src/views/index.vue | 5 | + * @FilePath: /data-table/src/views/index.vue |
| 6 | * @Description: 首页 | 6 | * @Description: 首页 |
| 7 | --> | 7 | --> |
| 8 | <template> | 8 | <template> |
| 9 | - <div>111</div> | 9 | + <van-image width="100%" height="200" src="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg" /> |
| 10 | + <div style="padding: 1rem;">表单描述</div> | ||
| 11 | + <div style="padding: 1rem;"> | ||
| 12 | + <van-form @submit="onSubmit"> | ||
| 13 | + <van-cell-group> | ||
| 14 | + <component v-for="(item, index) in mockData" :key="index" :is="item.component" :item="item" /> | ||
| 15 | + </van-cell-group> | ||
| 16 | + <div style="margin: 16px;"> | ||
| 17 | + <van-button round block type="primary" native-type="submit"> | ||
| 18 | + 提交 | ||
| 19 | + </van-button> | ||
| 20 | + </div> | ||
| 21 | + </van-form> | ||
| 22 | + </div> | ||
| 23 | + | ||
| 10 | </template> | 24 | </template> |
| 11 | 25 | ||
| 12 | <script setup> | 26 | <script setup> |
| 13 | -import { _, dayjs, Cookies, $ } from '@/utils/generatePackage' | 27 | +import { createComponentType } from '@/hooks/useComponentType' |
| 28 | + | ||
| 29 | +const mockData = ref([]); | ||
| 30 | +onMounted(() => { | ||
| 31 | + mockData.value = [{ | ||
| 32 | + key: 'username', | ||
| 33 | + value: 'Hooke', | ||
| 34 | + label: '用户名', | ||
| 35 | + placeholder: '请输入用户名', | ||
| 36 | + rules: [{ required: true, message: '请填写用户名' }], | ||
| 37 | + component: '', | ||
| 38 | + component_type: 'text', | ||
| 39 | + required: true, | ||
| 40 | + }, { | ||
| 41 | + key: 'age', | ||
| 42 | + value: '', | ||
| 43 | + label: '年龄', | ||
| 44 | + placeholder: '请输入年龄', | ||
| 45 | + component: '', | ||
| 46 | + component_type: 'text', | ||
| 47 | + required: false, | ||
| 48 | + }, { | ||
| 49 | + key: 'gender', | ||
| 50 | + value: 'female', | ||
| 51 | + label: '性别', | ||
| 52 | + placeholder: '', | ||
| 53 | + component: '', | ||
| 54 | + component_type: 'radio', | ||
| 55 | + sub: [{ | ||
| 56 | + key: 'male', | ||
| 57 | + value: '男' | ||
| 58 | + }, { | ||
| 59 | + key: 'female', | ||
| 60 | + value: '女' | ||
| 61 | + }] | ||
| 62 | + }, { | ||
| 63 | + key: 'message', | ||
| 64 | + value: 'zzz', | ||
| 65 | + label: '留言', | ||
| 66 | + placeholder: '请输入留言', | ||
| 67 | + component: '', | ||
| 68 | + component_type: 'textarea', | ||
| 69 | + }]; | ||
| 70 | + // 生成自定义组件 | ||
| 71 | + createComponentType(mockData.value) | ||
| 72 | +}) | ||
| 14 | 73 | ||
| 15 | -const go = useGo() | 74 | +const onSubmit = (values) => { |
| 16 | -const goTo = useGoTo(); | 75 | + console.log('submit', values); |
| 76 | +}; | ||
| 17 | 77 | ||
| 18 | </script> | 78 | </script> |
| 19 | 79 | ||
| 20 | <style lang="less" scoped> | 80 | <style lang="less" scoped> |
| 21 | - | ||
| 22 | </style> | 81 | </style> | ... | ... |
-
Please register or login to post a comment