Przeglądaj źródła

表单组件封装

lifanagju_citu 1 rok temu
rodzic
commit
6ed24264ad

+ 0 - 331
src/components/CtForm/index copy.vue

@@ -1,331 +0,0 @@
-<template>
-  <v-form ref="form" v-model="valid" class="login-form" @submit.prevent>
-    <div>
-      <v-row dense no-gutters class="justify-space-between">
-        <template v-for="(item, index) in props.items.options">
-          <slot :name="item.prevSlot"></slot>
-          <v-col :key="item.key" v-if="!item.hide" :cols="item.col || '12'" class="position">
-            <template v-if="item.slotTitle">
-              <div :class="item.class" :style="item.slotTitleStyle">{{ item.slotTitle }}</div>
-            </template>
-            <div class="d-flex" :class="item.flexStyle || 'flex-row'">
-              <v-text-field
-                v-if="['text', 'password', 'number'].includes(item.type)"
-                :type="item.type"
-                v-model="item.value"
-                :rules="item.rules"
-                :disabled="item.disabled"
-                :density="item.dense || 'compact'"
-                :color="item.color"
-                :label="item.label"
-                :placeholder="item.placeholder || item.label"
-                variant="outlined"
-                :width="item.width"
-                :autofocus="item.autofocus"
-                :class="item.class"
-                :suffix="item.suffix"
-                :append-inner-icon="item.appendIcon"
-                :clearable="item.clearable"
-                :readonly="item.readonly"
-                :prepend-inner-icon="item.prependInnerIcon"
-                hide-spin-buttons
-                @wheel="$event => handleWheel($event, item)"
-                @keyup.enter="item.keyupEnterNative && item.keyupEnterNative(index)"
-                @click="item.click && item.click(index)"
-                @click:append-inner="item.clickAppendInner"
-                @change="handleChange(item)"
-              />
-              <v-autocomplete
-                v-if="item.type === 'autocomplete'"
-                :rules="item.rules"
-                v-model="item.value"
-                :attach="!item.noAttach"
-                :loading="item.loading"
-                :label="item.label"
-                :placeholder="item.placeholder || item.label"
-                :items="item.items"
-                :item-text="item.itemText || 'label'"
-                :item-value="item.itemValue || 'value'"
-                variant="outlined"
-                :density="item.dense || 'compact'"
-                :disabled="item.disabled"
-                :multiple="item.multiple"
-                :clearable="item.clearable"
-                :search="item.searchInput"
-                :hide-no-data="item.hideNoData"
-                :no-data-text="item.noDataText || 'No data available'"
-                :hide-selected="item.hideSelected"
-                @change="handleChange(item)"
-              >
-                <template v-if="item.slotAppendItem" v-slot:append-item>
-                  <slot :name="item.slotAppendItem" :item="item"></slot>
-                </template>
-                <template v-if="item.prependItem" #prepend-item>
-                  <slot :name="item.prependItem" :item="item"></slot>
-                </template>
-              </v-autocomplete>
-              <!-- autocomplete2 多选纸片样式 -->
-              <v-autocomplete
-                v-if="item.type === 'autocomplete2'"
-                v-model="item.value"
-                :rules="item.rules"
-                :attach="!item.noAttach"
-                :loading="item.loading"
-                :label="item.label"
-                :placeholder="item.placeholder || item.label"
-                :items="item.canCreate ? [inputUpdateValue, ...item.items].filter(Boolean) : item.items"
-                :item-text="item.itemText || 'label'"
-                :item-value="item.itemValue || 'value'"
-                variant="outlined"
-                :density="item.dense || 'compact'"
-                :multiple="item.multiple"
-                :clearable="item.clearable"
-                :search-input="item.searchInput"
-                :hide-no-data="item.hideNoData"
-                :hide-selected="item.hideSelected"
-                :readonly="item.readonly"
-                @change="handleChange(item)"
-                @update:search-input="$event => item.canCreate ? inputUpdateValue = $event : inputUpdateAutocomplete($event)"
-                :hide-details="!item.showDetails"
-                deletable-chips
-                cache-items
-                small-chips
-              ></v-autocomplete>
-              <v-combobox
-                v-if="item.type === 'combobox'"
-                :rules="item.rules"
-                v-model="item.value"
-                :attach="true"
-                :label="item.label"
-                :placeholder="item.placeholder || item.label"
-                :items="item.items"
-                :item-text="item.itemText || 'label'"
-                :item-value="item.itemValue || 'value'"
-                variant="outlined"
-                :density="item.dense || 'compact'"
-                :clearable="item.clearable"
-                :disabled="item.disabled"
-                @change="handleChange(item)"
-              >
-                <template v-if="item.hasIcon" v-slot:selection="data">
-                  <v-icon color="blue darken-2">{{ data.item.label }}</v-icon>
-                </template>
-                <!-- <template v-if="item.hasIcon" v-slot:item="data">
-                  <v-list-item-avatar>
-                    <v-icon>{{ data.item.label }}</v-icon>
-                  </v-list-item-avatar>
-                  <v-list-item-content>
-                    {{ data.item.label }}
-                  </v-list-item-content>
-                </template> -->
-              </v-combobox>
-              <v-textarea
-                v-if="item.type === 'textarea'"
-                :rules="item.rules"
-                v-model="item.value"
-                :label="item.label"
-                :placeholder="item.placeholder || item.label"
-                :no-resize="!item.resize"
-                variant="outlined"
-                :density="item.dense || 'compact'"
-                :rows="item.rows || 3"
-                :disabled="item.disabled"
-                @change="handleChange(item)"
-              ></v-textarea>
-              <v-radio-group
-                v-if="item.type === 'ifRadio'"
-                v-model="item.value"
-                :disabled="item.disabled"
-                mandatory
-                row
-                @change="handleChange(item)"
-              >
-                <template v-slot:label>
-                  <div :style="`width: ${item.width || 120}px;`">{{ item.label }}</div>
-                </template>
-                <v-radio
-                  v-for="radio in item.items"
-                  :key="`${item.key}_radio_${radio.label}`"
-                  :readonly="radio.readonly"
-                  :label="radio.label"
-                  :value="radio.value"
-                  class="mr-8"
-                ></v-radio>
-              </v-radio-group>
-              <template v-if="item.type === 'checkbox'">
-                <div style="width: 120px;" class="mt-4 label text-left">{{ item.label }}</div>
-                <div :style="item.style">
-                  <v-checkbox
-                    v-model="item.value"
-                    v-for="k in item.items"
-                    :key="k.key"
-                    :label="k.label"
-                    :color="item.color"
-                    :value="k.value"
-                    :readonly="k.readonly"
-                    hide-details
-                    :multiple="true"
-                    class="mr-3"
-                  ></v-checkbox>
-                </div>
-              </template>
-              <v-file-input
-                v-if="item.type === 'upload'"
-                :prepend-icon="item.prependIcon || ''"
-                :append-icon="item.appendIcon"
-                :append-outer-icon="item.appendOuterIcon"
-                :show-size="item.showSize"
-                variant="outlined"
-                :density="item.dense || 'compact'"
-                v-model="item.value"
-                :placeholder="item.placeholder || item.label"
-                :hint="item.hint"
-                :rules="item.rules"
-                :label="item.label"
-                :persistent-hint="item.persistentHint"
-                :loading= "item.loading"
-                :disabled="item.disabled"
-                :multiple="item.multiple"
-                :success="item.success"
-                :error="item.error"
-                :accept="item.accept || '.xlsx, .xls, .csv, .pdf, .txt, .doc'"
-                @change="handleChange(item)"
-              >
-                <template v-if="item.selfAppend" #append>
-                  <slot :name="item.selfAppend" :data="item.value"></slot>
-                </template>
-              </v-file-input>
-              <v-color-picker
-                v-if="item.type === 'colorPicker'"
-                class="mb-5"
-                v-model="item.value"
-                :elevation="item.elevation || 5"
-                :dot-size="item.dotSize || 25"
-                :show-swatches="item.showSwatches || false"
-                swatches-max-height="200"
-                :mode="item.mode || 'hexa'"
-                :hide-mode-switch="true"
-                @input="item.change"
-              />
-              <template v-if="item.type === 'switch'">
-                <span v-if="item.describe"> {{ item.describe }} </span>
-                <span class="ml-2" v-if="item.trueLabel"> {{ item.trueLabel }}</span>
-                <v-switch
-                  dense hide-details class="mt-0 ml-2 pa-0"
-                  v-model="item.value"
-                  :label="item.label"
-                  :disabled="item.disabled || false"
-                  :color="item.color || 'primary'"
-                  :true-value="(item.trueValue !== undefined) ? item.trueValue : true"
-                  :false-value="(item.falseValue !== undefined) ? item.falseValue : false"
-                ></v-switch>
-                <span v-if="item.falseLabel"> {{ item.falseLabel }} </span>
-              </template>
-              <template v-if="item.type === 'date'">
-                <div class="d-flex" style="margin-bottom: 22px;">
-                  <span class="label d-flex align-center" :style="`width: ${item.width || 120}px;`">{{ item.label }}</span>
-                  <!-- <date-picker
-                    :is-valid="isValid"
-                    :option="{ ...item.option, disabled: item.disabled }"
-                    v-model="item.value"
-                    :style="item.style"
-                    @change="item.value = $event; handleChange(item); handleCheck(item)"></date-picker> -->
-                </div>
-              </template>
-              <template v-if="item.slotName">
-                  <slot :name="item.slotName" :item="item"></slot>
-              </template>
-            </div>
-          </v-col>
-        </template>
-      </v-row>
-    </div>
-    <slot></slot>
-  </v-form>
-</template>
-
-<script setup>
-// import DatePicker from '@/components/Form/datePicker.vue'
-import { ref, defineEmits  } from 'vue'
-defineOptions({ name: 'components-ct-form' })
-const props = defineProps({items: Object})
-const inputUpdateValue = ref('')
-const form = ref()
-const valid = ref(false)
-const isValid = ref(true)
-const emit = defineEmits(['inputUpdateAutocomplete', 'change'])
-
-const handleWheel = (event, item) => {
-  if (item.type !== 'number') return
-  event.preventDefault()
-  if (event.deltaY > 0) {
-    item.value--
-  } else {
-    item.value++
-  }
-  handleChange(item)
-}
-
-const handleCheck = (e) => {
-  if (e.type !== 'date' || e.hide || !e.rules) return
-  const rules = e.rules[0]
-  const check = rules(e.value)
-  if (typeof check === 'string') {
-    e.option.error = true
-    e.option.errorMsg = check
-    return
-  }
-  e.option.error = false
-  e.option.errorMsg = null
-}
-
-const validateTime = () => {
-  isValid.value = true
-  props.items.options.forEach((e) => {
-    if (e.type !== 'date' || e.hide || !e.rules) return
-    const rules = e.rules[0]
-    const check = rules(e.value)
-    if (typeof check === 'string') {
-      isValid.value = false
-      e.option.error = true
-      e.option.errorMsg = check
-    } else {
-      e.option.error = false
-      e.option.errorMsg = null
-    }
-  })
-  return isValid.value
-}
-
-const validate = () => {
-  const form = form.value.validate()
-  const time = validateTime()
-  return form && time
-}
-
-const inputUpdateAutocomplete = (val) => {
-  emit('inputUpdateAutocomplete', val)
-}
-
-const resetValidation = () => {
-  form.value.resetValidation()
-}
-const reset = () => {
-  form.value.reset()
-}
-const handleChange = (item) => {
-  if (item.type === 'date' && item.value) item.option.validate = false
-  if (item?.change) item.change(item.value, item)
-  emit('change', false)
-}
-</script>
-
-<style lang="scss" scoped>
-.position {
-  position: relative;
-}
-.label {
-  font-size: 14px;
-  color: rgba(0, 0, 0, .6);
-}
-</style>

