vee-validateのエラーが出ているので、vee-validate4を導入して、コードを修正します。
前回:Nuxt BridgeをNuxt3に移行。先ずはVuetifyでページが表示される所まで

[plugin:vite:import-analysis] Failed to resolve import “vee-validate” from “pages/users/sign_in.vue”. Does the file exist?

vee-validate4を導入

【公式】VeeValidate – Form
GitHub – logaretm/vee-validate: ✅ Painless Vue forms
-> MIT license

Packageを追加

% yarn add -D vee-validate @vee-validate/rules @vee-validate/i18n

使用しているPageやComponentを修正

※v-bindだけだと、変更画面の初期値が表示されなくなるのでv-modelに戻しました。
v-model=”field.value”でもOKなのですが、
v-file-inputは、エラー(下記)になるので、定義を揃えておく事にしました。

[Vue warn]: Unhandled error during execution of scheduler flush.
 This is likely a Vue internals bug.
 Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/core

Uncaught (in promise) DOMException: Failed to set the 'value' property on 'HTMLInputElement':
 This input element accepts a filename, which may only be programmatically set to the empty string.

Uncaught (in promise) TypeError: Cannot read properties of null (reading 'emitsOptions')

vue.js – vee-validate + vuetify text input field → how to migrate to new versions? – Stack Overflow

pages/users/sign_up.vue

-        <validation-observer v-slot="{ invalid }" ref="observer">
+        <Form v-slot="{ meta }" ref="form">
          <v-form autocomplete="on">
            <v-card-title>アカウント登録</v-card-title>
            <v-card-text>

-              <validation-provider v-slot="{ errors }" name="password_confirmation" rules="required|confirmed_password:password">
+              <Field v-slot="{ errors }" v-model="query.password_confirmation" name="password_confirmation" rules="required|confirmed_password:@password">
                <v-text-field
+                  v-bind="field"
                  v-model="query.password_confirmation"
                  :type="showPassword ? 'text' : 'password'"
                  label="パスワード(確認)"
                  prepend-icon="mdi-lock"
                  :append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
                  autocomplete="new-password"
                  counter
                  :error-messages="errors"
                  @input="waiting = false"
                  @click:append="showPassword = !showPassword"
                />
-              </validation-provider>
+              </Field>

              <v-btn
                id="sign_up_btn"
                color="primary"
                class="mt-4"
-                :disabled="invalid || processing || waiting"
+                :disabled="!meta.valid || processing || waiting"
                @click="postSingUp()"
              >
                登録
              </v-btn>

-        </validation-observer>
+        </Form>

<script>
- import { ValidationObserver, ValidationProvider, extend, configure, localize } from 'vee-validate'
- import { required, email } from 'vee-validate/dist/rules'
+ import { Form, Field, defineRule, configure } from 'vee-validate'
+ import { localize, setLocale } from '@vee-validate/i18n'
+ import { required, email, min, max, confirmed } from '@vee-validate/rules'
+ import ja from '~/locales/validate.ja' // 標準のメッセージを使うなら'@vee-validate/i18n/dist/locale/ja.json'

- extend('required', required)
- extend('email', email)
- extend('min', min)
- extend('max', max)
- extend('confirmed_password', confirmed)
+ defineRule('required', required)
+ defineRule('email', email)
+ defineRule('min', min)
+ defineRule('max', max)
+ defineRule('confirmed_password', confirmed)

- configure({ generateMessage: localize('ja', require('~/locales/validate.ja.js')) })
+ configure({ generateMessage: localize({ ja }) })
+ setLocale('ja')

