Обновление вычисляемого свойства (формы) в Vue при ошибке? - PullRequest
0 голосов
/ 12 июня 2018

Хорошо, так что я последовал за всеми видео Vue Laracasts, которые заканчиваются классом Form и Errors.Вот ссылка на репозиторий github из видео:

https://github.com/laracasts/Vue-Forms/blob/master/public/js/app.js

Теперь я пытаюсь интегрировать Vuex, чтобы отслеживать моего текущего вошедшего в систему пользователя, предварительно заполнить формус текущими значениями и отображать ошибки в случае сбоя проверки Laravel.

Проблема, с которой я, похоже, сталкиваюсь, заключается в том, что мне нужно установить свой authUser как вычисляемое свойство, чтобы извлечь его из хранилища Vuex.,Затем, так как я не могу использовать их ни в каком наборе данных, мне пришлось переместить мою форму в вычисляемое свойство.Теперь, когда это вычисляемое свойство, оно никогда не обновляется, поэтому в моей форме никогда не возникает ошибок, даже когда выдается ошибка.

Вот мой файл маршрута Account.vue

<template>
<div>
    <form @submit.prevent="onSubmit" @keydown="form.errors.clear($event.target.name)">
        <div class="row">
            <div class="form-group col-md-6 col-lg-3">
                <label>Name</label>
                <input type="text" class="form-control" name="user" autocomplete="false" v-model="form.name">
                <span class="help is-danger" v-if="form.errors.has('name')" v-text="form.errors.get('name')"></span>
            </div>
            <div class="form-group col-md-6 col-lg-3">
                <label>Email address</label>
                <input type="email" class="form-control" placeholder="Enter email" autocomplete="false" name="email" v-model="form.email">
                <span class="help is-danger" v-if="form.errors.has('email')" v-text="form.errors.get('email')"></span>
            </div>
            <div class="form-group col-lg-3">
                <label>Password</label>
                <input type="password" class="form-control" placeholder="Password" autocomplete="false" name="password" v-model="form.password">
                <span class="help is-danger" v-if="form.errors.has('password')" v-text="form.errors.get('password')"></span>
            </div>
        </div>

        <div class="col-12">
            <button type="submit" class="btn btn-primary">Submit</button>
        </div>
    </form>
</div>
</template>

<script>
export default {
    computed: {
        authUserName: {
            get: function() {
                return this.$store.getters.getAuthUser.name;
            },
            set: function(value) {
                this.$store.commit('setAuthUserValue', { key: 'name', value })
            }
        },
        authUserEmail: {
            get: function() {
                return this.$store.getters.getAuthUser.email;
            },
            set: function(value) {
                this.$store.commit('setAuthUserValue', { key: 'email', value })
            }
        },
        form() {
            return new Form({
                name: this.authUserName,
                email: this.authUserEmail,
                password: ''
            })
        }
    },

    data() {
        return {

        }
    },

    mounted() {
    },

    methods: {
        onSubmit() {
            this.form
                .patch('/current-user')
                .then(status => {
                    this.$emit('success', status);
                });
        }
    }
}
</script>

index.js

import AuthUser from "../models/AuthUser";

export default new Vuex.Store({
state: { // = data
    authUser: {
        name: null,
        email: null,
    }
},

getters: { // = computed properties
    getAuthUser(state, getters) {
        return state.authUser;
    }
},

actions: { // = methods
    fetchAuthUser(context) {
        AuthUser.load(user => {
            context.commit('setAuthUser', user);
        });
    }
},

mutations: {
    setAuthUser(state, user) {
        Vue.set(state, 'authUser', user);
    },
    setAuthUserValue(state, payload) {
        state.authUser = { ...state.authUser, payload }
    }
}
});

app.js

import router from './routes';
import Hamburger from './components/Hamburger';
import NavHeader from './components/NavHeader';
import store from "./store/index";

new Vue({

el: '#app',
components: {
    Hamburger,
    NavHeader
},

data() {
    return {

    }
},

created() {
    store.dispatch('fetchAuthUser');
},
router,
store
});

