I use:
bootstrap-vue
fullscreen-vue
And I have a simple project codesandbox.
There are many different modals in project. As not to create unnecessary methods (open, close, ... ) due to amount of popups with diffetent logic I use this.$bvModal.msgBoxConfirm with then.
Template:
<template>
<div id="app">
<fullscreen ref="fullscreen" #change="fullscreenChange" class="h-100">
<router-view/>
</fullscreen>
<div class="fullscreen-toggle">
<a href="#" #click="toggleFullscreen" class="btn btn-warning">
<span v-if="!fullscreen" class="fullscreen-btn">+</span>
<span v-if="fullscreen" class="fullscreen-btn">-</span>
</a>
</div>
</div>
</template>
Script:
<script>
export default {
name: "App",
data () {
return {
fullscreen: false,
}
},
methods: {
toggle () {
this.$refs['fullscreen'].toggle()
},
fullscreenChange (fullscreen) {
this.fullscreen = fullscreen
},
toggleFullscreen () {
this.$store.commit('toggleFullscreen');
},
},
created () {
//console.log('App created')
this.$store.watch(
(state) => {
return this.$store.state.fullscreen // could also put a Getter here
},
(newValue, oldValue)=>{
this.$refs['fullscreen'].toggle()
//something changed do something
console.log(oldValue)
console.log(newValue)
},
//Optional Deep if you need it
{
deep:true
}
)
}
};
</script>
And I want show "+" if fullscreen: false, "-" if fullscreen: true , but nothing work.
Quastion: How I can use fullscreen-vue with multiple bootstrap-vue modals?
Related
Am very new to vuejs.am trying to replicate the javascript with vue. where a user can toggle button. I have a list of buttons and I would like to toggle the active class but remove the active class from all other buttons.. Is there a better way of writtting the function without the querySelector? Am really stuck..
<template>
<div #click="selectItem" class="menu-tabs">
<button type="btn" class="menu-tab-item active" data-target="#remis-transfer"> Transfer
</button>
<button type="btn" class="menu-tab-item text-muted" data-target="#bank-transfer">
Transfer Money
</button>
<button type="btn" class="menu-tab-item text-muted" data-target="#fueling">
Fueling
</button>
</div>
</template>
<script>
export default {
methods: {
selectItem(e) {
if (e.target.classList.contains("menu-tab-item") && !e.target.classList.contains("active")) {
const target = e.target.getAttribute("data-target")
menuTabs.querySelector(".active").classList.remove("active");
e.target.classList.add("active");
const menuSection = document.querySelector(".menu-section");
menuSection.querySelector(".menu-tab-content.active").classList.remove("active");
menuSection.querySelector(target).classList.add('active');
}
}
}
}
</script>
Look at the code
var Main = {
data() {
return {
active: 0,
buttonList: [
{
text: "Transfer",
target: "#remis-transfer",
},
{
text: "Transfer Money",
target: "#bank-transfer",
},
{
text: "Fueling",
target: "#fueling",
},
],
};
},
methods: {
selectItem(i) {
this.active = i;
},
},
};
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.js"></script>
<div id="app">
<div class="menu-tabs">
<button
type="btn"
class="menu-tab-item"
v-for="(item, index) in buttonList"
:class="[{ active: active == index }, { 'text-muted': active != index }]"
:data-target="item.target"
:key="index"
#click="selectItem(index)"
>
{{ item.text }}
</button>
</div>
</div>
You can simply define some states like:
data() {
return {
myActiveClass: 'active',
myMutedClass: 'text-muted'
}
},
and pass this myActiveClass and myMutedClass states to your elements like this:
class=menu-tab-item ${myMutedClass} ${myActiveClass}
with this approach, you can quickly achieve what you want. So when you want an element to not be active, in your function you can make myActiveClass = '', or if you want the text to lose muted class you can say myMutedClass = '' .
Just make sure to play with states in the way you want.
I'm working with BootstrapVue. To my problem: I have a v-for in my template in which I have two buttons.
Looping over my v-for my v-if doesn't generate unique IDs and than after clicking one button each button will be triggered (from Open me! to Close me! and other way around).
How can I manage to get each button only triggers itself and doesn't affect the other?
I think I have to use my n of my v-for but I actually don't know how to bind this to a v-if..
Thanks in advance!
<template>
<div>
<div v-for="n in inputs" :key="n.id">
<b-button v-if="hide" #click="open()">Open me!</b-button>
<b-button v-if="!hide" #click="close()">Close me! </b-button>
</div>
<div>
<b-button #click="addInput">Add Input</b-button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
id: null,
inputs: [{
id: 0
}],
hide: true,
};
},
methods: {
open() {
this.hide = false
},
close() {
this.hide = true
},
addInput() {
this.inputs.push({
id: this.id += 1;
})
}
}
};
</script>
Everything seems to look fine. In order to handle each button triggers,
you can maintain an object like so:
<script>
export default {
data() {
return {
inputs: [{id: 0, visible: false}],
};
},
methods: {
open(index) {
this.inputs[index].visible = false
},
close(index) {
this.inputs[index].visible = true
},
addInput() {
this.inputs.push({id: this.inputs.length, visible: false});
}
}
};
</script>
and your template should be like
<template>
<div>
<div v-for="(val, index) in inputs" :key="val.id">
<b-button v-if="val.visible" #click="open(index)">Open me!</b-button>
<b-button v-if="!val.visible" #click="close(index)">Close me! </b-button>
</div>
</div>
</template>
Edit:
You don't need to insert an id every time you create a row, instead can use the key as id. Note that the inputs is an object and not array so that even if you want to delete a row, you can just pass the index and get it removed.
I would create an array of objects. Use a boolean as property to show or hide the clicked item.
var app = new Vue({
el: '#app',
data: {
buttons: []
},
created () {
this.createButtons()
this.addPropertyToButtons()
},
methods: {
createButtons() {
// Let's just create buttons with an id
for (var i = 0; i < 10; i++) {
this.buttons.push({id: i})
}
},
addPropertyToButtons() {
// This method add a new property to buttons AFTER its generated
this.buttons.forEach(button => button.show = true)
},
toggleButton(button) {
if (button.show) {
button.show = false
} else {
button.show = true
}
// We are changing the object after it's been loaded, so we need to update ourselves
app.$forceUpdate();
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<template>
<div>
<div v-for="button in buttons" :key="button.id">
<button v-if="button.show" #click="toggleButton(button)">Open me!</button>
<button v-if="!button.show" #click="toggleButton(button)">Close me! </button>
</div>
</div>
</template>
</div>
I'm using vue-awesome-swiper and I want to be able to show or hide the Next/Previous buttons on specific conditions.
Specifically, when the slide has reached the beginning, it should show the NEXT button, then when it reaches the end, it should hide that button and show the PREVIOUS button instead.
If possible, I would want it to be set as a variable that v-if can hook on. How do I go about doing that?
HTML
<div id="swiper">
<div class="menu-tabs-icon-label">
<swiper ref="productMenu" :options="swiperNavMenu">
<swiper-slide>
<div class="nav-item">
Item 1
</div>
</swiper-slide>
<swiper-slide>
<div class="nav-item">
Item 2
</div>
</swiper-slide>
<swiper-slide>
<div class="nav-item ">
Item 3
</div>
</swiper-slide>
<div v-if="reachedEnd" class="swiper-button-prev" slot="button-prev"></div>
<div v-if="reachedBeginning" class="swiper-button-next" slot="button-next"></div>
</swiper>
</div>
</div>
JS
new Vue({
el: "#swiper",
components: {
LocalSwiper: VueAwesomeSwiper.swiper,
LocalSlide: VueAwesomeSwiper.swiperSlide
},
data: {
swiperNavMenu: {
freeMode: true,
slidesPerView: 5.75,
on: {
reachBeginning: function() {
reachedBeginning = true;
},
reachEnd: function() {
reachedEnd = true;
}
}
}
},
computed: {
swiperA() {
return this.$refs.productMenu.swiper;
}
}
});
Your problem is related that reachedBeginning and reachedEnd variables are not defined
...
data() {
return {
reachedBeginning: false,
reachedEnd: false,
swiperNavMenu: {
freeMode: true,
slidesPerView: 5.75,
on: {
reachBeginning: ()=> {
this.reachedBeginning = true;
},
reachEnd: ()=> {
this.reachedEnd = true;
}
}
}
}
},
...
I found that the answer lies in binding the instance to the variable. The final code should look like this:
data() {
const self = this; // this is the line that fixes it all
return {
reachedEnd: false,
swiperNavMenu: {
on: {
reachEnd: function(){
self.reachedEnd=true
}
}
}
};
},
Still thanks to sugars for pointing the way.
I have been trying to show my modal but for some reason it keeps saying that the property isn't defined even though I have declared it in the Data()
I feel like I am missing something critical to my understanding on how this all works ...
The property is defined as false on load and should turn to true on click of the button.
<template>
<div class="product-item">
<h3>{{product.name}}</h3>
<p>{{product.tagline}}</p>
<img class="product-image" :src="product.image_url">
<p>PH: {{product.ph}}</p>
<button class="show-modal" #click="showModal = true">Show a tip</button>
<modal v-if="showModal" #close="showModal = false"></modal>
</div>
</template>
<script>
import Modal from "#/components/Modal.vue";
export default {
components: {
Modal
},
Data() {
showModal: false
},
props: {
product: {
type: Object
}
},
methods: {},
computed: {},
mounted() {}
};
</script>
You data Object should be returned via a function like :
data(){
return{
showModal: false
}
}
data should be in lowercase .
A component’s data option must be a function, so that each instance can maintain an independent copy of the returned data object:
data: function () {
return {
...
},
}
import Modal from "#/components/Modal.vue";
export default {
components: {
Modal
},
data: function () {
return {
showModal: false
},
}
props: {
product: {
type: Object
}
},
methods: {},
computed: {},
mounted() {}
};
<template>
<div class="product-item">
<h3>{{product.name}}</h3>
<p>{{product.tagline}}</p>
<img class="product-image" :src="product.image_url">
<p>PH: {{product.ph}}</p>
<button class="show-modal" #click="showModal = true">Show a tip</button>
<modal v-if="showModal" #close="showModal = false"></modal>
</div>
</template>
How do I open the first tab with VueJS? I have made two components but I don't know how to open the first tab automatically. This is what I've tried, but it doesn't work:
In mounted when i do console.log(this.tabs) return only 0 but before i do this.tabs = this.$children
Tabs.vue
<template>
<div>
<div class="tabs-header">
<ul>
<li v-for="tab in tabs" :key="tab.id" :class="{'is-active' : tab.isActive}">
<a :href="tab.href" #click="selectTab(tab)">{{ tab.name }}</a>
</li>
</ul>
</div>
<div class="content">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
name: "Tabs",
data: function(){
return { tabs: null };
},
created: function() {
this.tabs = this.$children;
//this.tabs[0].isActive = true;
},
methods: {
selectTab (selectedTab){
this.tabs.forEach(tab => {
tab.isActive = (tab.href == selectedTab.href);
});
}
}
}
</script>
This is my second components $children
Tab.vue
<template>
<div v-show="isActive">
<slot></slot>
</div>
</template>
<script>
export default {
name: "Tabs",
props: {
name: { require: true },
selected: { default: false }
},
data() {
return { isActive: false }
},
computed: {
href() {
return '#' + this.name.toLowerCase().replace(/ /g,'-');
}
},
mounted() {
this.isActive = this.selected;
},
methods: {
select(){
this.isActive = true;
}
}
}
</script>
This line doesn't work:
//this.tabs[0].isActive = true;
I copy pasted the code from laracasts.com/series/learn-vue-2-step-by-step/episodes/11 and the first tab is opened by default.
It is the case because in the html, you have :selected=true set on the first tab.
If you want to open the second tab by default, move :selected=true to the second tab, like this : https://jsfiddle.net/ahp3zzte/1/
If you want to change the default tab dynamically, remove :selected=true from the html and call the selectTab method in the js. Also note that to do this, you need to use mounted instead of created. Check this other fiddle : https://jsfiddle.net/0402y2ew/