Как можно изменить анимацию, чтобы при нажатии на кнопку оба элемента массива перемещались одновременно, а не только левый элемент? Пример кода можно найти <a href="https://codepen.io/DazzRune/pen/LYwVOvm" rel="nofollow">здесь</a>. В текущей реализации используется следующий код: <br/> <pre><code class="html"><template>
<div
v-for="(item, index) in data"
:key="item.id"
class="block"
:style="`left: ${80 * index}px; top: 0px`"
>
{{ item.id }}
</div>
<button @click="swap" style="position: absolute; top: 80px;">SWAP</button>
</template></code></pre> <br/> <pre><code class="javascript"><script setup>
import { ref } from 'vue'
const data = ref([{ id: 0 }, { id: 1 }])
function swap() {
;[data.value[0], data.value[1]] = [data.value[1], data.value[0]]
}
</script></code></pre> <br/> <pre><code class="css"><style>
.block {
transition: left ease-out 1s;
position: absolute;
width: 80px;
height: 80px;
border: 1px solid black;
}
</style></code></pre>
Ваш код использует `absolute` позиционирование для элементов, и это может вызывать проблемы с анимацией перехода, так как элементы фактически перемещаются одна за другой, а не одновременно. Кроме того, Vue не отслеживает изменения в свойствах `style`, применяемых к элементам с помощью атрибутов, таких как `left`, что также может привести к некорректному отображению анимации.
Чтобы сделать так, чтобы оба элемента перемещались одновременно при нажатии на кнопку, можно изменить подход к позиционированию, например, использовать CSS Grid или Flexbox. Вот один из способов, как можно это реализовать:
1. Измените стиль на использование Flexbox.
2. Добавьте анимацию смены местами для всех элементов сразу.
Вот обновлённый код:
### HTML
```html
<template>
<div class="container">
<div
v-for="(item, index) in data"
:key="item.id"
class="block"
>
{{ item.id }}
</div>
</div>
<button @click="swap" style="margin-top: 20px;">SWAP</button>
</template>
```
### JavaScript
```javascript
<script setup>
import { ref } from 'vue'
const data = ref([{ id: 0 }, { id: 1 }])
function swap() {
;[data.value[0], data.value[1]] = [data.value[1], data.value[0]]
}
</script>
```
### CSS
```css
<style>
.container {
display: flex;
position: relative;
}
.block {
transition: all ease-out 1s; /* Меняем left на all, чтобы анимация срабатывала на изменение всех свойств */
width: 80px;
height: 80px;
border: 1px solid black;
margin-right: 10px; /* Немного пространства между блоками */
}
</style>
```
### Объяснение:
1. **Flexbox**: Контейнер теперь использует `display: flex`, что позволяет двум элементам располагаться в одну строку.
2. **Анимация**: Мы изменили свойство `transition` на `all`, что позволит анимации сработать для любого изменения (в данном случае, изменения порядка).
Теперь при нажатии на кнопку элементы будут перемещаться полностью вместе, без задержек. Вы можете попробовать это решение в вашем проекте!
У тебя блоки перерисовываются, поэтому у левого всегда left: 0 и анимации нет <br/> Надо либо, добавить элементам параметр позиции: <br/> <pre><code class="javascript">const data = ref([{ id: 0, pos: 0 }, { id: 1, pos: 1 }])</code></pre> <br/> задавать left относительно позиции: <br/> <code>:style="`left: ${80 * item.pos}px; top: 0px`"</code> <br/> ну и менять тогда так: <br/> <pre><code class="javascript">function swap() {
data.value.forEach(el => {
el.pos = el.pos === 1 ? 0 : 1
})
}</code></pre> <br/> <br/> Либо, лучше для этого лучше использовать <a href="https://codepen.io/adrianparr/pen/LYGOZJG" rel="nofollow">transition-group</a>