Vee Validate - 服务器端验证和前端验证

Posted

技术标签:

【中文标题】Vee Validate - 服务器端验证和前端验证【英文标题】:Vee Validate - Sever side validation and front end validation 【发布时间】:2020-10-17 02:58:33 【问题描述】:

我有一个 laravel 流明端点,我从中返回错误。我面临的问题是 vee validate 没有设置错误?

<template>
  <v-container fluid class="ma-0 pa-0">

    <v-card route>
      <v-card-title class="primary white--text">Create New User</v-card-title>

      <v-row align="center" :class="'px-6': $vuetify.breakpoint.xs, 'pa-8': $vuetify.breakpoint.smAndUp">
        <v-row justify="space-between" v-if="!isCreating">

          <v-col cols="12" md="4">

            <v-row align="center" justify="center" class="mb-4">
              <v-avatar color="primary" size="128">
                <v-icon size="48" dark v-if="!userAvatarName()">mdi-account</v-icon>
                <span 
                  v-if="userAvatarName()"
                  class="white--text display-2"
                > userAvatarName() </span>
              </v-avatar>
            </v-row>
          </v-col>

          <v-col>

            <ValidationObserver v-slot=" invalid, validated, passes " ref="provider">
              <v-form @submit.prevent="passes(handleSubmit)">

                <v-row >
                  <v-col class="py-0">
                   <VTextFieldWithValidation vid="username" rules="required" v-model="newUser['username']" label="Username" />
                  </v-col>
                </v-row>
                <v-row >
                  <v-col class="py-0">
                    <VTextFieldWithValidation vid="email" rules="required|email" v-model="newUser['email']" label="Email address" />
                  </v-col>
                </v-row>

                <v-row >
                  <v-col class="py-0">
                    <VTextFieldWithValidation rules="required" v-model="newUser['first_name']" label="First name" />
                  </v-col>
                  <v-col class="py-0">
                    <VTextFieldWithValidation rules="required" v-model="newUser['last_name']" label="Last name" />
                  </v-col>
                </v-row>

                <v-row >
                  <v-col class="py-0 mt-4">
                    <ValidationProvider name="role" rules="required" v-slot=" errors, valid ">
                      <v-select
                        :error-messages="errors"
                        :success="valid"
                        :items="roles"
                        item-text="name" item-value="value"
                        label="Role"
                        outlined
                        v-model="newUser['role']"
                      ></v-select>
                    </ValidationProvider>
                  </v-col>
                </v-row>

                <v-divider></v-divider>

                <v-row >
                  <v-col class="py-0">
                    <v-switch
                      v-model="newUser['send_activation']"
                      label="Send Activation Email"
                    ></v-switch>
                  </v-col>
                </v-row>

                <v-row  v-if="!newUser['send_activation']">
                  <v-col class="py-0">
                    <ValidationProvider name="password" :rules="!newUser['send_activation'] ? 'required|min:8' : ''"  v-slot=" errors, valid ">
                      <v-text-field
                        outlined
                        counter
                        :error-messages="errors"
                        :success="valid"
                        label="Password"
                        :append-icon="userPasswordVisibility.password_current_show ? 'mdi-eye' : 'mdi-eye-off'"
                        :type="userPasswordVisibility.password_current_show ? 'text' : 'password'"
                        @click:append="userPasswordVisibility.password_current_show = !userPasswordVisibility.password_current_show"
                        v-model="newUser['password']"
                      ></v-text-field>
                    </ValidationProvider>
                  </v-col>
                  <v-col class="py-0">
                    <ValidationProvider name="confirmation" :rules="!newUser['send_activation'] ? 'required|password:@password' : ''" v-slot=" errors, valid ">
                      <v-text-field
                        outlined
                        counter
                        :error-messages="errors"
                        :success="valid"
                        label="Password Confirmation"
                        :append-icon="userPasswordVisibility.password_new_show ? 'mdi-eye' : 'mdi-eye-off'"
                        :type="userPasswordVisibility.password_new_show ? 'text' : 'password'"
                        @click:append="userPasswordVisibility.password_new_show = !userPasswordVisibility.password_new_show"
                        v-model="newUser['password_confirmation']"
                      ></v-text-field>
                    </ValidationProvider>
                  </v-col>
                </v-row>

                <v-row  class="mt-4">
                  <v-col class="py-0">
                    <v-btn text color="primary" :to=" name: 'organisation/users', params:  org_id: organisation.id ">Cancel</v-btn>
                  </v-col>
                  <v-col class="py-0 text-right">
                    <v-tooltip top>
                      <template v-slot:activator=" on ">
                        <v-btn outlined color="primary" v-on="on" @click="passes(handleSubmit)" :disabled="invalid || !validated">Add New User</v-btn>
                      </template>
                      <span>Create new user and add them to <strong>organisation.name</strong>.</span>
                    </v-tooltip>
                  </v-col>
                </v-row>

              </v-form>
            </ValidationObserver>

          </v-col>

        </v-row>

        <v-row align="center" justify="center" v-if="isCreating">
          <v-progress-circular
            class="ma-5"
            indeterminate
            color="teal accent-1 darken-2" >
          </v-progress-circular>
        </v-row>

      </v-row>
    </v-card>

  </v-container>
