Для интеграции Interact.js в проект на Vue.js можно использовать стандартный подход через npm:
npm install interactjs
После установки библиотеку импортируют в компонент или основной файл:
import interact from 'interactjs';
В случае глобального использования можно подключить библиотеку через
<script> в index.html:
<script src="https://cdn.jsdelivr.net/npm/interactjs/dist/interact.min.js"></script>
mountedВ компонентах Vue взаимодействие с DOM должно происходить после монтирования, чтобы элементы были доступны для Interact.js:
export default {
data() {
return {
position: { x: 0, y: 0 }
};
},
mounted() {
interact(this.$refs.draggable)
.draggable({
listeners: {
move: this.dragMoveListener
}
});
},
methods: {
dragMoveListener(event) {
this.position.x += event.dx;
this.position.y += event.dy;
event.target.style.transform = `translate(${this.position.x}px, ${this.position.y}px)`;
}
}
};
Ключевые моменты:
$refs обеспечивает прямой доступ к
элементу DOM.event.dx и event.dy отражают смещение за
текущее событие.data, что позволяет
синхронизировать с реактивными данными Vue.Interact.js позволяет задавать ограничения на перемещение элементов
через restrict:
interact(this.$refs.draggable)
.draggable({
modifiers: [
interact.modifiers.restrictRect({
restriction: 'parent',
endOnly: true
})
],
listeners: { move: this.dragMoveListener }
});
Разбор параметров:
restriction: 'parent' – элемент не выйдет за пределы
родителя.endOnly: true – проверка ограничений выполняется только
при завершении перетаскивания.Для сложных сценариев можно передавать кастомный объект ограничения с координатами:
restriction: { top: 0, left: 0, bottom: 400, right: 600 }
Interact.js поддерживает мульти-тач и работу с
gesturable:
interact(this.$refs.resizable)
.gesturable({
listeners: {
move: (event) => {
const scale = (this.scale || 1) * (1 + event.ds);
this.rotation = (this.rotation || 0) + event.da;
this.scale = scale;
event.target.style.transform = `rotate(${this.rotation}deg) scale(${this.scale})`;
}
}
});
event.ds – изменение масштаба.event.da – изменение угла вращения.scale и rotation сохраняются в
data для реактивного обновления состояния.Для реализации привязки к сетке используется snap
модификатор:
interact(this.$refs.draggable)
.draggable({
modifiers: [
interact.modifiers.snap({
targets: [
interact.createSnapGrid({ x: 50, y: 50 })
],
range: Infinity,
relativePoints: [{ x: 0, y: 0 }]
})
],
listeners: { move: this.dragMoveListener }
});
createSnapGrid({ x, y }) – задает шаг сетки.range: Infinity позволяет элементу привязываться в
любом радиусе.relativePoints управляет точкой привязки, чаще всего
используют { x: 0, y: 0 } для верхнего левого угла
элемента.При динамическом создании компонентов через v-for
необходимо повторно инициализировать Interact.js для новых элементов.
Пример с использованием nextTick:
this.$nextTick(() => {
this.items.forEach(item => {
interact(this.$refs[`item_${item.id}`])
.draggable({ listeners: { move: this.dragMoveListener } });
});
});
$refs для массивов компонентов возвращает массив
элементов.nextTick гарантирует, что DOM обновлен перед
применением Interact.js.Для полного взаимодействия между библиотекой и Vue важно хранить
состояние элементов в реактивных свойствах и обновлять DOM через
style.transform или классы.
Пример с двухмерным массивом координат для нескольких элементов:
data() {
return {
elements: [
{ id: 1, x: 0, y: 0 },
{ id: 2, x: 100, y: 50 }
]
};
},
mounted() {
this.elements.forEach((el, index) => {
interact(this.$refs[`el_${el.id}`])
.draggable({
listeners: {
move: (event) => {
this.elements[index].x += event.dx;
this.elements[index].y += event.dy;
event.target.style.transform = `translate(${this.elements[index].x}px, ${this.elements[index].y}px)`;
}
}
});
});
}
Interact.js можно комбинировать с Vue Transition для плавного появления или скрытия интерактивных элементов:
<transition name="fade">
<div ref="draggable" v-if="showElement" class="box"></div>
</transition>
В methods при перемещении элемента применяется
transform, а анимация появления управляется Vue Transition
через CSS:
.fade-enter-active, .fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
draggable и
gesturable для большого количества элементов.requestAnimationFrame при обновлении
transform для плавного рендеринга.Эти подходы позволяют построить полноценную интерактивную среду с поддержкой перетаскивания, масштабирования, вращения и сеток в Vue.js, используя всю мощь Interact.js.