It's been a while since using Vue JS and I am currently attempting to render a list of data with a button for each record. When the button is clicked, I would like to conditionally render a component ( in this instance).
Is there a Vue approved way of doing this? Should I be manipulating the DOM? The following doesn't seem to work.
<template>
<div v-for="data in list">
{{ data.bar}}
<button @click="handleClick">
<div v-if="dataset.loading === 'true'">
<loader/>
</div>
<div v-else>
</button>
</div>
</template>
<script setup>
import { loader } from './components'
const list = [{ foo: 'bar'}];
const handleClick = (el) => {
el.dataset.loading = 'true';
setTimeout(3, () => el.dataset.loading = 'false');
};
</script>
CodePudding user response:
You need to use ref
on your list
variable to make it reactive. Also, you are accessing a dataset
variable which doesn't exists in your application.
This is one way of doing it, I just added an extra data on your list
<script setup>
import {ref} from 'vue'
let list = ref([{ foo: 'bar', loading: 'true'}]);
const handleClick = (data) => {
setTimeout(() => {
data.loading = 'false'
},1000);
};
</script>
<template>
<div v-for="data in list" >
{{ data.foo}}
<button @click="handleClick(data)"> //you can also use a `ref` here.
<div v-if="data.loading === 'true'">
Your Loader Component
</div>
<div v-else>
Something else...
</div>
</button>
</div>
</template>
You can also use Template Refs
CodePudding user response:
Observation :
- There is no object with
bar
key in thelist
array. Usedata.foo
instead ofdata.bar
.
Suggestions :
It is recommended to provide a
:key
withv-for
whenever possible.Add
loading
property in each object of the list array. So that it will behave dynamically while setting the valueonClick
.
Live Demo :
new Vue({
el: '#app',
data: {
list: [{ foo: 'bar', loading: false }]
},
methods: {
handleClick(dataIndex) {
this.list[dataIndex].loading = true;
setTimeout(() => {
this.list[dataIndex].loading = false;
}, 2000);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="(data, index) in list" :key="index">
{{ data.bar }}
<button @click="handleClick(index)">
<div v-if="data.loading">
Loading Start
</div>
<div v-else> Loading Finish </div>
</button>
</div>
</div>