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))
}
})
