0๐
โ
I would suggest to use refs
and save Promise resolve
function until user clicks button
methods: {
onClick() {
this.resolve();
},
handleClick() {
const popupRef = this.$refs.popupRef;
const classList = popupRef.classList;
return new Promise(resolve => {
classList.toggle("show");
this.resolve = resolve;
})
.then(() => {
classList .toggle("show");
})
})
},
Example
Vue.config.devtools = false;
Vue.config.productionTip = false;
Vue.component("child-component", {
props: {
text: String,
response: String,
clicked: Boolean
},
template: `<div class="instruction">
<div>{{text}}</div>
<span ref="popupRef" class="popup">Click it!</span>
<button v-if="!clicked" @click="onClick">Ok Done!</button>
<div v-if="clicked">{{response}}</div>
</div>`,
methods: {
onClick() {
this.resolve();
},
handleClick() {
const popupRef = this.$refs.popupRef;
const classList = popupRef.classList;
return new Promise(resolve => {
classList.toggle("show");
this.resolve = resolve;
})
.then(() => {
classList.toggle("show");
})
},
}
})
new Vue({
el: '#container',
data() {
return {
text: 'Show Instructions',
disabled: false,
instructions: [{
id: 1,
text: 'Eat something!',
response: 'Nice!',
clicked: false
},
{
id: 2,
text: 'Work',
response: 'Wow!',
clicked: false
}
]
}
},
methods: {
async showInstructions() {
this.disabled = true;
this.text = "Showing instructions...";
const combined = this.instructions.map((obj, index) => [
obj,
this.$refs.instructions[index]
]);
for (let [instruction, ref] of combined) {
await ref.handleClick();
this.$set(instruction, 'clicked', true);
}
this.text = 'Processing...';
setTimeout(() => {
this.disabled = false;
this.text = 'Show Instructions';
this.instructions = this.instructions.map(instruction => ({
...instruction,
clicked: false
}))
}, 500);
}
}
});
.instruction {
border: 1px solid black;
padding: 10px;
}
.popup {
position: absolute;
opacity: 0;
padding: 10px;
background: black;
color: white;
margin-top: -10px;
margin-left: 90px;
}
.popup.show {
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="container">
<child-component ref="instructions" :key="item.id" v-bind="item" v-for="item in instructions"></child-component>
<button :disabled="disabled" @click="showInstructions">{{text}}</button>
</div>
Source:stackexchange.com