Vuex操作会更改组件数据

时间:2018-03-18 10:34:57

标签: vue.js vuejs2 vuex

我有以下组件,它只是一个简单的登录表单:

<template>
    <v-card>
        <v-card-title primary-title class="headline white--text primary">Login</v-card-title>
        <form @keyup.enter="submit( form )" @submit.prevent="submit( form )">
            <v-card-text>
                <v-text-field
                    label="Email address"
                    required
                    :error-messages="errors['email']"
                    v-model="form.email"
                />

                <v-text-field
                    label="Password"
                    hint="At least 8 characters"
                    minlength="8"
                    :append-icon="passwordVisible ? 'visibility_off' : 'visibility'"
                    :append-icon-cb="() => (passwordVisible = !passwordVisible)"
                    :type="passwordVisible ? 'text' : 'password'"
                    required
                    counter
                    :error-messages="errors['password']"
                    v-model="form.password"
                />
            </v-card-text>

            <v-card-actions>
                <v-btn type="submit" color="primary">Login</v-btn>
            </v-card-actions>
        </form>
    </v-card>
</template>

<script>
    export default
    {
        metaInfo: {
            title: 'Login'
        },

        data()
        {
            return {
                form: {
                    email: '',
                    password: '',
                },
                passwordVisible: false,
            }
        },

        computed: {    
            errors()
            {
                return this.$store.getters.errors;
            }
        },

        methods: {
            submit( data )
            {
                this.$store.dispatch( 'userLogin', data );
            }
        },
    }
</script>

userLogin操作如下所示:

userLogin( context, data )
        {
            // Base64 encode password
            data.password = btoa( data.password );

            fetch( '/api/users/login', {
                headers: {
                    'X-Requested-With': 'XMLHttpRequest',
                    'X-CSRF-token': window.token,
                    'Content-Type': 'application/json',
                    'Accept': 'application/json'
                },
                method: 'POST',
                body: JSON.stringify( data )
            })
                .then( response => {
                    return response.json();
                })
                .then( response => {
                    // If there are any errors
                    if( response.errors )
                    {
                        context.commit( 'errors', response.errors );
                    }

                    context.commit( 'message', response.message );
                    context.commit( 'success', response.success ? response.success : false );

                    if( response.token )
                    {
                        context.commit( 'userLogin', response.token );
                    }
                })
                .catch( error => {
                    console.error( 'userLogin', error );
                });
        }

表单中的所有内容都按预期工作,直到我尝试登录为止。提交表单后,该操作将运行2次。首先,我得到预期的结果,这是API生成的标记。但是,第二次模板中的密码字段已更改为base64值。

所以我的问题是为什么动作执行了两次?为什么密码字段值只在&#34;存储和读取时才会改变&#34;从组件内部?

我希望有人能为我解决问题。

1 个答案:

答案 0 :(得分:1)

为什么动作执行了两次

表单上附加了两个事件侦听器:

  1. @submit.prevent
  2. @keyup.enter
  3. 这两个事件的事件处理程序都是submit( form ),它正在调度操作

    当您专注于输入字段并点击输入按钮时,表单将被提交implicitly。 因此,submit( form )将被调用两次;

    1. 表单的提交方法被称为
    2. 由于按下了输入按钮,@keyup.enter的事件处理程序也称为
    3. 为什么只在组件中“存储和读取”值时密码字段值会发生变化?

      您将form作为有效负载传递给作为对象的操作:

      form: { email: '', password: '', }
      

      在JavaScript对象中passed by reference. 在您的操作中,您将通过

      突变form对象的密码属性
      data.password = btoa( data.password );
      

      所以这些变化也反映在组件中

      <强> ----------------------------------

      <强>孤子

      why is the action executed twice
      

      由于输入处于焦点时按下输入的默认行为是提交表单,您可以删除@keyup.enter侦听器

      Why does the password field value change when the value is only "stored and read" from within the component?
      

      不要改变原始对象。而是创建一个新的并将其作为您的帖子请求主体传递

      // Base64 encode password
      let details = {
              email: data.email, 
              password: btoa( data.password )
          }
      
      fetch( '/api/users/login', {
          headers: {
              'X-Requested-With': 'XMLHttpRequest',
              'X-CSRF-token': window.token,
              'Content-Type': 'application/json',
              'Accept': 'application/json'
          },
          method: 'POST',
          body: JSON.stringify( details )
      })