'vuejs - Changing a computed property via a method
I am trying to adjust a computed property within a vue component inside a method. When this property changes I am trying to show/hide a div. Currently when I perform the click event, I am seeing the correct boolean log under the set function, but not seeing any change to the showBanner prop.
Here's where I'm at.
HTML
<template>
<div v-if="someConfig.displayBanner && showBanner" class="bn-banner">
{{showBanner}}
</div>
</template>
<script>
import { mapActions, mapState } from 'vuex';
export default{
name: "myComponentShell",
computed: {
...mapState('utilitiesStore', [
'someConfig'
]),
styleObject () {
return {
background: this.someConfig.colorHex
}
},
showBanner:{
get () {
return (this.someConfig.text === localStorage.getItem("gma_alerts_hide")) ? false : true
},
set (value) {
console.log(value)
return value
}
}
},
methods: {
...mapActions('utilitiesStore', [
'getJSON'
]),
closeBreaking () {
localStorage.setItem("someData", this.someConfig.text)
this.showBanner = false;
}
},
}
</script>
Solution 1:[1]
showBanner is not truly a computed property, it is simply a variable who's state is initialized from a ternary. Therefore you should just declare it as a data property.
data () {
return {
showBanner: (this.someConfig.text === localStorage.getItem("gma_alerts_hide")) ? false : true
}
}
Then this.showBanner = false; makes sense.
Edit Updated data declaration because you're using single file components.
Solution 2:[2]
you can use && operator in your code to fixed "text is undefined" error
(this.someConfig && this.someConfig.text)
Inside this code:
data () {
return {
showBanner: (this.someConfig.text === localStorage.getItem("gma_alerts_hide")) ? false : true
}}
Solution 3:[3]
The value of a computed prop will always be the value returned by the getter.
Vue will only re-run the getter when it detects a change in any reactive value used inside the getter.
And localStorage is not reactive.
The setter is a function which is run when you assign a value to the computed, taking the value as an argument.
Your current setter:
set (value) {
console.log(value)
return value
}
does not do anything which could affect the returned value of the getter. In other words, no matter what you assign to the setter, although the setter code runs, the computed's value will always remain the same.
You might ask yourself: In closeBreaking method, I'm saving to localStorage, which should affect the getter. Why doesn't that assignment change the value of the getter?
That's the proper question to be asked here.
It's because localStorage is not reactive (it's a native browser API and browser APIs are not reactive). When localStorage changes, Vue doesn't know about the update.
How to fix this? In short, track the state of showBanner inside the component, do not rely on localStorage
To achieve it, create a reactive showBanner prop (in data) and update it (using a method) after you write to localStorage and when someConfig.text changes.
The gist:
export default {
data: () => ({
showBanner: false
}),
methods: {
setShowBanner() {
this.showBanner =
this.someConfig.text !== localStorage.getItem("someData");
},
closeBreaking() {
localStorage.setItem("someData", this.someConfig.text);
this.setShowBanner();
}
},
watch: {
'someConfig.text': {
handler() { this.setShowBanner() },
immediate: true
}
}
}
Note: You still need to add the store related stuff, I didn't add it above as it's irrelevant for the update logic.
Note: This still doesn't make localStorage reactive. In other words, with the above code you still should not expect Vue to detect a change to localStorage performed by some other component. If you need this functionality, you should place someData into a store and update localStorage as a side-effect of that stores' state being mutated.
Solution 4:[4]
That's because you're returning a value instead of assigning a value in your set method of showBanner computed property.
Try something like
set (value) {
this.someConfig.text = value; // I assign a value so get() method will trigger
}
Keep in mind that set method must modify something in order to see changes in showBanner
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ohgodwhy |
| Solution 2 | ElsaKarami |
| Solution 3 | |
| Solution 4 | Eduardo Aguad |