+ 33 - 4
src/components/CtForm/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <v-form ref="form" v-model="valid" class="login-form" @submit.prevent>
+  <v-form ref="formRef" v-model="valid" class="login-form" @submit.prevent>
     <div>
       <v-row dense no-gutters class="justify-space-between">
         <template v-for="(item) in props.items.options">
@@ -13,13 +13,13 @@
               <textUI
                 v-if="['text', 'password', 'number'].includes(item.type)"
                 v-model="item.value"
-                :items="item"
+                :item="item"
                 @change="handleChange(item)"
               ></textUI>
               <autocompleteUI
                 v-if="item.type === 'autocomplete'"
                 v-model="item.value"
-                :items="item"
+                :item="item"
                 @change="handleChange(item)"
               ></autocompleteUI>
               <template v-if="item.slotName">
@@ -36,11 +36,13 @@
 <script setup>
 defineOptions({ name:'components-ct-form'})
 import textUI from './../FormUI/TextInput'
-import autocompleteUI from './../FormUI/TextInput'
+import autocompleteUI from './../FormUI/autocomplete'
 import { ref } from 'vue'
 const emit = defineEmits(['change', 'inputUpdateAutocomplete'])// 定义一个或多个自定义事件
 const props = defineProps({items: Object})
 const valid = ref(false)
