index.vue 7.36 KB
<!--
 * @Date: 2022-07-18 10:22:22
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2022-09-14 14:56:30
 * @FilePath: /data-table/src/views/index.vue
 * @Description: 首页
-->
<template>
  <van-image v-if="table_cover" width="100%" height="200" :src="table_cover" />
  <div v-if="table_title" class="table-title">{{ table_title }}</div>
  <div class="table-box">
    <van-form @submit="onSubmit">
      <van-cell-group>
        <component :ref="item.component_props.name" v-for="(item, index) in mockData" :key="index" :is="item.component" :item="item" @active="onActive" />
      </van-cell-group>
      <div style="margin: 16px;">
        <van-button round block type="primary" native-type="submit">
          提交
        </van-button>
      </div>
    </van-form>
  </div>
</template>

<script setup>
import { createComponentType } from '@/hooks/useComponentType'
import _ from 'lodash'

const table_cover = ref('');
const table_title = ref('');
const mockData = ref([]);
const postData = ref({})

onMounted(() => {
  table_cover.value = 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg'
  table_title.value = '这是一个表单的描述'
  mockData.value = [
  // {
  //   key: 'phone',
  //   value: '',
  //   label: '手机号',
  //   placeholder: '请输入手机号',
  //   component: '',
  //   component_props: {
  //     name: 'phone'
  //   },
  //   required: true,
  // },
  // {
  //   key: 'username',
  //   value: 'test',
  //   label: '用户名',
  //   placeholder: '请输入用户名',
  //   component: '',
  //   component_props: {
  //     name: 'text',
  //     // readonly: true,
  //     // disabled: true,
  //     // align: 'left',
  //   },
  //   required: true,
  // },
  // {
  //   key: 'date',
  //   value: '',
  //   label: '日历选择',
  //   placeholder: '请选择日历日期',
  //   component: '',
  //   component_props: {
  //     name: 'calendar',
  //     type: 'range', // 日期区间 ['multiple', 'range']
  //     minDate: new Date(2022, 0, 1), // 最小日期
  //     maxDate: new Date(2023, 0, 31), // 最大日期
  //     maxRange: 5, // 最大可选天数
  //   },
  //   required: false,
  // },
  // {
  //   key: 'email',
  //   value: '',
  //   label: '邮箱',
  //   placeholder: '请输入邮箱',
  //   component: '',
  //   component_props: {
  //     name: 'email'
  //   },
  //   required: true,
  // },
  {
    key: 'id_code',
    value: '',
    label: '身份证号码',
    placeholder: '请输入身份证号码',
    component: '',
    component_props: {
      name: 'id_code'
    },
    required: true,
  },
  // {
  //   key: 'age',
  //   value: '',
  //   label: '年龄',
  //   placeholder: '请输入年龄',
  //   component: '',
  //   component_props: {
  //     name: 'number'
  //   },
  //   required: true,
  // },
  // {
  //   key: 'gender',
  //   value: '',
  //   label: '性别',
  //   placeholder: '',
  //   component: '',
  //   component_props: {
  //     name: 'radio',
  //     direction: 'horizontal'
  //   },
  //   options: [{
  //     key: '男',
  //     value: '男'
  //   }, {
  //     key: '女',
  //     value: '女'
  //   }]
  // },
  // {
  //   key: 'hobby',
  //   value: [],
  //   label: '兴趣爱好',
  //   component: '',
  //   component_props: {
  //     name: 'checkbox',
  //     direction: 'horizontal',
  //     max: '3'
  //   },
  //   options: [{
  //     key: '足球',
  //     value: '足球'
  //   }, {
  //     key: '篮球',
  //     value: '篮球'
  //   }, {
  //     key: '羽毛球',
  //     value: '羽毛球'
  //   }, {
  //     key: '乒乓球',
  //     value: '乒乓球'
  //   }]
  // },
  // {
  //   key: 'message',
  //   value: '一种可以用来记录,展示文字信息的载体,有比较强的时效性。一般以黑板、木板为载体。用来留言。各种各样的留言使用。留言板还有引申的“网络留言板”。这个和网络留言本不一样的地方是留言板一般比较集中的反应信息的。',
  //   label: '留言',
  //   placeholder: '请输入留言',
  //   component: '',
  //   component_props: {
  //     name: 'textarea',
  //     rows: 3,
  //     maxlength: null,
  //   },
  // },
  // {
  //   key: 'vehicle',
  //   value: '自行车',
  //   label: '交通工具',
  //   placeholder: '请选择交通工具',
  //   component: '',
  //   component_props: {
  //     name: 'picker'
  //   },
  //   options: [
  //     { text: '自行车', value: '自行车' },
  //     { text: '汽车', value: '汽车' },
  //     { text: '地铁', value: '地铁' },
  //   ],
  //   required: true,
  // },
  // {
  //   key: 'sign',
  //   value: '',
  //   label: '电子签名',
  //   placeholder: '',
  //   component: '',
  //   component_props: {
  //     name: 'sign',
  //   },
  //   required: true,
  // },
  // {
  //   key: 'city',
  //   value: '天津市/天津市/和平区',
  //   city_code: '120101',
  //   label: '地址',
  //   address: '',
  //   placeholder: '请选择省市区',
  //   component_props: {
  //     name: 'area_picker'
  //   },
  // },
  // {
  //   key: 'date',
  //   value: '2022-10',
  //   label: '日期选择',
  //   placeholder: '请选择日期',
  //   component_props: {
  //     name: 'date_picker',
  //     title: '请选择',
  //     min_date: new Date(),
  //     columns_type: ['year', 'month']
  //   },
  // },
  // {
  //   key: 'time',
  //   value: '',
  //   label: '时间选择',
  //   placeholder: '请选择时间',
  //   component_props: {
  //     name: 'time_picker',
  //     title: '请选择',
  //     columns_type: ['hour', 'minute']
  //   },
  //   required: true,
  // },
  // {
  //   key: 'image_src',
  //   value: '',
  //   label: '图片上传',
  //   component_props: {
  //     name: 'image_uploader',
  //     image_type: ['jpg', 'png'],
  //     multiple: false
  //   }
  // }
  // {
  //   key: 'datetime',
  //   value: '2022-06-01 12:00',
  //   label: '日期时间',
  //   placeholder: '请选择日期时间',
  //   component_props: {
  //     name: 'datetime_picker',
  //     title: '请选择',
  //     minDate: new Date(),
  //   },
  //   required: true,
  // },
  // {
  //   key: 'rate',
  //   value: '',
  //   label: '评分',
  //   placeholder: '请选择评分',
  //   component_props: {
  //     name: 'rate_picker',
  //     count: 10
  //   },
  //   required: true,
  // }
  ];
  // 生成自定义组件
  createComponentType(mockData.value)
})

const sign = ref(null);
const rate_picker = ref(null);

const onSubmit = (values) => {
  // 合并自定义字段到提交表单字段
  postData.value = _.assign(postData.value, values);
  // console.warn(mockData.value);
  // 检查非表单输入项
  if (validOther()) { // 通过验证
    console.warn(postData.value);
    console.warn('通过验证');
  } else {
    console.warn('不通过验证');
  }
};

const onActive = (item) => {
  // 返回自定义字段
  if (item.key === 'sign') {
    postData.value['sign'] = item.value
  }
  if (item.key === 'rate') {
    postData.value['rate'] = item.value
  }
}

const validOther = () => {
  // 检验没有绑定name的输入项
  let flag = true;
  if (sign.value) { // 检验电子签名
    flag = sign.value[0].validSign();
  }
  if (rate_picker.value) { // 检验评分
    flag = rate_picker.value[0].validRate();
  }
  return flag;
}
</script>

<style lang="less" scoped>
  .table-title {
    padding: 1rem;
  }
  .table-box {
    padding: 1rem;
  }
</style>