Я пробовал возиться с наблюдателями, но все выдает ошибки,Я очень стараюсь создать форму с предустановленными значениями существующих пользователей, и мне было рекомендовано попробовать vuex, но сейчас я сталкиваюсь с этими проблемами, когда теперь нужно вычислять форму, а не задавать в данных, поэтому форма никогда не будетесть ошибки сейчас.Извините, потянул меня за волосы, изучая все эти новые вещи сразу. Lol.

EDIT

Я также попытался установить форму пустого объекта формы в данных,затем устанавливая свойства в mount (), но как бы я ни пытался получить доступ к authUser в смонтированном, я получаю неопределенное.

mounted() {
    console.log(this.authUser);
    console.log(this.authUser.name);
    console.log(this.$store.getters.getUser.name);
},

output ...

{ ob : наблюдатель}

не определено

не определено

РЕДАКТИРОВАТЬ 2

Последний код обновлен,все еще не отображаются ошибки, отображаемые под входными данными, хотя они отображаются в инструментах разработчика в .. Root> Аккаунт> computed> form> errors> errors

В нем перечислены ошибки имени и электронной почты, еслиЯ оставил их пустыми.Может ли это быть потому, что это двойное гнездо?Я знаю, что это проблема Laravel из-за того, как она вкладывает ответ json.

Возможно, что-то в этом классе Form или Errors в app.js?

1 Ответ

0 голосов
/ 12 июня 2018

AuthUser.load является функцией asynchronous, так как вы выполняете ее в хуке created, не гарантируется, что значения authUsers будут установлены к тому времени, когда Account.vue '* createdhook запущен.

Теперь проблема, с которой вы столкнулись, связана с тем, что у вас есть вычисляемое свойство без setter.Класс Form пытается mutate the value of the store directly, что приведет к взрыву консоли.

Если вы указали setter для своего значения, при попытке записи в него вы можете отреагировать на это значениепередается в setter, и вы можете отправить (или, в вашем случае, зафиксировать) это значение в хранилище:

computed: {
   authUser: {
      get(): {
          return this.$store.getters.getUser;
      },
      set(value): {
          this.$store.commit('setUser', value)
      }
   }
}

Но подождите, это все равно не будет работать!Зачем?Поскольку полученное вами значение будет просто значением ввода текста, как вы узнаете, какое свойство в AuthUser нужно обновить?Вероятно, самый простой способ решить эту проблему - создать computed property for each property on the authUser

computed: {
   authUserName: {
      get(): {
          return store.getters.getUser.name;
      },
      set(value): {
          this.$store.commit('setUser', { key: 'name', value })
      }
   },
   authUserEmail: {
      get(): {
          return store.getters.getUser.email;
      },
      set(value): {
          this.$store.commit('setUser', { key: 'email', value })
      }
   },
   authUserPassword: {
      get(): {
          return store.getters.getUser.password;
      },
      set(value): {
          this.$store.commit('setUser', { key: 'password', value })
      }
   }
}

Теперь вы можете создать экземпляр формы с каждым из получателей:

new Form({
    name: this.authUserName,
    email: this.authUserEmail,
    password: this.authUserPassword
})

Но, опять же, этовсе еще не будет работать!Нам нужна новая мутация, которая будет записывать только свойства нашего authUser

setUserValue(state, payload) {
   state.authUser = { ...state.authUser, payload }
}

. Используя простую деструктуру, мы можем перезаписать свойства нашего authUser и объединить новое значение вычисляемого свойства.

Теперь вам нужно обновить computed properties и использовать вместо него this.$store.commit('setUserValue', { key: 'name/email/password': value}) в вашем установщике.

Наконец, ваш authUser должен быть объектом с предустановленными свойствами:

authUser: {
    name: null,
    email: null,
    password: null
}

Это важно как properties of an object are reactive.Однако, если к объекту добавлены свойства, you cannot simply overwrite the object and have new reactive properties.Для этого вам нужно будет использовать Vue.set(), например:

setUser(state, user) {
    Vue.set(state, 'authUser', user)
}

. Это позволит правильно наблюдать наблюдаемые свойства, которые станут реактивными.Это важная концепция реактивности магазина VueX.Это также причина, почему ваши значения undefined.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...