store.dispatch('config/loadMain').then(() => {
new Vue({
...
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
<div id="app" @dragover.prevent="">
<button v-if="done" @click="init">ещё раз</button>
<div v-else>
<div class="questions">
<div
v-for="n in questions"
:class="[ 'card', { hidden: n.done } ]"
draggable="true"
@dragstart="onDragStart($event, n)"
>{{ n.question }}</div>
</div>
<div class="answers">
<div
v-for="n in answers"
:class="[ 'card', { hidden: n.done } ]"
@drop="onDrop(n)"
>{{ n.answer }}</div>
</div>
</div>
</div>
$side: 75px;
.questions,
.answers {
width: $side * 3;
height: $side * 3;
margin: 10px;
display: inline-block;
}
.card {
display: inline-flex;
justify-content: center;
align-items: center;
border: 1px solid silver;
box-sizing: border-box;
width: $side;
height: $side;
background: red;
color: white;
font-weight: bold;
font-family: monospace;
}
.hidden {
visibility: hidden;
}
new Vue({
el: '#app',
data: () => ({
dragged: null,
items: [
{ question: '2 x 2', answer: 4 },
{ question: '5 x 6', answer: 30 },
{ question: '7 x 7', answer: 49 },
{ question: '8 x 4', answer: 32 },
{ question: '7 x 5', answer: 35 },
{ question: '6 x 9', answer: 54 },
{ question: '9 x 8', answer: 72 },
{ question: '6 x 8', answer: 48 },
{ question: '9 x 7', answer: 63 },
].map(n => (n.done = false, n)),
questions: [],
answers: [],
}),
computed: {
done() {
return this.items.every(n => n.done);
},
},
methods: {
onDragStart(e, item) {
this.dragged = item;
},
onDrop(item) {
if (item === this.dragged) {
item.done = true;
} else {
alert('Ты дурак, да?');
}
},
init() {
const { items } = this;
items.forEach(n => n.done = false);
this.questions = [...this.items].sort(() => 0.5 - Math.random());
this.answers = [...this.items].sort(() => 0.5 - Math.random());
},
},
created() {
this.init();
document.addEventListener('dragend', () => this.dragged = null);
},
});
h1 {
font-size: var(--h1-font-size);
}
<input v-model="fontSize" type="range">
<h1>hello, world!!</h1>
data: () => ({
fontSize: 24,
}),
mounted() {
this.$watch(
'fontSize',
val => this.$el.style.setProperty('--h1-font-size', `${val}px`),
{ immediate: true }
);
},
computed: mapState({
products: state => state.product.all.map(n => ({
...n,
isOrdered: state.order.all.some(m => m.id === n.id),
})),
}),
<b-button :disabled="product.isOrdered"
.<div v-if="product.isOrdered"
.computed: {
isOrdered() {
return Object.fromEntries(this.$store.state.order.all.map(n => [ n.id, true ]));
},
},
product.isOrdered
из предыдущего варианта, будет isOrdered[product.id]
.v-model
.props: {
value: Number,
...
computed: {
item() {
return this.items[this.value];
},
...
<transition name="slide-fade" mode="out-in">
<div class="content" :key="value">
<h2>{{ item.title }}</h2>
<p>{{ item.text }}</p>
</div>
</transition>
methods: {
next(change) {
const len = this.items.length;
this.$emit('input', (this.value + change + len) % len);
},
...
<button @click="next(-1)">Prev</button>
<button @click="next(+1)">Next</button>
data: () => ({
active: 1,
...
<v-slider
v-model="active"
...
data: () => ({
items: [ 'hello, world!!', 'fuck the world', 'fuck everything' ],
focused: null,
}),
<div v-for="(n, i) in items">
<input @focus="focused = i" @blur="focused = null">
<span v-show="focused === i" v-text="n"></span>
</div>
('#app') new Vue({ router, store, render: h => h(App) }).$mount