Вопрос об использовании ...mapMutations
, но в случае, если кто-то захочет добавить бизнес-логику, рекомендуются mapAction
и mapState
.Я объясню, как заставить его работать с mapAction
и mapState
, поскольку вызов API может включать использование бизнес-логики в вашем приложении.В противном случае, я бы сказал, почему вы вообще не пользуетесь VueX, за исключением уведомления другой части вашего приложения о том, что вы загружаете;).При этом, вот мой ответ.
Используя ...mapState
, вы получите то, что искали бы, computed
реактивность состояния.Это произошло бы особенно во время вызова действия.Затем действие будет меняться, или то, что мы называем commit
в VueX, - состояние (см. Документ: https://vuex.vuejs.org/guide/state.html)
Давайте возьмем ваш код и изменим его на модуль с пространством имен, а затем воспользуемся модулем.в вашем vue (это то, что я бы сделал, если приложение большое, в противном случае то же самое может быть достигнуто с помощью мутации или вообще без VueX):
const LOADING_STATE = 'LOADING_STATE'
export default {
namespaced: true, // Read the doc about that
state: {
loaded: false
},
mutations: {
[LOADING_STATE]: function (state, isLoading) {
state.loading = isLoading
}
},
actions: {
setLoading ({ commit }, isLoading) {
commit(LOADING_STATE, isLoading)
}
}
}
Для вашего vue файл, где у вас есть ваш шаблон и ваши действия. Это будет выглядеть так:
<script>
import { mapAction, mapState } from 'vuex'
exports default {
computed: {
...mapState({
// Here you could even have the full computation for the CSS class.
loading: state => state.loadingModule.loading,
// Like this... or you could use the getters that VueX does (search in the documentation since it's out of the scope of your question)
loadingCss: state => { return state.loadingModule.loading ? 'is-loading' : '' }
})
},
methods: {
// Usage of a namespace to avoid other modules in your VueX to have the same action.
...mapActions(['loadingModule/setLoading']),
}
}
</script>
А что касается вашего HTML-шаблона, вы сможете вызвать метод this['loadingModule/setLoading'](true)
или false
, а затем свойството, на что вы можете реагировать, будет «загружаться».
Во время использования обещаний, во время вашего post
или get
или любого другого HTTP-вызова rest, не забывайте контекст.Если вы используете Axios, после регистрации его в контексте VueJs я бы сделал
this.$http.get('/my/api')
.then(response => {
// ... some code and also set state to ok ...
})
.catch(e => {
// set state to not loading anymore and open an alert
})
Давайте завершим ваш код сейчас, учитывая, что вы где-то выполняете свой HTTP (S) вызов.
<form @submit.prevent="postThis">
<div class="field">
<div class="control">
<!-- Here I would then use a computed property for that class (error). I would even put the a template or a v-if on a div in order to show or not all those html elements. That's you're choice and I doubt this is your final code ;) -->
<input class="input" :class="{ 'is-danger': errors.title }" type="text" id="title" placeholder="I have this idea to..." autofocus="" v-model="newTitle">
</div>
<p class="is-size-6 help is-danger" v-if="errors.title">
{{ errors.title[0] }}
</p>
</div>
<div class="field">
<div class="control">
<button @click="['loadingModule/setLoading'](true)" type="submit" :class="{'is-loading' : loading }">
Post
</button>
</div>
</div>
</form>