Vuelidate : بازنگری اعتبار سنجی‌ها در Vue.js

Vuelidate : بازنگری اعتبار سنجی‌ها در Vue.js
آفلاین
user-avatar
عرفان حشمتی
20 اسفند 1399, خواندن در 6 دقیقه

در حال حاضر کتابخانه‌های اعتبارسنجی خوبی برای Vue.js مانند vue-validator یا vee-validate اختصاص داده شده است.

این دو کتابخانه کاملا مشابه هم کار کرده و شما را ملزم به نوشتن قوانین درون تمپلیت می‌کنند. این چیزی است که شما در واقع برای برنامه خود نیاز دارید. بیایید نگاهی به این مثال vee-validate بیندازیم:

<input v-model="email" v-validate data-rules="required|email" :class="{'input': true, 'is-danger': errors.has('email') }" type="text" placeholder="Email">

مشکل

اگر بیشتر روی یک برنامه داده محور کار می‌کنید، متوجه می‌شوید که چیزی بیش از ورودی‌های خود را اعتبارسنجی می‌کنید. سپس باید رویکرد فوق را با روش‌های اعتبارسنجی یا مقادیر محاسبه شده سفارشی ترکیب کنید. این مسئله نویز اضافی را هم در الگوها و هم در کد وارد می‌کند. من معتقدم که الگوها بهترین مکان برای اعلام منطق برنامه نیستند.

وقتی می‌خواهید مجموعه‌ها یا مقادیر ترکیبی از منابع مختلف مانند Vuex getterها، ورودی‌های کاربر و مقادیر محاسبه شده را تأیید کنید، این مورد بیشتر نمایان می‌شود. یا وقتی قوانین اعتبارسنجی شما به نتایج اعتبارسنجی دیگر و ... بستگی دارد.

معرفی Vuelidate

آنچه من شخصا در مورد Vue.js دوست دارم این است که کد شما را به خوبی ساختاردهی می‌کند: داده‌ها، متدها، مقادیر محاسبه شده، Vuex، مسیریابی؛ همه چیز جای خود را دارد. پس چرا برای اعتبارسنجی یکی ایجاد نکنیم؟

برای رفع این نیاز، ما یک vuelidate ایجاد کرده‌ایم. روش دیگری برای مقابله با اعتبارسنجی داده‌ها در Vue.js.

اعتبارسنجی‌های فراتر از فرم

بزرگترین تفاوتی که در Vuelidate مشاهده خواهید کرد این است که اعتبارسنجی‌ها کاملا از تمپلیت جدا شده‌اند. این بدان معنی است که شما به جای تهیه قوانینی برای ورودی‌های مختلف در داخل یک تمپلیت، آن قوانین را برای مدل داده خود تعریف می‌کنید. این شبیه نحوه کار Ember است.

همچنین برای Vuex (یک الگوی مدیریت state + کتابخانه‌ای برای برنامه‌های Vue.js)، شی مسیریابی و مقادیر محاسبه شده کار می‌کند. از این رو می‌توانید به خاطر انجام این کار حتی موضوع را عمیق‌تر بررسی کرده و نتایج اعتبارسنجی‌های دیگر را تأیید کنید.

مثال فوق را می‌توان به صورت زیر بازسازی کرد:

import Vue from 'vue'
import Validations from 'vuelidate'
import { email, required } from 'vuelidate/lib/validators'

Vue.use(Validations)

