欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue3+Element?Plus動態(tài)表單實現(xiàn)

 更新時間:2025年05月15日 08:41:15   作者:滿  
本文主要介紹了Vue3+Element?Plus動態(tài)表單實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

 完整代碼

<template>
  <div class="dynamic-form-container">
    <el-form
      ref="dynamicFormRef"
      :model="formData"
      :rules="formRules"
      label-width="auto"
      label-position="top"
      v-loading="loading"
    >
      <!-- 動態(tài)渲染表單字段 -->
      <template v-for="field in formConfig" :key="field.name">
        <!-- 輸入框 -->
        <el-form-item
          v-if="field.type === 'input'"
          :label="field.label"
          :prop="field.name"
          :rules="generateFieldRules(field)"
        >
          <el-input
            v-model="formData[field.name]"
            :placeholder="field.placeholder || `請輸入${field.label}`"
            :type="field.inputType || 'text'"
            :clearable="field.clearable !== false"
          />
        </el-form-item>

        <!-- 下拉選擇 -->
        <el-form-item
          v-else-if="field.type === 'select'"
          :label="field.label"
          :prop="field.name"
          :rules="generateFieldRules(field)"
        >
          <el-select
            v-model="formData[field.name]"
            :placeholder="field.placeholder || `請選擇${field.label}`"
            :clearable="field.clearable !== false"
            style="width: 100%"
          >
            <el-option
              v-for="option in field.options"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            />
          </el-select>
        </el-form-item>

        <!-- 單選框 -->
        <el-form-item
          v-else-if="field.type === 'radio'"
          :label="field.label"
          :prop="field.name"
          :rules="generateFieldRules(field)"
        >
          <el-radio-group v-model="formData[field.name]">
            <el-radio
              v-for="option in field.options"
              :key="option.value"
              :label="option.value"
            >
              {{ option.label }}
            </el-radio>
          </el-radio-group>
        </el-form-item>

        <!-- 復(fù)選框 -->
        <el-form-item
          v-else-if="field.type === 'checkbox'"
          :label="field.label"
          :prop="field.name"
          :rules="generateFieldRules(field)"
        >
          <el-checkbox-group v-model="formData[field.name]">
            <el-checkbox
              v-for="option in field.options"
              :key="option.value"
              :label="option.value"
            >
              {{ option.label }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>

        <!-- 日期選擇器 -->
        <el-form-item
          v-else-if="field.type === 'date'"
          :label="field.label"
          :prop="field.name"
          :rules="generateFieldRules(field)"
        >
          <el-date-picker
            v-model="formData[field.name]"
            :type="field.dateType || 'date'"
            :placeholder="field.placeholder || `請選擇${field.label}`"
            style="width: 100%"
          />
        </el-form-item>

        <!-- 開關(guān) -->
        <el-form-item
          v-else-if="field.type === 'switch'"
          :label="field.label"
          :prop="field.name"
        >
          <el-switch v-model="formData[field.name]" />
        </el-form-item>

        <!-- 自定義插槽 -->
        <el-form-item
          v-else-if="field.type === 'slot'"
          :label="field.label"
          :prop="field.name"
          :rules="generateFieldRules(field)"
        >
          <slot :name="field.slotName" :field="field" :model="formData" />
        </el-form-item>
      </template>

      <el-form-item>
        <el-button type="primary" @click="submitForm">提交</el-button>
        <el-button @click="resetForm">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'

// 表單引用
const dynamicFormRef = ref()

// 加載狀態(tài)
const loading = ref(false)

// 表單數(shù)據(jù)
const formData = ref({})

// 表單驗證規(guī)則
const formRules = ref({})

// 表單配置(從后端獲?。?
const formConfig = ref([
  // 默認(rèn)配置,實際會被后端數(shù)據(jù)覆蓋
  {
    name: 'username',
    label: '用戶名',
    type: 'input',
    required: true,
    placeholder: '請輸入用戶名'
  }
])

// 模擬從后端獲取表單配置
const fetchFormConfig = async () => {
  try {
    loading.value = true
    
    // 這里替換為實際的API調(diào)用
    const response = await mockApiGetFormConfig()
    
    formConfig.value = response.data.fields
    
    // 初始化表單數(shù)據(jù)
    initFormData()
    
    // 生成驗證規(guī)則
    generateFormRules()
  } catch (error) {
    ElMessage.error('獲取表單配置失敗: ' + error.message)
  } finally {
    loading.value = false
  }
}

// 初始化表單數(shù)據(jù)
const initFormData = () => {
  const data = {}
  formConfig.value.forEach(field => {
    // 根據(jù)字段類型設(shè)置默認(rèn)值
    switch (field.type) {
      case 'checkbox':
        data[field.name] = field.defaultValue || []
        break
      case 'switch':
        data[field.name] = field.defaultValue || false
        break
      default:
        data[field.name] = field.defaultValue || ''
    }
  })
  formData.value = data
}

// 生成表單驗證規(guī)則
const generateFormRules = () => {
  const rules = {}
  formConfig.value.forEach(field => {
    if (field.required || field.rules) {
      rules[field.name] = generateFieldRules(field)
    }
  })
  formRules.value = rules
}

// 生成單個字段的驗證規(guī)則
const generateFieldRules = (field) => {
  const rules = []
  
  // 必填規(guī)則
  if (field.required) {
    rules.push({
      required: true,
      message: field.message || `${field.label}不能為空`,
      trigger: field.trigger || 'blur'
    })
  }
  
  // 自定義規(guī)則
  if (field.rules && Array.isArray(field.rules)) {
    rules.push(...field.rules)
  }
  
  // 類型校驗
  if (field.type === 'input' && field.inputType === 'email') {
    rules.push({
      type: 'email',
      message: '請輸入正確的郵箱格式',
      trigger: ['blur', 'change']
    })
  }
  
  return rules
}

// 提交表單
const submitForm = async () => {
  try {
    // 表單驗證
    await dynamicFormRef.value.validate()
    
    // 這里替換為實際的提交API
    const response = await mockApiSubmitForm(formData.value)
    
    ElMessage.success('提交成功')
    console.log('表單數(shù)據(jù):', formData.value)
    console.log('服務(wù)器響應(yīng):', response)
    
    // 可以在這里處理提交成功后的邏輯
  } catch (error) {
    if (error instanceof Error) {
      ElMessage.error('表單驗證失敗: ' + error.message)
    }
  }
}

// 重置表單
const resetForm = () => {
  dynamicFormRef.value.resetFields()
}

// 模擬API獲取表單配置
const mockApiGetFormConfig = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        data: {
          fields: [
            {
              name: 'username',
              label: '用戶名',
              type: 'input',
              required: true,
              placeholder: '請輸入用戶名',
              maxlength: 20
            },
            {
              name: 'password',
              label: '密碼',
              type: 'input',
              inputType: 'password',
              required: true,
              placeholder: '請輸入密碼',
              rules: [
                { min: 6, max: 18, message: '密碼長度在6到18個字符', trigger: 'blur' }
              ]
            },
            {
              name: 'gender',
              label: '性別',
              type: 'select',
              required: true,
              options: [
                { label: '男', value: 'male' },
                { label: '女', value: 'female' },
                { label: '其他', value: 'other' }
              ]
            },
            {
              name: 'hobbies',
              label: '興趣愛好',
              type: 'checkbox',
              options: [
                { label: '游泳', value: 'swimming' },
                { label: '跑步', value: 'running' },
                { label: '閱讀', value: 'reading' }
              ]
            },
            {
              name: 'subscribe',
              label: '訂閱通知',
              type: 'switch',
              defaultValue: true
            },
            {
              name: 'birthday',
              label: '出生日期',
              type: 'date',
              dateType: 'date',
              required: true
            }
          ]
        }
      })
    }, 800)
  })
}

