If I have a computed property with only getter, setter is set to a noop. If I then try to assign to such a computed property, nothing happens. This can hide programming errors.
I would suggest that when not in production, instead of a noop a warning function would be assigned to a setter and a warning message would be printed if one tries to assign a value to such computer property.
Alternatively, output of computed property without setter could be configured without a setter at all, as a read-only property.
@yyx990803
Now with the vue version v2.4.2, when I put a state into the computed property by the mapState helper function,I get a warn [Vue warn]: Computed property "isLoading" was assigned to but it has no setter.
I couldn't find setter in the vuex state,so I think the warn may should consider this condition.
codes like this:
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
isLoading: false
}
const mutations = {
updateLoadingStatus (state, payload) {
state.isLoading = payload.isLoading
}
}
export default new Vuex.Store({
state,
mutations
})
// App.vue
<template>
<div id="app">
<router-view></router-view>
<loading v-model="isLoading"></loading>
</div>
</template>
md5-c6ef946cf43d4b3ec39dd3b16c586445
@Plortinus That happens because of the v-model. It' trying to change the value of isLoading but mapState will only create getters. You can probably make things work by binding the value to the isLoading and then handle the update by committing the mutations on the @input
@posva
Thanks a lot.I tried to use the sync modifier to handle this problem.It works.
But I am wondering if my solution is a good practice or not.The purpose of these codes is to show a loading toast when switch one page to another page in an SPA.
<template>
<div id="app">
<router-view></router-view>
<loading :value.sync="isLoading"></loading>
</div>
</template>
<script>
import { Loading } from 'vux'
import { mapState } from 'vuex'
export default {
name: 'app',
components: {
Loading
},
computed: {
...mapState({
isLoading: state => state.isLoading
})
}
}
</script>
Why/when would the <loading> component ever want to change the value of "isLoading"? That component can hardly know when the process is over, can it?
So I don't see a need for .sync or v-model or anything like it.
I update the value of isLoading before/after the router action.
router.beforeEach(function (to, from, next) {
store.commit('updateLoadingStatus', { isLoading: true })
next()
})
router.afterEach(function (to) {
store.commit('updateLoadingStatus', { isLoading: false })
})
Yeah sure, but then that value will go from your parent component down to the <loading> compoent, not up from the loading component. That value is not changed in the <loading> component, which is the only situation that you would need v-model or .sync for.
Maybe you have a missunderstanding how props work, at least in combination with computed properties?
okay mate this is a snippet of my code maybe it may help you figure out where you are wrong but i Think it should be easier now since i also had the same error but with getter
`computed: {
comparePasswords() {
return this.password !== this.confirmPassword
? "Passwoeds do not match!"
: "";
},
user() {
return this.$store.getters.user;
}
},
watch: {
user: function(value) {
if (value !== null && value !== undefined) {
this.$router.push("/");
}
}
},`
Most helpful comment
@Plortinus That happens because of the
v-model. It' trying to change the value ofisLoadingbut mapState will only create getters. You can probably make things work by binding thevalueto theisLoadingand then handle the update by committing the mutations on the@input