APIでは不正値が保存されないように必ずバリデーションを掛けますが、フロントは任意。
でも、あった方がユーザーが入力段階で気付けるのと、無駄なAPIリクエストを抑制できる。
フロントだけで完結できるものは追加した方が、親切&インフラに優しい。
vee-validateが使える状態になっている前提で記載します。
入力値のみでチェックする場合
サブドメイン
<template>内
<validation-provider v-slot="{ errors }" name="slack_name" rules="required|max:32|subdomain" >
<script>内
extend('subdomain', { message: '英字(小文字)・数字・ハイフンのみで入力してください。', validate (value) { return value == null || value === '' || value.match(/^[a-z0-9-]*$/) != null } })
SlackのWebhook URL
https://hooks.slack.com/services/(半角英数字)/(半角英数字)/(半角英数字)
こんな感じのなのですが、将来の変更も想定して、ある程度汎用的なLチェックにしました。
<template>内
<validation-provider v-slot="{ errors }" name="slack_webhook_url" rules="required|max:128|webhook_url" >
<script>内
extend('webhook_url', { message: '形式が正しくありません。', validate (value) { return value == null || value === '' || value.match(/^https?:\/\/[A-Za-z0-9.-]+\/[A-Za-z0-9/]+$/) != null } })
完全に汎用的にするには、記号も必要になりますが、今回は要件を絞って、ドメインは変わる事があるけど、パス複数ありで半角英数字のみとしました。
Slackのメンション
任意で、下記のいずれかを入力させます。
> !channel または !here または !subteam^ID または @メンバーID
<template>内
<validation-provider v-slot="{ errors }" name="slack_mention" rules="max:64|slack_mention" >
<script>内
extend('slack_mention', { message: '形式が正しくありません。', validate (value) { return value == null || value === '' || value.match(/^[A-Za-z0-9!^@|]*$/) != null } })
他の入力値と比較する場合
開始日・終了日
<template>内
<validation-provider v-slot="{ errors }" name="started_date" rules="required|before_started_date:ended_date" > <validation-provider v-slot="{ errors }" name="ended_date" rules="after_ended_date:started_date" >
<script>内
extend('before_started_date', { params: [{ name: 'endValue', isTarget: true }], message: '終了日よりも前の日付を入力してください。', validate (value, { endValue }) { return value == null || value === '' || endValue == null || endValue === '' || new Date(value) < new Date(endValue) } }) extend('after_ended_date', { params: [{ name: 'startValue', isTarget: true }], message: '開始日より後の日付を入力してください。', validate (value, { startValue }) { return value == null || value === '' || startValue == null || startValue === '' || new Date(startValue) < new Date(value) } })
終了日のみにすると、開始日を変更しても終了日のルールが動かない場合がるので、両方に入れました。
条件によりバリデーションをスキップしたい場合
今日より後
元の値のままの場合はOKで、変更する時のみチェックしたい場合、
<template>内(先ほどの修正)
<validation-provider v-slot="{ errors }" name="started_date" - rules="required|before_started_date:ended_date"> + :rules="`required${syncTask.started_date != taskStartedDate ? '|after_today_date' : ''}|before_started_date:ended_date`" >
rulesに設定するかの条件を入れればOK
<script>内
extend('after_today_date', { message: '今日より後の日付を入力してください。', validate (value) { return value == null || value === '' || new Date() <= new Date(`${value}T23:59:59`) } })
この中では、thisの値を参照できない。スコープ違うの当然ですね。
入力しない値と比較する場合
開始以降、翌月末まで
<template>内
<validation-provider name="start"> <v-text-field v-model="syncEvent.start" type="hidden" /> </validation-provider> <validation-provider v-slot="{ errors }" name="last_ended_date" rules="required|after_end_date:start|before_end_date:start">
thisの値を参照できないので、hiddenで値を渡してあげる。
そうすれば、他の入力値と比較する場合と同じように値を渡せます。
<script>内
import { addMonths, endOfMonth } from 'date-fns' extend('after_end_date', { params: [{ name: 'startValue', isTarget: true }], message: '開始以降の日付を入力してください。', validate (value, { startValue }) { return value == null || value === '' || startValue == null || startValue === '' || new Date(value) >= new Date(startValue) } }) extend('before_end_date', { params: [{ name: 'startValue', isTarget: true }], message: '翌月末までの日付を入力してください。', validate (value, { startValue }) { return value == null || value === '' || startValue == null || startValue === '' || new Date(value) <= endOfMonth(addMonths(new Date(startValue), 1)) } })