new Vue({
  el: '#app',
  data () {
    return {
      email: '',
    }
  },
  validations: {
    email: { required, email } // rules object
    }
}
<input v-model="email" :class="{'input': true, 'is-danger': $v.email.$invalid }" type="text" placeholder="Email">

شی نتایج اعتبارسنجی در this.$v موجود است. برای مثال فوق اینگونه به نظر می‌رسد:

$v: {
    email: {
      $dirty: false,
      $error: false,
      $invalid: true,
      required: false,
    email: false
    },
    $dirty: false,
    $error: false,
    $invalid: true,
}

مطمئنا در ابتدا ممکن است همه چیز کمی واضح به نظر برسد و به زیبایی افزودن قوانین داخل الگو نباشد. با این حال زمانی که به چیز پیچیده‌تری نیاز داشته باشید، احتمالا عاشق این روش خواهید شد.

اعتبارسنج‌های سفارشی

ارائه اعتبارسنج‌های سفارشی خود به آسانی انتقال تابع به شی قوانین است. آیا می‌خواهید از کوئری‌های Moment.js مانند isBefore یا isAfter استفاده کنید؟ مشکلی نیست، به همین راحتی می‌توانید:

validations: {
  startDate: {
    // given date is a moment object
    isBefore (date) { return date.isBefore(this.endDate) }
  },
  endDate: {
    isAfter (date) { return date.isAfter(this.startDate) }
  }
}

از lodash و متدهای ترکیب تابع آن مثل _.pipe و _.compose لذت می‌برید؟ ما آنها را پوشش داده‌ایم.

به این مثال نگاه کنید، جایی که ما یک رشته را به شی moment وارد کرده و سپس آن را اعتبارسنجی می‌کنیم.

validations: {
  startDate: {
    isBefore (date) {
        return _.pipe(
          moment, // coerce to a moment object
          momentDate => momentDate.isBefore(this.endDate) // validate it!
        )(date)
    }
  }
}

به راحتی می‌توانید شرایط بسیار پیچیده‌تری مانند مقایسه محدوده تاریخ با استفاده از moment-range یا ساخت اعتبارسنج‌های پویا را کنترل کنید.

چگونه از Vuelidate استفاده کنیم؟

از آنجا که ما هیچ اعتبارسنجی را درون هسته اصلی قرار نمی‌دهیم، پکیج نرم‌افزاری در مقایسه با سایر افزونه‌های اعتبارسنجی بسیار کوچکتر است. البته ما از برخی اعتبارسنج‌های آماده نیز استفاده می‌کنیم، اما آنها به عنوان فایل‌های جداگانه ذخیره می‌شوند.

اعتبارسنج‌ها و راهنماهای موجود در حال حاضر شامل موارد زیر است:

  • alpha
  • alphaNum
  • and
  • between
  • maxLength
  • minLength
  • or
  • required
  • sameAs

این لیست گسترش خواهد یافت، زیرا واقعا روی اندازه اعتبارسنج تأثیر نمی گذارد. در این صورت شما فقط می‌توانید از مواردی که واقعا نیاز دارید استفاده کنید.

اکنون می‌توانید آنها را به این صورت وارد کنید:

import require from 'vuelidate/lib/validators/require'
import between from 'vuelidate/lib/validators/between'

یا آنها را از فایل validators / index.js وارد کنید.

import { require, between } from 'vuelidate/lib/validators'

با تشکر از tree-shaking در Rollup.js یا Webpack 2، هر دو مورد بالا به یک اندازه بسته نرم‌افزاری یکسان منجر می‌شوند.

با فرض اینکه از یکی از پکیج‌های ماژول فوق استفاده می‌کنید (و من فکر می‌کنم باید این کار را انجام دهید)، اگر واقعا می‌خواهید اندازه فایل بسته نرم‌افزاری اولیه را کاهش دهید، حتی نیازی به نصب پلاگین ندارید.

بنابراین به جای:

// main.js
import Vue from 'vue'
import Validations from 'vuelidate'

Vue.use(Validations)

شما فقط می‌توانید قابلیت اعتبارسنجی را با کامپوننت‌هایی که در واقع از آن استفاده می‌کنند، ترکیب کنید.

// formView.vue
import { validationsMixin } from 'vuelidate'

export default {
  mixins: [validationsMixin]
}

احتمالا قبلا در مورد قابلیت استفاده مجدد حدس‌هایی زده‌اید. درست مانند خود پلاگین، قوانین اعتبارسنجی را می‌توان به mixinها منتقل کرد و در قسمت‌های مختلف برنامه به اشتراک گذاشت. یا فقط در داخل یک شی ذخیره کرد تا در صورت لزوم ایمپورت شود. یا با closureها آنها را ساخت. فقط اطمینان حاصل کنید که تابع اعتبارسنج با عبور مقدار درست Truthy و درصورت مقدار غلط falsy را برمی‌گرداند.

برای سهولت کار، مطمئن می‌شویم که هر نقش را با کامپوننت this، مشابه نحوه کار متدها و مقادیر محاسبه شده Vue فراخوانی می‌کنیم.

گروه‌ها و مجموعه‌های اعتبارسنجی

هنگام استفاده از فرم‌های بزرگتر یا پیچیده‌تر، مناسب است که اعتبارسنجی را درون گروه‌ها قرار دهید.

کد آن می‌تواند به صورت زیر باشد:

validations: {
  name: { alpha },
  email: { required, email }
  users: {
    minLength: minLength(2)
  },
  tags: {
    maxLength: maxLength(5)
  },
  formA: ['name', 'email'],
  formB: ['users', 'tags']
}

همین!

شی اعتبارسنجی برای گروه $v.fromA به این شکل است:

 formA: {
  $dirty: false,
  $error: false,
  $invalid: true,
  name: {
    $dirty: false,
    $error: false,
    $invalid: true,
    minLength: false
  },
  name: {
    $dirty: false,
    $error: false,
    $invalid: true,
    required: false,
    email: false
  }
}

همانطور که قبلا اشاره شد، ما همچنین از مجموعه‌ها (آرایه‌ها و اشیا) پشتیبانی می‌کنیم. برای این منظور یک کلید ویژه $each معرفی کردیم که به شما امکان می‌دهد تا اعتبارسنج‌ها را برای هر عنصر / کلید تعریف کنید.

نگاهی به این مثال بیندازید:

validations: {
  users: {
    minLength: minLength(1), // the users array must include at least 1 user
    $each: {
      email: { // Each user must have their email field set correctly
        required,
        email
      }
    }
  }
}

بازگشت به فرم ورودی‌ها

جالب است، اما در مورد شاخص‌های فرم مفید مانند $dirty چه کار کنیم؟

این سوال خوبی است.

از آنجا که ما تصمیم گرفتیم از هیچ دستورالعمل سفارشی استفاده نکنیم (حداقل موقتا)، در واقع شما مجبورید این کار را خودتان انجام دهید. عمدتا به این دلیل که برخی از توابع مفید برای انجام این کار را expose می‌کنیم.

<input
  v-model="email"
  :class="{'input': true, 'is-danger': $v.email.$error }"
  @change="$v.email.$touch()"
  type="text"
  placeholder="Email">

به نظر نمی‌رسد مانند سایر اعتبارسنج‌ها کار قشنگی باشد، اما من معتقدم این هزینه‌ای است که باید برای کنترلی که به دست می‌آوریم، پرداخت کنیم. از طرف دیگر، اگر از Vuex استفاده می‌کنید، بهره‌گیری از موارد فوق در متد به روزرسانی کار ساده‌ای است.

<input
  :value="email"
  :class="{'input': true, 'is-danger': $v.email.$error }"
  @change="update('email', $event)"
  type="text"
  placeholder="Email">
methods: {
  update (field, e) {
    this.$v[field].$touch()
    dispatch('updateField', field, e.target.value.trim())
  }
}

بسته به آنچه در واقع به آن نیاز دارید و بسته به زمانی که متد $touch() را فعال می‌کنید، پرچم $dirty می‌تواند به عنوان معادل touched و dirty استفاده شود.

برای تنظیم مجدد اعتبارسنجی پرچم، متد $reset() را فراخوانی کنید:

this.$v.$reset()
// or for a specific value
this.$v.email.$reset()

هر دوی $touch() و $reset() از ساختار شی عبور می‌کنند. این بدان معنی است که اگر یک گروه یا یک مدل تو در تو را $reset() کنید، به طور خودکار پرچم $dirty را در هر یک از اعضای گروه پاک می‌کند، اما برعکس آن صدق نمی‌کند. برای متد $touch() نیز به همین صورت است.

جمع بندی

امیدوارم این مقاله درک بهتری از رویکردی که ما با Vuelidate در پیش گرفته‌ایم به شما بدهد. اگر به اطلاعات بیشتری نیاز دارید، مستندات مربوط به نمونه کدهای بیشتر و یک راهنمای شروع کار را بررسی کنید.

منبع

چه امتیازی به این مقاله می دید؟
خیلی بد
بد
متوسط
خوب
عالی

دیدگاه‌ها و پرسش‌ها

برای ارسال دیدگاه لازم است، ابتدا وارد سایت شوید.

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

آفلاین
user-avatar
عرفان حشمتی @heshmati74
مهندس معماری سیستم های کامپیوتری، برنامه نویس و طراح وب سایت
دنبال کردن

گفتگو‌ برنامه نویسان

بخشی برای حل مشکلات برنامه‌نویسی و مباحث پیرامون آن وارد شو