App.vue
<HeaderPart></HeaderPart>
<router-view />
<PlayerBar v-if="audio"></PlayerBar>
I want to Hide/Show this PlayerBar using functions, In main.js i have created all the function to alter the value of audio.
Vue.mixin({
data: function() {
return {
baseURL: "https://sampleurl",
authToken: "sampleauth",
watch: false,
audio: true
};
},
methods: {
playaudio(item) {
window.Amplitude.playNow(item);
},
playvideo() {
this.audio = false;
this.watch = true;
console.log(this.audio);
},
stopvideo() {
this.watch = false;
this.audio = true;
console.log(this.audio);
}
},
computed: {
...mapGetters({
cur_user: "user"
})
}
});
So Whenever playvideo, the Playerbar will be hidden, and when he close video, playerbar will be shown. in Console.log, Values are coming fine, Audio is changing to true/false but playerbar not getting hidden on frontend
try v-show instead of v-if
<PlayerBar v-show="audio"></PlayerBar>
It might the naming conflict with the Vue component "watch" option (Vue watch option)
Related
I am working on a product overview page, that send out an API-call based on the current Category you are looking at:
store.dispatch("tweakwise/fetchAPIAttributesLayeredNavigation", {
tweakwiseCategory,
this.pageNumber,
}
In my Store, the data from this API-call will be set in the following VueX Store State:
this.$store.state.tweakwise.tweakwiseLayeredNavigationAttributes: []
I want to react to this data in my front-end but my Computed methods do not seem to react to this change. As you can also see in the function below I added a Catch to prevent a "Non defined" error. The function, however, will not be called after the state has been set.
This computed property is also added to the Mount() op the component
computed: {
initialFetchProducts() {
this.fetchProducts(
this.$store.state.tweakwise?.tweakwiseLayeredNavigationAttributes || []
);
},
},
make computed property for state you want to watch,
than create watch() for this prop. In watch you can react on computed property change.
<template>
<div v-for="product in products"></div>
</template>
<script>
export default {
data: {
return {
products: [],
}
},
computed: {
tweakwiseLayeredNavigationAttributes() {
return this.$store.state.tweakwise.tweakwiseLayeredNavigationAttributes;
},
},
watch: {
// on every tweakwiseLayeredNavigationAttributes change we call fetchProducts
tweakwiseLayeredNavigationAttributes: {
handler(newValue, oldValue) {
this.fetchProducts(newValue);
},
deep: true, // necessary for watching Arrays, Object
immediate: true, // will be fired like inside mounted()
}
},
methods: {
async fetchProducts(params) {
const products = await axios.get('/api', params);
this.products = products;
}
}
};
</script>
I have two components. One of them creates instances of the other one and adds them to an array then I try to watch on it to execute some functions, but it never triggers. My structure looks something like this:
const Child = Vue.extend({
data() {
triggerMe: false
},
methods: {
triggerSomething: function() {
console.log('It's called for sure');
this.triggerMe = true;
}
}
});
const Parent = Vue.extend({
data() {
children: []
},
components: {
child: Child
},
methods: {
addChild: function() {
this.children.push(new Child());
this.children[this.children.length - 1].$watch('triggerMe', _ => console.log('Never called'));
}
}
});
It works just right if it's the only one. How to fix that?
What I found is that $watch only triggers when component is mounted to some element in document. Other approach is needed:
<scipt id="parent-template">
<child
#trigger="triggerThat"
></child>
</script>
<script>
// in Child
this.$emit('trigger', someData);
// in Parent
methods: {
triggerThat: function(data) {
console.log('I can hear you');
console.log(data);
}
}
</script>
Vue doesn't rerender binded class when data changes
I declared data 'isLoading' with default value and binded in html tag and also declared method that changes the data.
Please see the code below!
style
.is-red{
background: red;
}
.is-blue{
background: blue;
}
script
export default {
created() {
this.isLoading = true;
},
mounted() {
},
data() {
return {
isloading: true
};
},
methods: {
changeColor() {
this.isLoading = !this.isLoading;
console.log(this.isLoading);
}
}
}
html
<h1 v-bind:class="{'is-blue': isLoading, 'is-red': !isLoading }">hello</h1>
<button #click="changeColor">toggle</button>
I can see the data switching between 'true' and 'false' in the console log. However nothing changes in DOM.
what is the problem?
You declared your variable with name isloading.
And you declare isLoading in created.Vue won't Observe changes on dynamic variables.
To update dynamic variables inside a component use Vue.set() or this.$set().
Your script:
export default {
mounted() {
},
data() {
return {
isLoading: true
};
},
methods: {
changeColor() {
this.isLoading = !this.isLoading;
}
}
}
try to use computed like below
script
export default {
data() {
return {
isloading: true
};
},
computed:{
classes(){
return this.isloading ? 'is-blue' : 'is-red';
}
},
methods: {
changeColor() {
this.isLoading = !this.isLoading;
console.log(this.isLoading);
}
}
}
html
<h1 :class="classes">hello</h1>
<button #click="changeColor">toggle</button>
I have a Vue project with vuetify, and i want to use the loading functionality.
The project is set up so the items are loaded with a computed field.
How do i now manipulate the 'loading' property, turning it of when its loaded?
I tried attaching the items async fetching the data with a non-computed field. But the v-data-table is turned into a component and i'm not succeeding.
<data-table
:title="title"
:headers="headers"
:items="allUsers"
:loading="loading"
#editItem="onEdit"
#deleteItem="onDelete" >
</data-table>
The allUsers property is computed
Right now the loaded property is also computed putting a .length on the allusers. This only works if there are users ... if none it keeps spinning.
computed: {
allUsers () {
return this.$store.getters['users/users']
},
loading(){
return this.$store.getters['users/users'] != null;
}
},
Assuming you load users into your store within an action, you should also set some state for loading.
For example (simplified, no module)
const store = {
state: {
users: [],
loading: false
},
mutations: {
setUsers (state, users) {
state.users = users
},
isLoading (state) {
state.loading = true
},
loadingComplete (state) {
state.loading = false
}
},
actions: {
async loadUsers ({ commit }) {
commit('isLoading') // set loading state
commit('setUsers', await fetchUserDataFromSomwhere())
commit('loadingComplete')
}
}
}
Now your components can subscribe to the loading state
computed: {
loading () {
return this.$store.state.loading // or use mapState / mapGetters / whatever
},
allUsers () {
return this.$store.state.users
}
}
I have code like this :
Vue.component("sample", {
inherit: true,
template: "#sample",
props: {
active : "active",
...
},
methods: {
forceChangeActive: function(){
var activeItem = this.$parent._data.active;
var modalSetup = this.$parent._data.showModal;
console.log("1.before function", this.$parent._data);
this.$parent.$options.methods.baseAction(activeItem, modalSetup);
console.log("2.before function", this.$parent._data);
});
}
});
new Vue({
el: "#app",
data: {
active: 0,
showModal: false,
...
},
methods: {
baseAction: function(activeItem, modalSetup){
console.log("3.modal", modalSetup, "activeItem": activeItem);
modalSetup = true;
activeItem = 2;
console.log("4.modal", modalSetup, "activeItem": activeItem);
}
}
});
There are active and showModal data variables in new Vue. Now I'm getting undefined for both if I use this.active or this.showModal.
And console output is:
before function Object { active=0, showModal=false }
modal false, activeItem 0
modal true, activeItem 2
before function Object { active=0, showModal=false }
How I can change variable`s values in new Vue or in component?
inherit:true is deprecated.
You need to explicitly pass active and showModal to the child component using properties. You can use .sync to make sure they are shared back to the parent as well:
<sample :active.sync="active" :show-modal.sync="showModal"></sample>