Draggable in Vue 3 won't display value - vue.js

I am using Vue draggable to sort items from my Store.js by drag and drop (I've simplified my example here using only ['a', 'b', 'c'] as my store data).
I am also using a computed property made accessible from the setup()
<draggable v-model="myList" item-key="id" #start="drag=true" #end="drag=false" >
<template #item="{card}">
<p>{{ card }}</p>
</template>
</draggable>
import draggable from 'vuedraggable';
export default {
name: "Dashboard",
components: {
draggable
},
setup() {
const cards = computed(() => {
return ['a', 'b', 'c']
})
return {
cards
}
}
}
I know the template iterates through cards but no value is displayed or is neither accessible.

In Vue 3 - When setup is executed, the component instance has not been created yet. As a result, you will not have access to data, computed, methods component options.
Reference:
https://v3.vuejs.org/guide/composition-api-setup.html#accessing-component-properties
Also in Draggable component, the array item will be accessed by element variable.
Updated template code:
<draggable v-model="myList" item-key="id" #start="drag=true" #end="drag=false" >
<template #item="{element}">
<p>{{ element.value }}</p>
</template>
</draggable>
Try changing the component code as follows,
import draggable from 'vuedraggable';
export default {
name: "Dashboard",
components: {
draggable
},
data:function(){
return {
drag:false
}
},
computed:{
myList:function(){
return [{id:1,value:'Card A'},{id:2, value:'Card B'}];
}
}
}

yarn add vue-draggable-next
<draggable class="w-full mt-5 dragArea list-group" :list="list" #change="log">
<div
class="max-w-md p-2 mb-5 border cursor-pointer list-styles"
v-for="element in list"
:key="element.name"
>
{{ element.name }}
</div>
</draggable>
</template>
<script>
import { defineComponent } from "vue";
import { VueDraggableNext } from "vue-draggable-next";
export default defineComponent({
components: {
draggable: VueDraggableNext,
},
data() {
return {
enabled: true,
list: [
{ name: "Medical science", id: 1 },
{ name: "Allied Medicine", id: 2 },
{ name: "Defense Service", id: 3 },
{ name: "Education training", id: 4 },
{ name: "Economics & Commerce", id: 5 },
{ name: "Banking & Finance", id: 6 },
{ name: "Enginnering", id: 7 },
{ name: "science", id: 8 },
],
dragging: false,
};
},
methods: {
log(event) {
console.log(event);
},
},
});
</script>

Related

How can I show a different value apart from the dropdown options in v-select in vue 2 js

Well the scenario is when the selectedFruits is having some element then I need to show "Fruits Selected" and If there is no fruit selected it should display "Select Fruits" in the select. Below is my template and the data I am using. So basically it won't show the fruits selected but display the messages mentioned above in the v-select dropdown. I am new to the vue js, so wondering whether this is possible or not? or is there any alternate way to achieve the same scenario.
<template>
<div>
<v-select
v-model="selectedFruits"
:items="fruits"
label="name"
multiple
/>
</div>
</template>
<script>
export default {
data() {
return {
fruits: [
{ name: 'Apple' },
{ name: 'Mango' },
{ name: 'Banana' },
{ name: 'Berries' },
{ name: 'Muskmelon' }
],
selectedFruits: []
}
}
}
</script>
Well, I found that there is an option called selection which we can use with v-slot through which I am able to achieve the desired result. Below is the changes I made in my code:
<template>
<div>
<v-select
v-model="selectedFruits"
:items="fruits"
label="Select Fruits"
multiple
>
<template v-slot:selection="{ item, index }">
<span v-if="index === 0">{{
item && "Fruits Selected"
}}</span>
</template>
</v-select>
</div>
</template>
<script>
export default {
data() {
return {
fruits: [
{ name: 'Apple' },
{ name: 'Mango' },
{ name: 'Banana' },
{ name: 'Berries' },
{ name: 'Muskmelon' }
],
selectedFruits: []
}
}
}
</script>

Cannot pass an object to a new route using props

I am working on a project where a user fills in a quiz and the results need to be passed to a new page. The quiz has the Quiz component, where the quiz is taken, and the QuizFinished component, where the user can go to the Results page. I have been able to pass the quiz answers to QuizFinished, but the problem lies in passing the answers from QuizFinished to QuizResults. I have copied some code from here which is from this stackoverflow question, but the code does not work.
Am I missing something here?
Any help would be much appreciated.
Quiz.vue
<template>
<div class="quiz-background py-5" id="mood-finder">
<b-container class="text-center">
<h1 class="">Mood finder</h1>
<component
<!-- This event is triggered when a question is answered in Question.vue, that works -->
v-on:click="_answerQuestion($event)"
<!-- Going from the startpage to the quiz -->
v-on:start="this.startQuiz"
v-bind:is="component"
<!-- Binds the answers to be read in QuizResult -->
:answers="answers"
ref="question"
/>
<b-row class="d-flex justify-content-center">
<b-col cols="12" md="8" class="pt-3">
<!-- A progress bar -->
<b-progress
variant="primary"
aria-label="Voortgang van de Moodfinder"
:value="progress"
:max="maxProgress"
></b-progress>
</b-col>
</b-row>
</b-container>
</div>
</template>
<script>
import quizStart from "./QuizStart.vue";
import question from "./Question";
import strawberry from "../assets/strawberry.webp";
import banana from "../assets/banana.webp";
import quizFinished from "./QuizFinished.vue";
export default {
name: "app",
components: {
quizStart,
question,
quizFinished,
},
data() {
return {
questionIndex: 0,
<!--The array with the answers. It is put in an object to circumvent the array limitation by Vue: https://github.com/vuejs/vue/issues/1798 -->
answers: {array: []},
component: "quizStart",
strawberry: strawberry,
banana: banana,
progress: 0,
maxProgress: 99,
};
},
methods: {
/**
* #description
* saved pressed answer text in answers array
*/
_answerQuestion(chosenItem) {
this.answers.array.push(chosenItem);
this.switchQuestion();
},
startQuiz(){
this.component= "question"
},
/**
* #description switches the questions when the user performs an action in the quiz
* it swaps out the quiz images, text and quiz question for each question.
*/
switchQuestion() {
/**
* questionIndex stands for the question the user would like to go to.
* So e.g questionIndex = 1 is going to the second question (counting from 0)
*/
this.questionIndex++;
switch (this.questionIndex) {
case 0:
this.progress = 0;
break;
// //For question 1, see Question.Vue data field
case 1:
this.$refs.question.setQuestion("Question 2");
this.$refs.question.setItems(
{ name: "strawberry", variety: "sweet" },
{ name: "strawberry", variety: "sweet" },
{ name: "strawberry", variety: "sweet" },
{ name: "strawberry", variety: "sweet" }
);
this.$refs.question.setImage(
this.strawberry,
this.strawberry,
this.strawberry,
this.strawberry
);
this.progress = 33;
break;
case 2:
console.log(this.questionIndex)
this.$refs.question.setQuestion("Question 3");
this.$refs.question.setItems(
{ name: "banana", variety: "sweet" },
{ name: "banana", variety: "sweet" },
{ name: "banana", variety: "sweet" },
{ name: "banana", variety: "sweet" }
);
this.$refs.question.setImage(
this.banana,
this.banana,
this.banana,
this.banana
);
this.progress = 66;
break;
case 3:
this.progress = 99;
//Goes to the quizFinished component
this.component = quizFinished;
}
},
},
};
</script>
//removed the styles
QuizFinished.vue:
<template>
<b-row class="d-flex justify-content-center py-3">
<b-col class="col-6 col-lg-2">
<p class="text-white">
De Mood finder is gemaakt. Je resultaten staan klaar!
</p>
<!-- <router-link :to="{ path: '/results/', params: { answers: answers } }"
><button class="btn btn-primary" type="button">
Verder naar resultaten
</button></router-link
> -->
<br />
<router-link :to="{ name: 'results', params: { params: answers} }"
>Go to results</router-link>
<!-- For testing purposes, the answers are shown here as: { "array": [{object1} etc.]} -->
{{ answers }}
</b-col>
</b-row>
</template>
<script>
export default {
name: "quizFinished",
props: {
//For reasoning behind type: Object, see previous codeblock
answers: { type: Object, required: false },
},
};
</script>
//removed styles
QuizResult.vue
<!-- Html here -->
<script>
export default {
props: {
params: { type: Object, required: false },
},
mounted() {
//returns undefined, adding a html object like this: {{params}} returns nothing
console.log(this.params);
}
};
</script>
//removed styles
main.js:
import Vue from 'vue';
import App from './App.vue';
import VueRouter from 'vue-router';
import './registerServiceWorker';
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue';
import 'bootstrap-vue/dist/bootstrap-vue.css';
import '../src/scss/bootstrap.css';
// Import for fontAwesome : svg-core, brand icons and vue
import { library } from '#fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome';
import { fab } from '#fortawesome/free-brands-svg-icons';
import VueMeta from 'vue-meta';
library.add(fab);
// fontawesome component neccesary to call
Vue.component('font-awesome-icon', FontAwesomeIcon, fab);
// Make BootstrapVue available throughout your project
Vue.component('font-awesome-icon', FontAwesomeIcon, fab);
Vue.use(BootstrapVue);
Vue.use(IconsPlugin);
Vue.use(VueRouter);
Vue.use(VueMeta);
import results from './components/pages/Results';
import index from './components/pages/Index';
import pageNotFound from './components/pages/PageNotFound';
import webshop from './components/pages/Webshop';
const resultsRoute = { path: '/results', name: 'results', component: results, props: true, };
const indexRoute = { path: '/', name: 'index', component: index };
const pageNotFoundRoute = { path: '*', name: 'pageNotFound', component: pageNotFound };
const webshopRoute = { path: '/webshop', name: 'webshop', component: webshop };
const routes = [resultsRoute, indexRoute, pageNotFoundRoute, webshopRoute];
const router = new VueRouter({
routes,
mode: 'history',
});
Vue.config.productionTip = false;
new Vue({
router,
render: function(h) {
return h(App);
},
}).$mount('#app');
Here's a very quick snippet to show quiz using VueRouter:
const QuizStart = {
template: `
<div><router-link :to="'/question/0'">START</router-link></div>
`
}
const QuizQuestion = {
props: ['qidx', 'questions'],
computed: {
question() {
return this.questions[this.qidx]
},
},
methods: {
setAnswer(val) {
this.$emit('set-answer', {
id: this.qidx,
answer: val
})
let next = ''
if (Number(this.qidx) < this.questions.length - 1) {
next = `/question/${ Number(this.qidx) + 1 }`
} else {
next = '/result'
}
this.$router.push(next)
},
},
template: `
<div>
{{ question.text }}:<br />
<button #click="() => setAnswer(1)">YES</button> | <button #click="() => setAnswer(-1)">NO</button>
</div>
`
}
const QuizResult = {
props: ['questions'],
computed: {
computedResult() {
return this.questions.reduce((a, c) => a + c.answer, 0)
}
},
template: `
<div>
Your score is {{ computedResult }}
</div>
`
}
const routes = [{
path: '/',
component: QuizStart
},
{
path: '/question/:qidx',
component: QuizQuestion,
props: true
},
{
path: '/result',
component: QuizResult
},
]
const router = new VueRouter({
routes // short for `routes: routes`
})
new Vue({
el: "#app",
components: {
QuizStart,
QuizQuestion,
QuizResult,
},
router,
data() {
return {
questions: [{
text: 'Is this the first question?',
answer: null,
},
{
text: 'Is this the second question?',
answer: null,
},
{
text: 'Is this the third question?',
answer: null,
},
],
}
},
methods: {
setAnswer({
id,
answer
}) {
this.questions[id].answer = answer
},
},
template: `
<div>
<div>
QUESTIONS STATE: {{ questions }}
</div>
<hr />
<router-view
:questions="questions"
#set-answer="(data) => setAnswer(data)"
></router-view>
</div>
`
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app"></div>
You can see that
the whole quiz state is tracked in one place: the question components do nothing but display the question and emit the answer back to the parent to update the state;
the questions are passed down from the parent; the route param (:qidx) is used to choose which question to display;
when the last question is reached, the next step is automatically the result page; but, because ALL the pages in the router-view receive the state of the questions, it's easy to calculate a result based on any calculation rule you might need.
I hope this helps you in a "smooth quiz-flow" :)
What I ended up doing is pushing to the router directly like this:
In the button:
v-on:click="toResults()"
And in methods:
toResults() {
this.$router.push({
name: "resultsRoute",
params: {
items: this.answers,
}
I was then able to get the items on the other side like this:
vm.$route.params.items

Add or removing a class to a element in a child component

I've recently hit a wall with vue. Currently we three components Parent.vue ChildOne.vue and ChildTwo.vue. Parent Passes some object data (from a state) to the ChildOne component.
The ChildOnecomponent has the ChildTwo component as a custom element. On that custom element <ChildTwo></ChildTwo> we have a v-for loop that loops through the data and the ChildTwo component is just for html formatting the data.
What I want to is on a click add a custom class .selected to a div and remove it from the other div if selected, much like my example here.
https://codepen.io/david-wh/pen/gOrzQVR
Here is a sandbox of the full app I'm using:
https://codesandbox.io/s/onclick-forked-tkkre
Parent
<template>
<div>
<ChildOne :container-slot-data="ObjectData"></ChildOne>
</div>
</template>
<script>
import ChildOne from "./childComponentOne.vue";
export default {
name: "HelloWorld",
components: {
ChildOne
},
data() {
return {
ObjectData: [
{
id: "1",
name: "foo",
type: "aug",
subType: "1"
},
{
id: "2",
name: "bar",
type: "aug",
subType: "2"
},
{
id: "3",
name: "foobar",
type: "gear",
subType: "6"
}
]
};
}
};
</script>
ChildOne
<template>
<div class="Testing">
<ChildTwo v-for="(itemData, index) in containerSlotData" :key="index" :item-data="itemData"></ChildTwo>
</div>
</template>
<script>
import ChildTwo from "./childComponentTwo.vue";
export default {
name: "ChildOne",
components: {
ChildTwo
},
data() {
return {
current: null
};
},
props: {
containerSlotData: {
type: Array,
default: null
}
}
};
</script>
ChildTwo
<template>
<!-- <div class="selected"> -->
<div>
<ul>
<li>{{ itemData.id }}</li>
<li>{{ itemData.name }}</li>
<li>{{ itemData.subType }}</li>
</ul>
<hr>
</div>
</template>
<script>
export default {
name: "Childtwo",
data() {
return { current: null };
},
props: {
itemData: {
type: Object,
default: null
}
}
};
</script>
If all you want to do is to toggle the class on the elements, I suggest:
In ChildOne add a selectedItem to data and set it with #click handler.
In ChildTwo add a #click hanlder that will emit click event to the ChildOne compontent.
You can see a working example forked from your CodeSandbox here
I have added font-weight: bold to the .selected class to make it visible.

Is possible to generate vue component using for loop inside function?

Is possible to generate vue component using for loop. I am trying to generate and able to get but it's override by new component dynamically it's override component one schema also with component second with is at last generated.
https://jsfiddle.net/3ordn7sj/5/
https://jsfiddle.net/bt5dhqtf/973/
for (var key in app.html) {
Vue.component(key, {
template: `<div><vue-form-generator :model="model"
:schema="schema"
:options="formOptions"
ref="key"></vue-form-generator>{{ key }}</div>`,
mounted() {
this.schema = app.html[key]
},
data: function () {
return {
schema: app.html[key],
key: '',
formOptions: this.formOptions,
model: this.model,
}
},
}
)
}
Is possible to generate vue component using for loop. I am trying to generate and able to get but it's override by new component dynamically it's override component one schema also with component second with is at last generated. In above jsfiddel link my data is there inside created.
I am trying to generate vue component base on this data and I am using vue form generator.In above code what exactly I am trying to do is while my loop running form generated but I don't know how it's first component also getting second component schema and it;s showing on first step also overrides schema data.
I am very confused why this is happening I tried a lot but I am not getting any solution if you have please suggest what I can do for generate component using for loop inside function.
Please try to solve this issue or tell me id it;s not possible.
I did like this
<form-wizard #on-complete="onComplete"
#on-change="handleChange"
validate-on-back
ref="wizard"
:start-index.sync="activeTabIndex"
shape="circle" color="#20a0ff" error-color="#ff4949" v-if="html != 0">
<tab-content v-for="tab in tabs"
v-if="!tab.hide"
:key="tab.title"
:title="tab.title"
:icon="tab.icon">
<component :is="tab.component"></component>
</tab-content>
</form-wizard>
Inside Data I have added for now this tabs option
tabs: [{title: 'Personal details', icon: 'ti-user', component: 'firstTabSchema'},
{title: 'Is Logged In?', icon: 'ti-settings', component: 'secondTabSchema', hide: false},
],
generateNewForm.vue
<template>
<div class="app animated fadeIn">
<loading :active.sync="this.$store.state.isLoading"
:can-cancel="true"
:is-full-page="this.$store.state.fullPage"></loading>
<b-row>
<b-col cols="12" xl="12">
<transition name="slide">
<b-card>
<div slot="header">
<b-button variant="primary" #click="goBack"><i class="icon-arrow-left icons font-1xl"></i>Back</b-button>
</div>
<formcomponent :tree="this.$store.state.formData" />
</b-card>
</transition>
</b-col>
</b-row>
</div>
</template>
<script>
import {store} from '#/components/store'
import formcomponent from '#/components/formcomponent';
import Vue from 'vue'
import Loading from 'vue-loading-overlay';
import 'vue-loading-overlay/dist/vue-loading.css';
import {FormWizard, TabContent} from 'vue-form-wizard'
import 'vue-form-wizard/dist/vue-form-wizard.min.css'
import VueFormGenerator from "vue-form-generator";
/*import VeeValidate from 'vee-validate';*/
Vue.use(VueFormGenerator);
Vue.use(Loading);
export default {
name: 'tables',
store: store,
data: () => {
return {
finalModel: {},
activeTabIndex: 0,
model: {},
count: 0,
}
},
components: {
'loading': Loading,
FormWizard,
TabContent,
formcomponent: formcomponent
},
created() {
},
beforeMount() {
this.$store.dispatch('loadFormData', this.$route.params.id);
},
methods: {
onComplete: function(){
alert('Yay. Done!');
},
goBack() {
this.$router.go(-1)
}
}
}
</script>
formcomponent.vue
<template>
<div>
<form-wizard #on-complete="onComplete"
#on-change="handleChange"
validate-on-back
ref="wizard"
:start-index.sync="activeTabIndex"
shape="circle" color="#20a0ff" error-color="#ff4949" v-if="html != 0">
<tab-content v-for="tab in tabs"
v-if="!tab.hide"
:key="tab.title"
:title="tab.title"
:icon="tab.icon">
<component :is="tab.component"></component>
</tab-content>
</form-wizard>
</div>
</template>
<script>
import Vue from 'vue'
import {FormWizard, TabContent} from 'vue-form-wizard'
import 'vue-form-wizard/dist/vue-form-wizard.min.css'
import VueFormGenerator from "vue-form-generator";
//console.log(Vue.options);
Vue.use(VueFormGenerator);
export default {
components: {
FormWizard,
TabContent,
},
data() {
return {
loadingWizard: false,
error: null,
count: 0,
dash: '-',
firstTime: 0,
model: {},
html: '',
index: '',
activeTabIndex: 0,
tabs: [{title: 'Personal details', icon: 'ti-user', component: 'firstTabSchema'},
{title: 'Is Logged In?', icon: 'ti-settings', component: 'secondTabSchema', hide: false},
],
formOptions: {
validationErrorClass: "has-error",
validationSuccessClass: "has-success",
validateAfterLoad: true,
validateAfterChanged: true,
},
}
},
created() {
this.html = this.tree;
this.index = this.ind;
},
props: ['tree', 'ind'],
methods: {
onComplete: function () {
alert('Yay. Done!');
},
setLoading(value) {
this.loadingWizard = value
},
handleChange(prevIndex, nextIndex) {
console.log(`Changing from ${prevIndex} to ${nextIndex}`)
},
setError(error) {
this.error = error
},
validateFunction: function () {
return new Promise((resolve, reject) => {
console.log(this.$refs.firstTabSchema);
setTimeout(() => {
if (this.count % 2 === 0) {
reject('Some custom error')
} else {
resolve(true)
}
this.count++
}, 100)
})
},
validate() {
return true
},
buildTree(tree, rep = 1) {
var html = '';
var app = this;
var dash = "--";
app.html = tree;
var test = this.formOptions;
for (var key in app.html) {
var isComponentExists = key in Vue.options.components
if(!isComponentExists) {
Vue.component(key, {
template: `<div :class="key"><vue-form-generator :model="model"
:schema="schema"
:options="formOptions"
ref="key"></vue-form-generator>{{ key }}</div>`,
mounted() {
this.schema = app.html[key]
this.key = key
},
data: function () {
return {
schema: app.html[key],
key: '',
formOptions: this.formOptions,
model: this.model,
}
},
}
)
//console.log(Vue.$options);
this.$emit('init')
}
}
}
},
watch: {
tree: {
handler() {
this.html = '';
this.buildTree(this.tree)
},
deep: true
}
}
}
</script>
So if I understand you correctly you are trying to use a list of some kind app.html to dynamically register a set of identical components under different names (key). I think it is possible, but i cannot tell from the code you provided what is going wrong.
I can tell you that this approach to code reuse/abstraction is probably not the right way to go. The whole point of components is that you can reuse functionality with the use of binding props. What you are trying to do is probably better achieved like this:
Vue.component('my-custom-form', {
props: ['key', 'schema', 'formOptions', 'model'],
template: `
<div>
<vue-form-generator
:model="model"
:schema="schema"
:options="formOptions"
:ref="key"
></vue-form-generator>{{ key }}
</div>`,
})
Then in your vue template:
<my-custom-form
v-for="(key, value) in app.html"
:key="key"
:schema="value"
:formOptions="formOptions"
:model="model"
/>
Let me know if that helps. Otherwise, if you are sure you want to stick with your original approach give me some more context for the code and I will see what i can do. Best of luck!
I think i understand a little bit better where you are getting stuck. I see this piece of code in your jsfiddle:
<div id="app">
<div>
<form-wizard #on-complete="onComplete">
<tab-content v-for="tab in tabs"
v-if="!tab.hide"
:key="tab.title"
:title="tab.title"
:icon="tab.icon">
<component :is="tab.component"></component>
</tab-content>
</form-wizard>
</div>
</div>
You don't need to use the component :is syntax to solve this problem. You could also write is as follows:
<div id="app">
<div>
<form-wizard #on-complete="onComplete">
<tab-content v-for="(tab, tabindex) in tabs"
v-if="!tab.hide"
:key="tab.title"
:title="tab.title"
:icon="tab.icon">
<my-custom-form v-if="tabindex == 1" :key="'the first key'" :schema="app.html['the first key']"/>
<my-custom-form v-else-if="tabindex == 2" :key="'the second key'" :schema="app.html['the second key']"/>
</tab-content>
</form-wizard>
</div>
</div>
etc. Let me know if that example is clear.
best

Hiding a pargraph using v-if through vuex but containing that in a specific tab

I have an array in My store which i am looping through to get a list which will be their own pages and share a same paragraph. I have a button which hides the paragraph. How do i make it so that it hides only on the first page and not on the other pages? So the way it should work is that if hide the paragraph in the Apple page, it should still appear on the other four pages.Or for the matter, if i hide the paragraph on any of the pages, it should not affect on any other page. Thank You
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
show:true,
specialTypes:[
{
name: "Apple",
Id:1
},
{
name: "Banana",
Id:2
},
{
name: "Berries",
Id:3
},
{
name: "Mango",
Id:4
},
{
name: "Oranges",
Id:5
}
]
},
mutations: {
toggle : state => {
state.show = !state.show
}
},
actions: {
}
})
My app.vue file looks like this
<template>
<div>
<ul >
<li v-for="specialType in $store.state.specialTypes"
:key="specialType.specialTypeId" #click="setActiveType(specialType)"
:class="{'active': activeType === specialType}">
<a><span>{{ specialType.name }}</span></a>
</li>
</ul>
<router-view/>
<Home></Home>
<About></About>
</div>
</template>
<script>
import Home from "./views/Home"
import About from "./views/About"
export default {
components:{
Home,
About
},
data(){
return{
activeType:""
}
},
methods:{
setActiveType(type) {
this.activeType = type
}
}
}
</script>
This is the paragraph which is shared by each tab.
<template>
<p v-if="$store.state.show">This needs to disappear</p>
</template>
<script>
import {mapMutations} from "vuex"
export default {
data(){
return{
}
},
methods : {
...mapMutations ([
"toggle"
])
}
}
</script>
The button is on this file
<template>
<div>
<button #click="toggle">Click Me</button>
</div>
</template>
<script>
import {mapMutations} from "vuex"
export default {
methods : {
...mapMutations ([
"toggle"
])
}
}
</script>
In your code, you are comparing objects here.
:class="{'active': activeType === specialType}"
Javascript doesn't work like this.
Replace above line with.
:class="{'active': activeType.Id === specialType.Id}"
Example:
var jangoFett = {
occupation: "Bounty Hunter",
genetics: "superb"
};
var bobaFett = {
occupation: "Bounty Hunter",
genetics: "superb"
};
console.log(bobaFett === jangoFett); // Outputs: false
The properties of bobaFett and jangoFett are identical, yet the objects themselves aren't considered equal.
I hope that helps.