</template>

<script>
import  mapState  from 'vuex'

import  CREATE_USER  from '@/_apollo/GraphQL/userGraphQL'
import BreadcrumbsManager from '@/_util/breadcrumbManager'

import VTextFieldWithValidation from '@/components/inputs/VTextFieldWithValidation'
import  ValidationProvider, ValidationObserver  from "vee-validate"

export default 
  name: 'CreateUser',
  mixins: [BreadcrumbsManager],
  props: [
    'organisation'
  ],
  components: 
    ValidationObserver,
    ValidationProvider,
    VTextFieldWithValidation
  ,
  data() 
    return 
      userPasswordVisibility: 
        password_current_show: false,
        password_new_show: false,
        password_new_confirm_show: false        
      ,
      newUser: 
        send_activation: 1
      ,
      roles: [
         name: 'Admin', value: 'organisation_admin' ,
         name: 'User', value: 'user' 
      ],
      isCreating: false
    
  ,
  computed: 
    ...mapState(
      authUser: state => state.AUTH_STORE.authUser
    ),
  ,
  methods: 
    userAvatarName() 
      let name = '';

      if (this.newUser['first_name']) 
        name += `$this.newUser['first_name'].charAt(0).toUpperCase()`
      

      if (this.newUser['last_name']) 
        name += `$this.newUser['last_name'].charAt(0).toUpperCase()`
      

      if (name !== '') 
        return name
      

      return false
    ,
    async handleSubmit() 
      this.isCreating = true

      this.newUser['reseller_id'] = this.authUser.reseller_id
      this.newUser['organisation_id'] = parseInt(this.$route.params.org_id)
      this.newUser['send_activation'] = this.newUser['send_activation'] ? 1 : 0


      
      
      var refs = this.$refs.provider

      this.$apollo
        .mutate(
          mutation: CREATE_USER,
          variables: this.newUser
        )
        .then(response => 
          this.isCreating = false  

          const user = response.data.createUser
          
          this.$store.commit('USER_STORE/CREATE_USER', response.data.createUser)
          this.$toast.success('Successfully created new user.')
          this.$router.push( name: "organisation/users", params:  org_id: this.$route.params.org_id , () => )
        ).catch((error) => 
          this.isCreating = false
          this.$toast.error(error.graphQLErrors[0].extensions.code.message)
          let errors = error.graphQLErrors[0].extensions.code.errors
          console.log(errors)
          refs.setErrors(errors)
          console.log(refs)
          
        )

        refs.validate();
    
  ,
  created() 
    this.setBreadcrumbs([
       text: 'Dashboard' , path: '/' ,
       text: 'Organisations' , path: '/organisation/all/' , 
       text: ':organisation' , 
       text: 'Users', path: `/organisation/$this.organisation.org_id/users/` ,
       text: 'Create' 
    ])

    this.replaceBreadcrumb(
      find: ':organisation',
      replace:  text: this.organisation.name, path: `/organisation/$this.organisation.org_id` 
    )
  

</script>

在处理提交的捕获错误中,我可以看到服务器错误,但我的视图不会在现场显示错误?

我从以下文档中获得灵感:

https://codesandbox.io/s/veevalidate-backend-driven-validation-ynrp9?from-embed=&file=/src/App.vue

但无济于事。

谁能帮忙?

【问题讨论】:

【参考方案1】:

事实证明,apollo 客户端是一个未解决的承诺,因此修复是:

const userResponse = await this.$apollo
        .mutate(
          mutation: CREATE_USER,
          variables: this.newUser
        )
        .then(response => 
          this.isCreating = false  

          const user = response.data.createUser
          
          this.$store.commit('USER_STORE/CREATE_USER', response.data.createUser)
          this.$toast.success('Successfully created new user.')
          this.$router.push( name: "organisation/users", params:  org_id: this.$route.params.org_id , () => )
        ).catch((error) => 
          this.isCreating = false
          this.$toast.error(error.graphQLErrors[0].extensions.code.message)
          return error.graphQLErrors[0].extensions.code.errors.detail
        )

     
      this.$refs.provider.setErrors(userResponse);

【讨论】:

以上是关于Vee Validate - 服务器端验证和前端验证的主要内容,如果未能解决你的问题,请参考以下文章

vuejs 使用 vee-validate 进行表单验证

Vee-validate vue 3 setErrors 无法定义字段

Vee-Validate 自定义日期验证

vee-validate 按钮验证

如何使用 vee-validate 3 验证自定义组件?

Vee-Validate 验证组