Bootstrap-Vue + Vuelidate: "Dialog" 用于创建和更新数据

Bootstrap-Vue + Vuelidate: "Dialog" for creating and updating data

我正在尝试重新使用对话框表单,但在尝试更新 Vuelidate 时说该表单无效,我不确定为什么。这是我的代码。

<b-modal size="lg" ref="my-modal" hide-footer :title="modalTitle + ' User'">
    <form @submit.prevent="onSubmit" @reset.prevent="onReset">
        <b-row>
            <b-col>
                <b-form-input id="input-name"
                              v-model="form.name"
                              @input="$v.form.name.$touch()"
                              :state="$v.form.name.$dirty ? !$v.form.name.$error : null"
                              placeholder="Name"
                              trim></b-form-input>
             </b-col>
             <b-col>
                <b-form-input id="input-email"
                              v-model="form.email"
                              @input="$v.form.email.$touch()"
                              :state="$v.form.email.$dirty ? !$v.form.email.$error : null"
                              placeholder="Email"
                              trim></b-form-input>
            </b-col>
        </b-row>

        <b-row v-if="mode === 0">
            <b-col>
                <b-form-input id="input-password"
                              v-model="form.password"
                              @input="$v.form.password.$touch()"
                              :state="$v.form.password.$dirty ? !$v.form.password.$error : null"
                              type="password"
                              placeholder="Password"
                              trim></b-form-input>
            </b-col>
            <b-col>
                <b-form-input id="input-password-confirm"
                               v-model="form.password_confirmation"
                               @input="$v.form.password_confirmation.$touch()"
                               :state="$v.form.password_confirmation.$dirty ? !$v.form.password_confirmation.$error : null"
                               type="password"
                               placeholder="Password Confirmation"
                               trim></b-form-input>
            </b-col>
        </b-row>

        <b-button v-if="mode === 1"
                  class="mb-1"
                  :class="visible ? null : 'collapsed'"
                  :aria-expanded="visible ? 'true' : 'false'"
                  aria-controls="collapse-4"
                  @click="visible = !visible">Change Password
        </b-button>
        <b-collapse v-model="visible" class="mt-2">
            <b-form-input id="input-password-edit"
                          v-model="form.password_edit"
                          @input="$v.form.password_edit.$touch()"
                          :state="$v.form.password_edit.$dirty ? !$v.form.password_edit.$error : null"
                          type="password"
                          placeholder="New Password"
                          trim></b-form-input>
        </b-collapse>

        <b-row>
            <b-col>
                <b-form-select :options="roles"
                               v-model="form.role"
                               @input="$v.form.role.$touch()"
                               :state="$v.form.role.$dirty ? !$v.form.role.$error : null"
                               placeholder="User Role"></b-form-select>
            </b-col>
        </b-row>

        <b-row align-h="end" style="padding-left: 1rem; padding-right: 1rem">
            <b-button class="mr-1" @click="cancel" variant="secondary">Cancel</b-button>
            <b-button type="submit" variant="primary">Save</b-button>
        </b-row>
    </form>
</b-modal>
 data() {
        return {
            url: '/users',
            form: {
                name: '',
                email: '',
                password: '',
                password_confirmation: '',
                password_edit: '',
                role: ''
            },
            users: [],
            roles: [],
        }
    },
    validations: {
        form: {
            name: {
                required
            },
            email: {
                required,
                email
            },
            password: {
                required: requiredIf(this.modalTitle() === 'New')
            },
            password_confirmation: {
                required: requiredIf(this.modalTitle() === 'New'),
                sameAsPassword: sameAs('password')
            },
            role: {
                required
            },
            password_edit: {
                required: requiredIf(this.modalTitle() === 'Edit')
            }

        }
    },
 methods: {
        create() {
            this.onReset();
            this.mode = 0;
            this.$refs['my-modal'].show();
        },
        edit(item) {
            this.onReset();
            this.mode = 1;
            this.form = _.cloneDeep(item);
            this.form.role = this.form.roles[0]['id'];

            this.$refs['my-modal'].show();
        },
        onSubmit() {
            this.$v.$touch()
            console.log(this.$v.invalid);
            if (!this.$v.$invalid) {
                if (this.mode === 0) {
                    this.$inertia.post(this.url, {
                        name: this.form.name,
                        email: this.form.email,
                        password: this.form.password,
                        password_confirmation: this.form.password_confirmation,
                        role: this.form.role,
                    }).then(
                        () => {
                            if (Object.entries(this.$page.props.errors).length === 0) {
                                this.$refs['my-modal'].hide();
                                this.onReset();

                                this.$bvToast.toast('New User Created', {
                                    title: 'Action Successful',
                                    variant: 'success',
                                    toaster: 'b-toaster-top-center',
                                    solid: true
                                });
                            }
                        }
                    )
                } else {
                    console.log('here')
                    this.$inertia.put(this.url + '/' + this.form.id, {
                        name: this.form.name,
                        email: this.form.email,
                        role: this.form.role,
                        password_edit: this.form.password_edit
                    }).then(
                        () => {
                            if (Object.entries(this.$page.props.errors).length === 0) {
                                this.$refs['my-modal'].hide();
                                this.onReset();

                                this.$bvToast.toast('User Updated', {
                                    title: 'Action Successful',
                                    variant: 'success',
                                    toaster: 'b-toaster-top-center',
                                    solid: true
                                });
                            }
                        }
                    )
                }
            }
        },
    },

onSubmit() 中,如果我添加 console.log 它会在 if (!this.$v.$invalid) 之后停止工作,这意味着我没有正确使用 Vuelidate,但是在我尝试使用 requiredIf 我得到一个错误

Error in created hook: "TypeError: Cannot read property 'modalTitle' of undefined"

TypeError: Cannot read property 'modalTitle' of undefined

this.modelTitle() 是计算出来的 属性,我也试过 required: requiredIf(this.mode === 1) 但我得到了同样的错误。

我该如何修复它,以便在创建必填字段时包含 passwordpassword_confimation 但在编辑时不需要它们?

解决方案是像这样更改验证器,在我的例子中,为了能够编辑密码,使用变量 visible 打开了一个部分,因此只有当该部分可见时,它才会需要新密码,如果该部分不可见,则不需要更改密码。

    validations: {
        form: {
            password: {
                required: requiredIf(function (pass) {
                    return !this.form.id
                }),
            },
            password_confirmation: {
                required: requiredIf(function (pass) {
                    return !this.form.id
                }),
                sameAsPassword: sameAs('password')
            },
            password_edit: {
                required: requiredIf(function (pass) {
                    return this.form.id && this.visible
                }),
            }
        }
    },