+const isValid = ref(true)
+const formRef = ref()
 
 const handleChange = (item) => {
   console.log('handleChange', item)
@@ -48,6 +50,33 @@ const handleChange = (item) => {
   if (item?.change) item.change(item.value, item)
   emit('change', false)
 }
+
+const validateTime = () => {
+  isValid.value = true
+  props.items.options.forEach((e) => {
+    if (e.type !== 'date' || e.hide || !e.rules) return
+    const rules = e.rules[0]
+    const check = rules(e.value)
+    if (typeof check === 'string') {
+      isValid.value = false
+      e.option.error = true
+      e.option.errorMsg = check
+    } else {
+      e.option.error = false
+      e.option.errorMsg = null
+    }
+  })
+}
+  
+const validate = () => {
+  console.log('点击调用子组件方法', 1)
+  const form = formRef.value.validate()
+  const time = validateTime()
+  return form && time
+}
+defineExpose({
+  validate
+})
 </script>
 <style lang="scss" scoped>
 .position {

+ 0 - 338
src/components/CtForm/list.vue

@@ -1,338 +0,0 @@
-<template>
-  <v-form ref="form" v-model="valid" class="login-form" @submit.native.prevent>
-      <div>
-          <v-row dense no-gutters class="justify-space-between">
-            <template v-for="(item, index) in items.options">
-              <slot :name="item.prevSlot"></slot>
-              <v-col :key="item.key" v-if="!item.hide" :cols="item.col || '12'" class="position">
-                <template v-if="item.slotTitle">
-                  <div :class="item.class" :style="item.slotTitleStyle">{{ item.slotTitle }}</div>
-                </template>
-                <div class="pl-2 pr-2 d-flex" :class="item.flexStyle || 'flex-row'">
-                  <v-text-field
-                      v-if="['text', 'password', 'number'].includes(item.type)"
-                      :type="item.type"
-                      v-model="item.value"
-                      :rules="item.rules"
-                      :disabled="item.disabled"
-                      :dense="item.dense"
-                      :style="{width: item.width}"
-                      :color="item.color"
-                      :label="item.label"
-                      :placeholder="item.placeholder || item.label"
-                      :outlined="item.outlined"
-                      :autofocus="item.autofocus"
-                      :required="item.required"
-                      :class="item.class"
-                      :suffix="item.suffix"
-                      :append-icon="item.appendIcon"
-                      :clearable="item.clearable"
-                      :readonly="item.readonly"
-                      :prepend-inner-icon="item.prependInnerIcon"
-                      hide-spin-buttons
-                      @wheel.native="$event => handleWheel($event, item)"
-                      @keyup.enter.native="item.keyupEnterNative && item.keyupEnterNative(index)"
-                      @click="item.click && item.click(index)"
-                      @click:append="item.clickAppend && item.clickAppend(index)"
-                      @change="handleChange(item)"
-                  />
-                  <v-autocomplete
-                      v-if="item.type === 'autocomplete'"
-                      :rules="item.rules"
-                      v-model="item.value"
-                      :attach="!item.noAttach"
-                      :loading="item.loading"
-                      :label="item.label"
-                      :placeholder="item.placeholder || item.label"
-                      :items="item.items"
-                      :item-text="item.itemText || 'label'"
-                      :item-value="item.itemValue || 'value'"
-                      :outlined="item.outlined"
-                      :dense="item.dense"
-                      :disabled="item.disabled"
-                      :multiple="item.multiple"
-                      :clearable="item.clearable"
-                      :search-input.sync="item.searchInput"
-                      :hide-no-data="item.hideNoData"
-                      :no-data-text="item.noDataText || 'No data available'"
-                      :hide-selected="item.hideSelected"
-                      @change="handleChange(item)"
-                  >
-                    <template v-if="item.slotAppendItem" v-slot:append-item>
-                      <slot :name="item.slotAppendItem" :item="item"></slot>
-                    </template>
-                    <template v-if="item.prependItem" #prepend-item>
-                      <slot :name="item.prependItem" :item="item"></slot>
-                    </template>
-                  </v-autocomplete>
-                  <!-- autocomplete2 多选纸片样式 -->
-                  <v-autocomplete
-                      v-if="item.type === 'autocomplete2'"
-                      v-model="item.value"
-                      :rules="item.rules"
-                      :attach="!item.noAttach"
-                      :loading="item.loading"
-                      :label="item.label"
-                      :placeholder="item.placeholder || item.label"
-                      :items="item.canCreate ? [inputUpdateValue, ...item.items].filter(Boolean) : item.items"
-                      :item-text="item.itemText || 'label'"
-                      :item-value="item.itemValue || 'value'"
-                      :outlined="item.outlined"
-                      :dense="item.dense"
-                      :multiple="item.multiple"
-                      :clearable="item.clearable"
-                      :search-input.sync="item.searchInput"
-                      :hide-no-data="item.hideNoData"
-                      :hide-selected="item.hideSelected"
-                      :readonly="item.readonly"
-                      @change="handleChange(item)"
-                      @update:search-input="$event => item.canCreate ? inputUpdateValue = $event : inputUpdateAutocomplete($event)"
-                      :hide-details="!item.showDetails"
-                      deletable-chips
-                      cache-items
-                      small-chips
-                    ></v-autocomplete>
-                  <v-combobox
-                      v-if="item.type === 'combobox'"
-                      :rules="item.rules"
-                      v-model="item.value"
-                      :attach="true"
-                      :label="item.label"
-                      :placeholder="item.placeholder || item.label"
-                      :items="item.items"
-                      :item-text="item.itemText || 'label'"
-                      :item-value="item.itemValue || 'value'"
-                      :outlined="item.outlined"
-                      :dense="item.dense"
-                      :clearable="item.clearable"
-                      :disabled="item.disabled"
-                      @change="handleChange(item)"
-                  >
-                    <template v-if="item.hasIcon" v-slot:selection="data">
-                      <v-icon color="blue darken-2">{{ data.item.label }}</v-icon>
-                    </template>
-                    <template v-if="item.hasIcon" v-slot:item="data">
-                      <v-list-item-avatar>
-                        <v-icon>{{ data.item.label }}</v-icon>
-                      </v-list-item-avatar>
-                      <v-list-item-content>
-                        {{ data.item.label }}
-                      </v-list-item-content>
-                    </template>
-                  </v-combobox>
-                  <v-textarea
-                    v-if="item.type === 'textarea'"
-                    :rules="item.rules"
-                    v-model="item.value"
-                    :label="item.label"
-                    :placeholder="item.placeholder || item.label"
-                    :no-resize="!item.resize"
-                    :outlined="item.outlined"
-                    :dense="item.dense"
-                    :rows="item.rows || 3"
-                    :disabled="item.disabled"
-                    @change="handleChange(item)"
-                  ></v-textarea>
-                  <v-radio-group
-                    v-if="item.type === 'ifRadio'"
-                    v-model="item.value"
-                    :disabled="item.disabled"
-                    mandatory
-                    row
-                    @change="handleChange(item)"
-                  >
-                    <template v-slot:label>
-                      <div :style="`width: ${item.width || 120}px;`">{{ item.label }}</div>
-                    </template>
-                    <v-radio
-                      v-for="radio in item.items"
-                      :key="`${item.key}_radio_${radio.label}`"
-                      :readonly="radio.readonly"
-                      :label="radio.label"
-                      :value="radio.value"
-                      class="mr-8"
-                    ></v-radio>
-                  </v-radio-group>
-                  <template v-if="item.type === 'checkbox'">
-                    <div style="width: 120px;" class="mt-4 label text-left">{{ item.label }}</div>
-                    <div :style="item.style">
-                      <v-checkbox
-                        v-model="item.value"
-                        v-for="k in item.items"
-                        :key="k.key"
-                        :label="k.label"
-                        :color="item.color"
-                        :value="k.value"
-                        :readonly="k.readonly"
-                        hide-details
-                        :multiple="true"
-                        class="mr-3"
-                      ></v-checkbox>
-                    </div>
-                  </template>
-                  <v-file-input
-                    v-if="item.type === 'upload'"
-                    :prepend-icon="item.prependIcon || ''"
-                    :append-icon="item.appendIcon"
-                    :append-outer-icon="item.appendOuterIcon"
-                    :show-size="item.showSize"
-                    :outlined="item.outlined"
-                    :dense="item.dense"
-                    v-model="item.value"
-                    :placeholder="item.placeholder || item.label"
-                    :hint="item.hint"
-                    :rules="item.rules"
-                    :label="item.label"
-                    :persistent-hint="item.persistentHint"
-                    :loading= "item.loading"
-                    :disabled="item.disabled"
-                    :multiple="item.multiple"
-                    :success="item.success"
-                    :error="item.error"
-                    :accept="item.accept || '.xlsx, .xls, .csv, .pdf, .txt, .doc'"
-                    @change="handleChange(item)"
-                  >
-                    <template v-if="item.selfAppend" #append>
-                      <slot :name="item.selfAppend" :data="item.value"></slot>
-                    </template>
-                  </v-file-input>
-                  <v-color-picker
-                    v-if="item.type === 'colorPicker'"
-                    class="mb-5"
-                    v-model="item.value"
-                    :elevation="item.elevation || 5"
-                    :dot-size="item.dotSize || 25"
-                    :show-swatches="item.showSwatches || false"
-                    swatches-max-height="200"
-                    :mode="item.mode || 'hexa'"
-                    :hide-mode-switch="true"
-                    @input="item.change"
-                  />
-                  <template v-if="item.type === 'switch'">
-                    <span v-if="item.describe"> {{ item.describe }} </span>
-                    <span class="ml-2" v-if="item.trueLabel"> {{ item.trueLabel }}</span>
-                    <v-switch
-                      dense hide-details class="mt-0 ml-2 pa-0"
-                      v-model="item.value"
-                      :label="item.label"
-                      :disabled="item.disabled || false"
-                      :color="item.color || 'primary'"
-                      :true-value="(item.trueValue !== undefined) ? item.trueValue : true"
-                      :false-value="(item.falseValue !== undefined) ? item.falseValue : false"
-                    ></v-switch>
-                    <span v-if="item.falseLabel"> {{ item.falseLabel }} </span>
-                  </template>
-                  <template v-if="item.type === 'date'">
-                    <div class="d-flex" style="margin-bottom: 22px;">
-                      <span class="label d-flex align-center" :style="`width: ${item.width || 120}px;`">{{ item.label }}</span>
-                      <date-picker
-                        :is-valid="isValid"
-                        :option="{ ...item.option, disabled: item.disabled }"
-                        v-model="item.value"
-                        :style="item.style"
-                        @change="item.value = $event; handleChange(item); handleCheck(item)"></date-picker>
-                    </div>
-                  </template>
-                  <template v-if="item.slotName">
-                      <slot :name="item.slotName" :item="item"></slot>
-                  </template>
-                </div>
-              </v-col>
-            </template>
-          </v-row>
-      </div>
-      <slot></slot>
-  </v-form>
-</template>
-
-<script>
-import DatePicker from '@/components/Form/datePicker.vue'
-export default {
-  name: 'form-list',
-  components: { DatePicker },
-  props: {
-    items: {
-      type: Object,
-      default: () => {},
-      required: true
-    }
-  },
-  data () {
-    return {
-      inputUpdateValue: '',
-      valid: false,
-      isValid: true
-    }
-  },
-  methods: {
-    handleWheel (event, item) {
-      if (item.type !== 'number') return
-      event.preventDefault()
-      if (event.deltaY > 0) {
-        item.value--
-      } else {
-        item.value++
-      }
-      this.handleChange(item)
-    },
-    handleCheck (e) {
-      if (e.type !== 'date' || e.hide || !e.rules) return
-      const rules = e.rules[0]
-      const check = rules(e.value)
-      if (typeof check === 'string') {
-        e.option.error = true
-        e.option.errorMsg = check
-        return
-      }
-      e.option.error = false
-      e.option.errorMsg = null
-    },
-    validateTime () {
-      this.isValid = true
-      this.items.options.forEach((e, index) => {
-        if (e.type !== 'date' || e.hide || !e.rules) return
-        const rules = e.rules[0]
-        const check = rules(e.value)
-        if (typeof check === 'string') {
-          this.isValid = false
-          e.option.error = true
-          e.option.errorMsg = check
-        } else {
-          e.option.error = false
-          e.option.errorMsg = null
-        }
-      })
-      return this.isValid
-    },
-    validate () {
-      const form = this.$refs.form.validate()
-      const time = this.validateTime()
-      return form && time
-    },
-    inputUpdateAutocomplete (val) {
-      this.$emit('inputUpdateAutocomplete', val)
-    },
-    resetValidation () {
-      this.$refs.form.resetValidation()
-    },
-    reset () {
-      this.$refs.form.reset()
-    },
-    handleChange (item) {
-      if (item.type === 'date' && item.value) item.option.validate = false
-      if (item?.change) item.change(item.value, item)
-      this.$emit('change', false)
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.position {
-  position: relative;
-}
-.label {
-  font-size: 14px;
-  color: rgba(0, 0, 0, .6);
-}
-</style>

+ 3 - 3
src/components/FormUI/TextInput/index.vue

@@ -31,11 +31,11 @@
 </template>
 <script setup>
 import { computed } from 'vue';
-defineOptions({ name:'v-text-field'})
+defineOptions({ name:'FormUI-v-text-field'})
 
-const props = defineProps({items: Object, modelValue: [String, Number]})
+const props = defineProps({item: Object, modelValue: [String, Number]})
 const emit = defineEmits(['update:modelValue'])
-const item = props.items
+const item = props.item
 const value = computed({
   get() { return props.modelValue },
   set(value) { emit('update:modelValue', value) }

+ 5 - 5
src/components/FormUI/autocomplete/index.vue

@@ -7,9 +7,9 @@
       :loading="item.loading"
       :label="item.label"
       :placeholder="item.placeholder || item.label"
-      :items="item.items"
-      :item-title="item.itemText || item.itemTitle || 'label'"
+      :item-title="item.itemText || 'label'"
       :item-value="item.itemValue || 'value'"
+      :items="item.items"
       variant="outlined"
       :density="item.dense || 'compact'"
       :append-to-body="true"
@@ -25,11 +25,11 @@
 </template>
 <script setup>
 import { computed } from 'vue';
-defineOptions({ name:'v-autocomplete'})
+defineOptions({ name:'FormUI-v-autocomplete'})
 
-const props = defineProps({items: Object, modelValue: String})
+const props = defineProps({item: Object, modelValue: [String, Number]})
 const emit = defineEmits(['update:modelValue'])
-const item = props.items
+const item = props.item
 const value = computed({
   get() { return props.modelValue },
   set(value) { emit('update:modelValue', value) }

+ 23 - 5
src/views/Home/personal/index copy.vue

@@ -1,6 +1,5 @@
 <template>
   <div>
-    <NavBar></NavBar>
     <div>个人用户首页</div>
     <div>测试封装start</div>
     <div class="pt-5 pl-12" style="width: 800px;">
@@ -13,13 +12,28 @@
         density="compact" 
         :rules="[v=> !!v || '请输入姓名']"
       ></v-text-field>
-      <CtForm :items="formItems"></CtForm>
+      <v-autocomplete
+        v-model="dhwdwd"
+        label="公司名称"
+        placeholder="请输入公司名称" 
+        color="#00897B" 
+        variant="outlined" 
+        density="compact" 
+        return-object
+        :items="[{value: 'Alibaba', label: '阿里巴巴', shortName: '阿里' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }]"
+        :rules="[v=> !!v || '请输入公司名称']"
+      ></v-autocomplete>
+      <v-autocomplete
+        label="Autocomplete"
+        :items="['California', 'Colorado', 'Florida', 'Georgia', 'Texas', 'Wyoming']"
+      ></v-autocomplete>
+      <CtForm ref="CtFormRef" :items="formItems"></CtForm>
     </div>
+    <div @click="handleClickValidate">点击调用子组件方法</div>
     <div>测试封装end</div>
   </div>
 </template>
 <script setup>
-import NavBar from './components/navBar.vue'
 defineOptions({ name:'personal-index'})
 
 import CtForm from '@/components/CtForm'
@@ -41,11 +55,15 @@ const formItems = ref({ options: [
     key: 'username1',
     type: 'autocomplete',
     value: '',
-    label: '请输入公司名称',
+    label: '请输入公司名称123',
     rules: [v=> !!v || '请输入公司名称'],
-    items: [{value: 'Alibaba', title: '阿里巴巴', shortName: '阿里' }, {value: 'Tencent', title: '腾讯', shortName: '腾讯' }, {value: 'Tencent', title: '腾讯', shortName: '腾讯' }, {value: 'Tencent', title: '腾讯', shortName: '腾讯' }, {value: 'Tencent', title: '腾讯', shortName: '腾讯' }, {value: 'Tencent', title: '腾讯', shortName: '腾讯' }, {value: 'Tencent', title: '腾讯', shortName: '腾讯' }, {value: 'Tencent', title: '腾讯', shortName: '腾讯' }, {value: 'Tencent', title: '腾讯', shortName: '腾讯' }, {value: 'Tencent', title: '腾讯', shortName: '腾讯' }]
+    items: [{value: 'Alibaba', label: '阿里巴巴', shortName: '阿里' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }, {value: 'Tencent', label: '腾讯', shortName: '腾讯' }]
   }
 ]})
+const CtFormRef = ref()
+const handleClickValidate = () => {
+  if (CtFormRef.value) CtFormRef.value.validate()
+}
 </script>
 <style lang="scss" scoped>