// 模擬API提交表單
const mockApiSubmitForm = (data) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ code: 200, message: 'success', data })
    }, 500)
  })
}

// 組件掛載時獲取表單配置
onMounted(() => {
  fetchFormConfig()
})
</script>

<style scoped>
.dynamic-form-container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}
</style>

后端API數(shù)據(jù)結(jié)構(gòu)建議

后端API返回的表單配置建議采用如下JSON格式:

{
  "code": 200,
  "message": "success",
  "data": {
    "fields": [
      {
        "name": "username",
        "label": "用戶名",
        "type": "input",
        "required": true,
        "placeholder": "請輸入用戶名",
        "inputType": "text",
        "maxlength": 20,
        "rules": [
          {
            "pattern": "^[a-zA-Z0-9_]+$",
            "message": "只能包含字母、數(shù)字和下劃線"
          }
        ]
      },
      {
        "name": "gender",
        "label": "性別",
        "type": "select",
        "required": true,
        "options": [
          {
            "label": "男",
            "value": "male"
          },
          {
            "label": "女",
            "value": "female"
          }
        ]
      },
      {
        "name": "subscribe",
        "label": "訂閱通知",
        "type": "switch",
        "defaultValue": true
      }
    ]
  }
}

到此這篇關(guān)于Vue3+Element Plus動態(tài)表單實現(xiàn)的文章就介紹到這了,更多相關(guān)Vue3 Element Plus動態(tài)表單內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue.js實戰(zhàn)之組件的進階

    Vue.js實戰(zhàn)之組件的進階

    組件(Component)是 Vue.js 最強大的功能之一,之前的文章都只是用到了基本的封裝功能,這次將介紹一些更強大的擴展。這篇文章主要介紹了Vue.js實戰(zhàn)之組件進階的相關(guān)資料,需要的朋友們可以參考借鑒,下面來一起看看吧。
    2017-04-04
  • Vue程序化的事件監(jiān)聽器(實例方案詳解)

    Vue程序化的事件監(jiān)聽器(實例方案詳解)

    本文通過兩種方案給大家介紹了Vue程序化的事件監(jiān)聽器,每種方案通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2020-01-01
  • Vue3為什么這么快

    Vue3為什么這么快

    這篇文章主要介紹了Vue3為什么這么快,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Vue.js實現(xiàn)大轉(zhuǎn)盤抽獎總結(jié)及實現(xiàn)思路

    Vue.js實現(xiàn)大轉(zhuǎn)盤抽獎總結(jié)及實現(xiàn)思路

    這篇文章主要介紹了 Vue.js實現(xiàn)大轉(zhuǎn)盤抽獎總結(jié)及實現(xiàn)思路,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-10-10
  • 解決Vue中引入swiper,在數(shù)據(jù)渲染的時候,發(fā)生不滑動的問題

    解決Vue中引入swiper,在數(shù)據(jù)渲染的時候,發(fā)生不滑動的問題

    今天小編就為大家分享一篇解決Vue中引入swiper,在數(shù)據(jù)渲染的時候,發(fā)生不滑動的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • 淺析vue中的nextTick

    淺析vue中的nextTick

    這篇文章主要介紹了vue中nextTick的相關(guān)資料,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下
    2020-12-12
  • 詳解vue中axios請求的封裝

    詳解vue中axios請求的封裝

    這篇文章主要介紹了vue中axios請求的封裝,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • vue-router的hooks用法詳解

    vue-router的hooks用法詳解

    這篇文章主要介紹了vue-router的hooks用法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • 詳解webpack編譯多頁面vue項目的配置問題

    詳解webpack編譯多頁面vue項目的配置問題

    本篇文章主要介紹了詳解webpack編譯多頁面vue項目的配置問題,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • Vue 滾動行為的具體使用方法

    Vue 滾動行為的具體使用方法

    本篇文章主要介紹了Vue 滾動行為的具體使用方法。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09

最新評論