使用 vue-form-watchers 简化 Vue 3 表单管理

您是否曾在 Vue 中为表单字段编写重复的观察器代码?或者为防止 API 垃圾信息而苦苦挣扎,无法对表单更新进行反跳?今天,我将向您介绍 `vue-form-watchers`,这是一款轻量级实用程序,可让您轻松管理 Vue 3 中的表单状态。

问题

在典型的 Vue 应用程序中,管理表单状态通常涉及:

  • 为每个表单字段设置单独的观察者
  • 实施去抖动以防止过多的 API 调用
  • 处理程序更新而不触发观察者
  • 添加新的表单字段及其相应的观察者
  • 这导致样板代码看起来像这样:

    const form = ref({
      username: '',
      email: '',
      age: 0
    })
    
    // Individual watchers for each field
    watch(() => form.value.username, debounce((value) => {
      updateServer('username', value)
    }, 500))
    
    watch(() => form.value.email, debounce((value) => {
      updateServer('email', value)
    }, 500))
    
    watch(() => form.value.age, debounce((value) => {
      updateServer('age', value)
    }, 500))

    输入 vue-form-watchers

    `vue-form-watchers` 通过提供一种简单的声明式方法来处理表单状态变化,解决了这些问题。以下是如何开始:

    npm install vue-form-watchers

    基本用法

    import { ref } from 'vue'
    import { createFormWatchers } from 'vue-form-watchers'
    
    const form = ref({
      username: '',
      email: '',
      age: 0
    })
    
    const { destroy } = createFormWatchers(
      form.value,
      (key, value, source) => {
        console.log(`${key} changed to ${value} from ${source}`)
        // Handle updates (API calls, validation, etc.)
      },
      {
        debounceTime: 300 // Optional: default is 500ms
      }
    )
    // Clean up on component unmount
    onUnmounted(() => destroy())

    就是这样!该库会自动为所有表单字段创建防抖观察器。

    真实世界的例子

    1. 自动保存草稿帖子

    下面说明了如何为博客编辑器实现自动保存草稿系统:

    import { ref } from 'vue'
    import { createFormWatchers } from 'vue-form-watchers'
    
    export default {
      setup() {
        const draft = ref({
          title: '',
          content: '',
          tags: []
        })
    
        const { markUpdateAsExternal } = createFormWatchers(
          draft.value,
          async (key, value) => {
            try {
              await api.saveDraft({ [key]: value })
              toast.success('Draft saved')
            } catch (error) {
              toast.error('Failed to save draft')
            }
          },
          {
            debounceTime: 1000 // Wait for 1 second of inactivity
          }
        )
    
        // Load existing draft
        const loadDraft = async () => {
          const savedDraft = await api.getDraft()
          markUpdateAsExternal(() => {
            Object.assign(draft.value, savedDraft)
          })
        }
        onUnmounted(() => destroy())
    
        return { draft, loadDraft }
      }
    }

    2.实时表单验证

    以下是如何实现带有错误消息的实时验证:

    import { ref } from 'vue'
    import { createFormWatchers } from 'vue-form-watchers'
    
    export default {
      setup() {
        const form = ref({
          email: '',
          password: '',
          confirmPassword: ''
        })
    
        const errors = ref({})
    
        const { markUpdateAsExternal, destroy } = createFormWatchers(
          form.value,
          async (key, value) => {
            errors.value[key] = await validateField(key, value, form.value)
          },
          {
            debounceTime: 300,
            immediate: true // Validate fields immediately
          }
        )
    
        async function validateField(key, value, formData) {
          switch (key) {
            case 'email':
              return !value.includes('@') ? 'Invalid email' : null
            case 'password':
              return value.length < 8 ? 'Password too short' : null
            case 'confirmPassword':
              return value !== formData.password ? 'Passwords do not match' : null
          }
        }
    
        onUnmounted(() => destroy())
        return { form, errors }
      }
    }

    3. 带有 API 更新的多步骤表单

    对于跨越多个步骤的复杂表单:

    import { ref } from 'vue'
    import { createFormWatchers } from 'vue-form-watchers'
    
    export default {
      setup() {
        const userForm = ref({
          // Step 1: Basic Info
          firstName: '',
          lastName: '',
          email: '',
    
          // Step 2: Address
          street: '',
          city: '',
          country: '',
    
          // Step 3: Preferences
          notifications: false,
          theme: 'light'
        })
    
        const { markUpdateAsExternal } = createFormWatchers(
          userForm.value,
          async (key, value, source) => {
            if (source === 'user') {
              await api.updateUserProfile({ [key]: value })
            }
          },
          {
            skipExternalUpdates: true,
            isExternalUpdate: (key, newValue, oldValue) => {
              // Custom logic to determine external updates
              return false
            }
          }
        )
    
        return { userForm }
      }
    }

    高级功能

    1. 自定义外部更新检测

    定义您自己的识别外部更新的逻辑:

    createFormWatchers(form.value, updateCallback, {
      isExternalUpdate: (key, newValue, oldValue) => {
        return newValue === oldValue || key.startsWith('_')
      }
    })

    2. 排除领域

    跳过触发更新的特定字段:

    createFormWatchers(form.value, updateCallback, {
      exclude: ['tempField', 'localOnly']
    })

    3.调试模式

    在开发过程中启用调试模式以获取详细日志:

    createFormWatchers(form.value, updateCallback, {
      debug: process.env.NODE_ENV === 'development'
    })

    为什么要使用 vue-form-watchers?

  • 零依赖:除 Vue 3 外,该包没有外部依赖
  • TypeScript 支持:通过类型定义完全支持 TypeScript
  • 自动属性检测:自动处理添加到表单的新属性
  • 性能:内置防抖功能可防止过度更新
  • 捆绑包大小小:重量轻,针对生产进行了优化
  • 结论

    “vue-form-watchers” 提供简洁、声明式的 API 来处理表单更新,从而简化了 Vue 3 应用程序中的表单状态管理。它消除了样板代码,同时添加了防抖和外部更新处理等强大功能。

    无论您构建的是简单的联系表单还是复杂的多步骤向导,此实用程序都可以帮助您编写更清晰、更易于维护的代码。

    立即开始使用

    该库是开源的,可在 GitHub 上获取。如果您发现它有用,请考虑在 GitHub 上给它一个 ⭐️ 星 - 它可以帮助其他开发人员发现该软件包并激励进一步开发。

    在您的下一个 Vue 项目中尝试一下,然后让我知道它对您有何帮助!

    祝你编码愉快!🚀

    GitHub。