Reputation: 67
I am using Vue.js with TypeScript.
Link to my repo: https://github.com/Am4nzi/ac-vue
I have a component called Albums.vue
which is rendering an iFrame. I am attempting to update the source URL of the iFrame when a button is clicked in another component called AlbumsLeft.vue
. This updates a property in my store state called albumURL
.
The issue I am having is that the computed property I am using to set the URL in Albums.vue is not updating the URL in the iFrame element when the value in the store changes.
My understanding is that a computed property should automatically update when it detects a change, however I could be mistaken. If this is the wrong approach, could anyone recommend a better one?
I can confirm that the state in the store does change as expected when the button is clicked via inspecting Vuex in Vue devtools.
I am setting the iFrame source URL dynamically using v-bind:
<iframe
:src="imageSrcURL"
...
I am getting the URL from the store and setting it to a variable called imageSrcUrl via a computed property:
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component
export default class Albums extends Vue {
get getAlbumURL() {
return this.$store.state.albumURL;
}
private imageSrcURL = this.getAlbumURL;
}
</script>
The event handler within AlbumsLeft.vue is called changeAlbum:
changeAlbum(name: string) {
this.$store.dispatch(
'updateAlbumURL',
'https://bandcamp.com/EmbeddedPlayer/album=4251477660/size=large/bgcol=333333/linkcol=ffffff/tracklist=false/transparent=true',
);
}
This is my store:
export default new Vuex.Store({
state: {
currentAlbumId: '',
albumURL: 'https://bandcamp.com/EmbeddedPlayer/album=3937120203/size=large/bgcol=333333/linkcol=ffffff/tracklist=false/transparent=true',
},
mutations: {
setAlbumID(state, albumId) {
state.currentAlbumId = albumId;
},
setAlbumUrl(state, albumURL) {
state.albumURL = albumURL;
},
},
actions: {
updateAlbumID({ commit }, albumId) {
commit('setAlbumID', albumId);
},
updateAlbumURL({ commit }, albumId) {
commit('setAlbumUrl', albumId);
},
},
modules: {
},
});
Thanks in advance!
Upvotes: 1
Views: 1068
Reputation: 90277
The problem is here:
get getAlbumURL() {
return this.$store.state.albumURL;
}
private imageSrcURL = this.getAlbumURL;
getAlbumURL
changes correctly, but you're not reassigning it to imageSrcURL
, which remains unchanged, hence no update in the template.
Either use getAlbumURL
in :src
of <iframe>
or, if you do need imageSrcURL
for some functionality you haven't shown here, place a watch
on getAlbumURL
and update imageSrcURL
each time the former changes.
Side note: imageSrcURL
should not be private
if you use it in <template>
. private
means it's only accessible to the class. The template is outside the class. Basically, your production build
will fail because of this error.
If the only reason for having imageSrcURL
is because you can't mutate getAlbumURL
, you can actually, using a setter:
get getAlbumURL() {
return this.$store.state.albumURL;
}
set getAlbumURL(val) {
this.$store.dispatch('updateAlbumURL', val);
}
Now you can safely use getAlbumURL
as v-model
or whatever. And you might also understand why you should avoid naming properties getStuff
. stuff
will do.
Upvotes: 1