State of variable not binding - vue.js

<button id="btn1"> Button 1 </button>
<button id="btn2" v-if="state == 2"> Button 2 </button>
export default {
data() {
return {
emailPreferences: {
isLoading: false
},
state: 0
}
},
methods: {
OnBtn1Click() {
this.state = 2;
}
}
}
I'm trying to show the button "btn2" when I click the Button 1. But it doesn't seems to work.

Just putting #skirtle's comment in an awnser:
new Vue({
el: '#app',
data: {
state: 0
},
methods: {
OnBtn1Click() {
this.state = 2;
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button #click="OnBtn1Click" id="btn1"> Button 1 </button>
<button id="btn2" v-if="state == 2"> Button 2 </button>
</div>
The logic of your code was fine, just had the 'onclick' property missing for the button

Add a click event on the button
<button #click="OnBtn1Click" id="btn1"> Button 1 </button>

Related

How to show a hidden div by clicking on another div (button) in Vue?

I am trying to show the loading div that's normally hidden after clicking a confirm button, even after changing the hidden value on click.
here is my code:
<div class="form-btns">
<button type="button" class="btns full-width" v-on:click="submitPhoneNumber(); isHidden = false">
{{t('confirmNumber')}}
</button>
<loader title="" v-if="!isHidden"></loader>
<button type="button" class="btns hyperlink">
{{t('accountRecovery')}}
</button>
</div>
data() {
return {
isHidden: true,
};
Your code is a little funky. Get rid of how you're trying to set the value directly in the template HTML and set it in your function in the methods. So your new code would be:
<div class="form-btns">
<button type="button" class="btns full-width" v-on:click="submitPhoneNumber()">
v {{t('confirmNumber')}}
</button>
<loader title="" v-if="!isHidden"></loader>
<button type="button" class="btns hyperlink">
{{t('accountRecovery')}}
</button>
</div>
Then in your methods just toggle the value like this:
data() {
return {
isHidden: true,
}
},
methods: {
submitPhoneNumber() {
this.isHidden = false; // I would probably rename this to isLoading and invert the logic
// Other stuff...
}
}
You should change the isHidden value inside the submitPhoneNumber, either as below, or with a dedicated function that you call in the first one.
let app = new Vue({
el: '#app',
data: {
isHidden: true
},
methods: {
submitPhoneNumber() {
this.isHidden = false;
// Simulate an API response after 3s to hide the loader
setTimeout(() => { this.isHidden = true; }, 3000);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button type="button" #click="submitPhoneNumber()">
Submit button
</button>
<p v-if="!isHidden">Loading...</p>
</div>

How initialize tabs when state changes in vue?

Here is sample of my code in vue.
<template>
<tabs>
<tab
v-for="c in myCount"
:key="c"
:name="c"
:selected="c === 1"
>
{{ c }}
</tab>
</tabs>
<button type="button" #click="showOneTab">Show just one tab</button>
</template>
<script>
export default {
name: 'myComponent',
data: {
return {
myCount: 5
}
},
methods: {
showOneTab() {
this.myCount = 1
}
}
}
</script>
myCount has default value of 5. after clicking a button it changes to 1. I need to tabs be removed and just the first appears.
Your code looks correct. But it doesn't work, you can try a computed property:
v-for="c in count"
computed: {
count() {
return myCount
}
}
Your data option should be a function that returns an object data(){ return { myCount: 5 } } not a field with object as value :
Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
el: '#app',
data(){
return {
myCount: 5
}
},
methods: {
showOneTab() {
this.myCount = 1
}
}
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app" class="container">
<div v-for="c in myCount" :key="c">
{{ c }}
</div>
<button type="button" #click="showOneTab">Show just one tab</button>
</div>

How to toggle button in vuejs

I have play and pause buttons.
How to make them toggle button(show/hide) in Vue?
This is my code so far,
<button #click="slickPause" v-if="">slickPause</button>
<button #click="slickPlay" v-else>slickPlay</button>
methods: {
slickPause() {
this.$refs.carousel.pause();
},
slickPlay() {
this.$refs.carousel.play();
}
please help
You could make a state for playing and toggle it
new Vue({
el: '#app',
data: {
playing: false
},
methods: {
slickPause() {
// this.$refs.carousel.pause();
this.playing = false
},
slickPlay() {
// this.$refs.carousel.play();
this.playing = true
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button #click="slickPause" v-if="playing">slickPause</button>
<button #click="slickPlay" v-else>slickPlay</button>
</div>
This should work.
<button #click="togglePlay">
{{ isPlaying ? slickPause : slickPlay }}
</button>
data() {
return {
isPlaying: false
}
},
methods: {
togglePlay() {
let method = this.isPlaying ? pause : play;
this.$refs.carousel[method]();
this.isPlaying = !this.isPlaying
}
}

(Vue.js) I want to make image 1 pop up when I click on image 1, and I want image 2 to pop up when I click on image 2

There are several images. I want to make image 1 pop up when I click on image 1, and I want image 2 to pop up when I click on image 2. Can I solve it using the index in class?
Carousel.vue
<template>
<div v-for="(item, index) in items" :key="index">
<img :src="item.thumbnail" />
<button type="button" #click="imgClick()" :class="`img-index--${index}`">button-{{ index }}</button>
</div>
<Modal v-if="showModal" #close="showModal = false">
<div slot="body" v-for="(item, index) in items" :key="index">
<img :src="item.thumbnail" :class="`img-index--${index}`"/>
</div>
</Modal>
</template>
<script>
import Modal from './Modal.vue'
export default {
props: {
items: { type: Array, default: () => [] }
},
data() {
return {
showModal: false
}
},
methods: {
imgClick() {
this.showModal = !this.showModal;
}
},
components: {
Modal: Modal
}
}
</script>
You can build a new data from your items prop and inject a new property show: false for each image.
You don't need 2 v-for loops this way. You can put the Modal component inside the first loop and just use the item.show to display or not the modal.
<template>
<div>
<div v-for="(item, index) in photos" :key="index">
<div #click="imgClick(item)" style="cursor:pointer;>
<img :src="item.thumbnail" />
</div>
<Modal v-if='item.show' #close="item.show = false">
<div slot='body'>
<img :src="item.thumbnail" :class="`img-index--${index}`"/>
</div>
</Modal>
</div>
</div>
</template>
<script>
import Modal from './Modal.vue'
export default {
props: {
items: { type: Array, default: () => [] }
},
data() {
return {
photos: {}
}
},
created() {
this.photos = this.items.map(item => {
return { ...item, show: false }
})
},
methods: {
imgClick(item) {
item.show = true
}
},
components: {
Modal: Modal
}
}
</script>
Fiddle example here
Note: you can wrap the thumbnail inside a div to manage the click image.

Vue v-for conditional styling

I use v-for to create buttons. I add the .active class if isActiveButton() returns true:
<button
v-for="(text, index) in this.buttonOptions"
class="btn"
:class="{active: isActiveButton(text)}"
:value='text'
#mousedown.prevent #click="some_method">
{{text}}
</button>
What is the best way to add the .active class to the first button if isActive() returns false for all buttonOptions? Note that the buttonOptions is a prop.
A Computed Property would be the way to go!
var app = new Vue({
el: '#app',
data: {
buttonOptions: ['button1', 'button2', 'button3', 'button4']
},
methods: {
isActiveButton: function (text) {
return (text === text.toUpperCase());
},
some_method: function() {
console.log('Button clicked')
}
},
computed: {
shouldFirstBeActive: function () {
return (this.buttonOptions.filter(el => this.isActiveButton(el))).length === 0
}
}
});
.active {
background: #f00;
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<section>
<button
v-for="(text, index) in buttonOptions"
class="btn"
:class="{active: isActiveButton(text) || (shouldFirstBeActive && index === 0)}"
:value='text'
#mousedown.prevent #click="some_method">
{{text}}
</button>
</section>
</div>
I don't know what the methods isActiveButton do, so I had to improvise: It checks if the string is uppercase.
What does the trick is the computed property shouldFirstBeActive which returns true if all the items in the buttonOptions array fails the isActiveButton method:
return (this.buttonOptions.filter(el => this.isActiveButton(el))).length === 0
If you change the button2 to BUTTON2 for example, then the isActiveButton returns true for that item, which renders the shouldFirstBeActive computed property to false
var app = new Vue({
el: '#app',
data: {
buttonOptions: ['button1', 'BUTTON2', 'button3', 'button4']
},
methods: {
isActiveButton: function (text) {
return (text === text.toUpperCase());
},
some_method: function() {
console.log('Button clicked')
}
},
computed: {
shouldFirstBeActive: function () {
return (this.buttonOptions.filter(el => this.isActiveButton(el))).length === 0
}
}
});
.active {
background: #f00;
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<section>
<button
v-for="(text, index) in buttonOptions"
class="btn"
:class="{active: isActiveButton(text) || (shouldFirstBeActive && index === 0)}"
:value='text'
#mousedown.prevent #click="some_method">
{{text}}
</button>
</section>
</div>
Use a computed that filters this.buttonOptions where isActiveButton is true and that takes index as a parameter