export default {
  components: {
-    ValidationObserver,
-    ValidationProvider,
+    Form,
+    Field,

-            this.$refs.observer.setErrors(error.response.data.errors)
+            this.$refs.form.setErrors(error.response.data.errors)

vee-validate4の変更点

  • validation-observer -> Form
  • validation-provider -> Field, v-modelで値を渡す必要がある。v-bind=”field”で元のと紐付ける
  • invalidは廃止されている。validは空が返ってくる。!meta.validに変更
  • extend -> defineRule
  • localizeは@vee-validate/i18nに移動している。setLocaleしないとenになる
  • Field rulesの参照が@始まりに変更。例: “confirmed:@password”

メッセージカスタマイズ

こちらも折角なので、tsに変更します。(jsonでも良いけど、コメントアウトできない)
vee-validate4では、キーやメッセージの表記が変わっているので注意。

  • _default, url -> 追加
  • excluded -> not_one_of、oneOf -> one_of
  • is_not, double -> 削除
  • {field} -> {_field_}
  • {min} -> 0:{min}, {max} -> 1:{max}, 0:{length}, 0:{width}, 1:{height}, 0:{size}

locales/validate.ja.js -> .ts

- module.exports = {
-   messages: {
+ const code = 'ja'
+ const messages = {
-     <元のメッセージ>
+     <↓変更後のメッセージ> ※confirmed_password/confirmed_new_password/size_20MBは追加しています。
   // _default: '{field}は有効な値ではありません',
   // alpha: 'アルファベットのみで入力してください。', // "{field}はアルファベットのみ使用できます",
  // alpha_num: '英数字のみで入力してください。', // "{field}は英数字のみ使用できます",
  // alpha_dash: '英数字とハイフン・アンダースコアのみで入力してください。', // "{field}は英数字とハイフン、アンダースコアのみ使用できます",
  // alpha_spaces: 'アルファベットと空白のみで入力してください。', // "{field}はアルファベットと空白のみ使用できます",
  // between: '0:{min}から1:{max}の値を入力してください。', // "{field}は 0:{min} から 1:{max} の間でなければなりません",
  // confirmed: '致していません。', // "{field}が一致しません",
  confirmed_password: 'パスワードと一致していません。',
  confirmed_new_password: '新しいパスワードと一致していません。',
  // digits: '0:{length}桁の数字を入力してください。', // "{field}は 0:{length}桁の数字でなければなりません",
  // dimensions: '幅0:{width}px、高さ1:{height}px以下にしてください。', // "{field}は幅 0:{width}px、高さ 1:{height}px 以内でなければなりません",
  email: '形式が正しくありません。', // "{field}は有効なメールアドレスではありません",
  // not_one_of: '値が正しくありません。', // "{field}は不正な値です",
  // ext: 'このファイルには対応していません。', // "{field}は有効なファイル形式ではありません",
  // image: 'この画像には対応していません。', // "{field}は有効な画像形式ではありません",
  // integer: '整数のみで入力してください。', // "{field}は整数のみ使用できます",
  // is: '致していません。', // "{field}が一致しません",
  // length: '0:{length}文字で入力してください。', // "{field}は 0:{length} 文字でなければなりません",
  // max_value: '0:{max}以下を入力してください。', // "{field}は 0:{max} 以下でなければなりません",
  max: '0:{length}文字以下で入力してください。', // "{field}は 0:{length} 文字以内にしてください",
  // mimes: 'このファイルには対応していません。', // "{field}は有効なファイル形式ではありません",
  // min_value: '{min}以上を入力してください。', // "{field}は 0:{min} 以上でなければなりません",
  min: '0:{length}文字以上で入力してください。', // "{field}は 0:{length} 文字以上でなければなりません",
  // numeric: '正数を入力してください。', // "{field}は数字のみ使用できます",
  // one_of: '有効な値を入力してください。', // "{field}は有効な値ではありません",
  // regex: '形式が正しくありません。', // "{field}のフォーマットが正しくありません",
  required: '入力してください。', // "{field}は必須項目です",
  // required_if: '入力してください。', // "{field}は必須項目です",
  // size: '0:{size}KB以下のファイルを選択してください。', // "{field}は 0:{size}KB 以内でなければなりません",
  size_20MB: '20MB以下のファイルを選択してください。'
  // url: '形式が正しくありません。' // "{field}は有効なURLではありません"
}

+ export default {
+   code,
+   messages
+ }

[Vue warn]: Runtime directive used on component with non-element root node.

[Vue warn]: Runtime directive used on component with non-element root node.
 The directives will not function as intended. 

Fieldでv-ifは使えましたが、v-showだとwarnが出て動かないので、spanやdivで囲みます。

-  <Field v-show="tabDescription === 'input'" v-slot="{ errors }" v-model="space.description" name="description">
+  <span v-show="tabDescription === 'input'">
+    <Field v-slot="{ errors }" v-model="space.description" name="description">

+  </span>

vee-validateのエラー表示は消えましたが、
今度は$axiosのエラーでクルクルが表示されたままになりました。
$axiosは廃止されたようなので、次回はFetch APIに書き換えます。少ない修正量を目指す。
Nuxt BridgeをNuxt3に移行。$axiosをFetch APIに書き換える

今回のコミット内容

origin#507 vee-validateを導入
origin#507 v-text-fieldで初期値が表示されない。v-file-inputがエラーになる。useApiRequestのFormData対応

Nuxt BridgeをNuxt3に移行。vee-validateを導入” に対して1件のコメントがあります。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です