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

时间:2020-06-26 13:33:15

标签: laravel vue.js vee-validate

我有一个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>

在句柄提交的catch错误中,我可以看到严重错误,但是我的视图在该字段上不会显示错误?

我从以下文档中汲取了灵感:

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

但无济于事。

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

事实证明,阿波罗客户端是一个无法解决的承诺,因此解决方法是:

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