Я никогда раньше серьезно не писал компонент. Раньше в процессе написания бизнес-кода я использовал компоненты, упакованные другими, в этот раз я попытался написать компонент карусели изображений, хотя он не так хорош, как известный компонент карусели, но его функции в основном полны, и в процессе написания этого компонента я многому научился, и поделюсь этим с вами здесь.Если есть какие-то упущения, пожалуйста, поправьте меня!
Перед тем, как сделать этот компонент, автор прогуглил множество статей о каруселях и обнаружил, что хотя идеи реализации каруселей разные, большая логика на самом деле одна и та же.Эта статья в основном основана на МООК онлайн.Спецэффекты фокусной каруселиЭто класс, но сеть МООК в основном написана на нативном JS, и автор провел рефакторинг с помощью Vue и сделал небольшую модификацию. Завершенный рендеринг компонента выглядит следующим образом:
1. Прояснить идеи, понять требования и принципы
1. Какую карусель написать?
- При нажатии на правую стрелку изображение перемещается влево к следующему, при нажатии на левую стрелку изображение перемещается вправо к следующему.
- Нажмите на точки ниже, перейдите к соответствующему изображению, и стиль соответствующих точек также изменится.
- Чтобы получить эффект перехода, медленно проведите пальцем по
- При наведении мыши на картинку карусель останавливается, а когда мышь уходит, карусель продолжается
- Функция автозапуска
- Бесконечная прокрутка, то есть при прокрутке до последней, при нажатии на следующую, она будет продолжать скользить влево к первой, вместо того, чтобы тянуть ее к первой, здесь немного сложновато
2. Поймите принцип бесконечной карусели
Сначала рассмотрим схему:
Область красной линии на картинке - это изображение, которое мы видим, эта карусельПоказать только 5 фотографий, но есть две картинки в начале и в конце, картинка 5 помещается перед картинкой 1, а картинка 1 размещается после картинки 5. Это делается для того, чтобы сделать бесконечную прокрутку.Принцип бесконечной прокрутки заключается в следующем: когда все изображение прокручивается влево к правому изображению 5, оно будет продолжать двигаться вперед к изображению 1. После того, как изображение 1 будет полностью отображено, оно будет перемещено вправо на скорость, невидимая невооруженным глазом, к Рисунку 1 слева.Таким образом, даже если вы проведете пальцем влево, вы увидите рисунок 2.
Как показано ниже: После того, как финальное изображение 1 завершит переход и полностью отобразится, немедленно перетащите весь список вправо к изображению 1 слева. Другая карта границ, рис. 5, тоже прокручивается, но в противоположном направлении.
Во-вторых, пусть изображение переключится
1. Макет и подготовка
<template>
<div id="slider">
<div class="window"> // window上图中红线框
<ul class="container" :style="containerStyle"> //注意这里的:style //这是图片列表,排成一排
<li> //列表最前面的辅助图,它和图5一样,用于无限滚动
<img :src="sliders[sliders.length - 1].img" alt="">
</li>
<li v-for="(item, index) in sliders" :key="index"> //通过v-for渲染的需要展示的5张图
<img :src="item.img" alt="">
</li>
<li> //列表最后面的辅助图,它和图1一样,用于无限滚动
<img :src="sliders[0].img" alt="">
</li>
</ul>
<ul class="direction"> //两侧的箭头
<li class="left">
<svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M481.233 904c8.189 0 16.379-3.124 22.628-9.372 12.496-12.497 12.496-32.759 0-45.256L166.488 512l337.373-337.373c12.496-12.497 12.496-32.758 0-45.255-12.498-12.497-32.758-12.497-45.256 0l-360 360c-12.496 12.497-12.496 32.758 0 45.255l360 360c6.249 6.249 14.439 9.373 22.628 9.373z" /></svg>
</li>
<li class="right">
<svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M557.179 904c-8.189 0-16.379-3.124-22.628-9.372-12.496-12.497-12.496-32.759 0-45.256L871.924 512 534.551 174.627c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0l360 360c12.496 12.497 12.496 32.758 0 45.255l-360 360c-6.249 6.249-14.439 9.373-22.628 9.373z" /></svg>
</li>
</ul>
<ul class="dots"> //下面的小圆点
<li v-for="(dot, i) in sliders" :key="i"
:class="{dotted: i === (currentIndex-1)}"
>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'slider',
data () {
return {
sliders:[
{
img:'../../static/images/1.jpg'
},
{
img:'../../static/images/2.jpg'
},
{
img:'../../static/images/3.jpg'
},
{
img:'../../static/images/4.jpg'
},
{
img:'../../static/images/5.jpg'
}
],
currentIndex:1,
distance:-600
}
},
computed:{
containerStyle() { //这里用了计算属性,用transform来移动整个图片列表
return {
transform:`translate3d(${this.distance}px, 0, 0)`
}
}
}
}
</script>
Ну макет наверное такой, рендеры такие:
Приведенный выше код был прокомментирован, здесь следует упомянуть несколько моментов:
- окно в красной рамке,ширина 600px, он не двигается, движется контейнер, который оборачивает изображение, и он перемещается с помощью
:style="containerStyle", которое является вычисляемым свойством, сtransform:translate3d(${this.distance, 0, 0})для управления левым и правым движением - в данных
distanceа такжеcurrentIndexэто ключ,distanceУправляет расстоянием перемещения, значение по умолчанию равно -600, показывая второе из 7 изображений, которое показано на Рисунке 1.currentIndexЭто индекс изображения, отображаемого окном.По умолчанию здесь 1, что также является вторым изображением в 7 изображениях. - Необходимо отобразить только 5 изображений, но изображение 5 помещается перед изображением 1, а изображение 1 размещается после изображения 5 для бесконечной прокрутки.Принцип упоминался ранее.
- При нажатии на стрелку справа контейнер перемещается влево,
distanceОн будет становиться все меньше и меньше; при нажатии стрелки слева контейнер перемещается вправо,distanceОн будет становиться все больше и больше, не поймите неправильно
2. Переключение изображений
Добавляем события кликов на левую и правую стрелки:
<ul class="direction">
<li class="left" @click="move(600, 1)">
<svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M481.233 904c8.189 0 16.379-3.124 22.628-9.372 12.496-12.497 12.496-32.759 0-45.256L166.488 512l337.373-337.373c12.496-12.497 12.496-32.758 0-45.255-12.498-12.497-32.758-12.497-45.256 0l-360 360c-12.496 12.497-12.496 32.758 0 45.255l360 360c6.249 6.249 14.439 9.373 22.628 9.373z" /></svg>
</li>
<li class="right" @click="move(600, -1)">
<svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M557.179 904c-8.189 0-16.379-3.124-22.628-9.372-12.496-12.497-12.496-32.759 0-45.256L871.924 512 534.551 174.627c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0l360 360c12.496 12.497 12.496 32.758 0 45.255l-360 360c-6.249 6.249-14.439 9.373-22.628 9.373z" /></svg>
</li>
</ul>
......
methods:{
move(offset, direction) {
this.distance += this.distance * direction
if (this.distance < -3000) this.distance = -600
if (this.distance > -600) this.distance = -3000
}
}
Объясните приведенный выше код: щелкните стрелку слева или справа, вызовите функцию перемещения, перемещение получает два параметра смещения смещения и направления направления. Направление передает только два значения: 1 означает, что контейнер перемещается вправо, -1 означает, что контейнер перемещается влево, смещение равно 600, что соответствует ширине изображения. Если вы перейдете к последней из 7 картинок, притяните контейнер ко второй из 7 картинок; если вы перейдете к первой из 7 картинок, подтяните контейнер к пятой из 7 картинок.
Эффект:
Видно, что эффект переключения картинки вышел, но мелкие точки внизу не трансформировались. Далее мы добавляем этот эффект. Как видно из html-кода выше,:class="{dotted: i === (currentIndex - 1)}", эффект переключения маленьких точек связан со значением currentIndex в данных, нам нужно только изменить значение currentIndex при переключении изображения.
Измените код в методе перемещения:
......
move(offset, direction) {
direction === -1 ? this.currentIndex++ : this.currentIndex--
if (this.currentIndex > 5) this.currentIndex = 1
if (this.currentIndex < 1) this.currentIndex = 5
this.distance = this.distance + offset * direction
if (this.distance < -3000) this.distance = -600
if (this.distance > -600) this.distance = -3000
}
Три строки кода, добавленные выше, легко понять: если щелкнуть стрелку справа, контейнер переместится влево.this.currentIndexминус 1, иначе плюс 1.
Эффект:
Видно, что проявился эффект переключения маленьких точек.
3. Анимация перехода
В приведенном выше коде реализовано переключение, но нет эффекта анимации, что очень тупо.Следующим шагом будет добавление эффекта перехода в процесс переключения каждого изображения.
Автор этого компонента карусели не использует хук класса, поставляемый с Vue, и не использует напрямую свойство перехода CSS, а использует метод setTimeout и рекурсию, о которых упоминал первоначальный автор MOOC.com.
На самом деле, я также пытался использовать хуки Vue, но всегда есть небольшие проблемы, которые невозможно решить; например, этот пример приведен ниже:пример
В этом примере есть некоторые проблемы с границами переходов, с которыми я тоже сталкивался, и они все еще возникают и исчезают. И если вы используете метод перехода css, в браузере Chrome всегда будет мерцание при работе с бесконечной прокруткой границы, даже если вы добавите-webkit-transform-style:preserve-3d;а также-webkit-backface-visibility:hiddenЭто все еще бесполезно, и он должен сотрудничать с переходомtransitionendПоддержка событий для браузеров IE также не очень хороша.
Если вы видите лучший способ, пожалуйста, оставьте сообщение в комментариях~
Напишем этот эффект перехода, в основном переписав:
methods:{
move(offset, direction) {
direction === -1 ? this.currentIndex++ : this.currentIndex--
if (this.currentIndex > 5) this.currentIndex = 1
if (this.currentIndex < 1) this.currentIndex = 5
const destination = this.distance + offset * direction
this.animate(destination, direction)
},
animate(des, direc) {
if ((direc === -1 && des < this.distance) || (direc === 1 && des > this.distance)) {
this.distance += 30 * direc
window.setTimeout(() => {
this.animate(des, direc)
}, 20)
} else {
this.distance = des
if (des < -3000) this.distance = -600
if (des > -600) this.distance = -3000
}
}
}
Приведенный выше код — самая трудная и трудная для понимания часть этой карусели.
Чтобы понять: Прежде всего, мы переписали метод перемещения, поскольку нам нужно немного двигаться, мы должны сначала вычислить целевое расстояние, которое нужно переместить. Затем мы пишем функцию анимации для реализации этого перехода. Эта функция анимации принимает два параметра: один — расстояние, на которое следует двигаться, а другой — направление.this.distancethis.animatethis.distance
window.setInterval()
methods:{
move(offset, direction) {
direction === -1 ? this.currentIndex++ : this.currentIndex--
if (this.currentIndex > 5) this.currentIndex = 1
if (this.currentIndex < 1) this.currentIndex = 5
const destination = this.distance + offset * direction
this.animate(destination, direction)
},
animate(des, direc) {
const temp = window.setInterval(() => {
if ((direc === -1 && des < this.distance) || (direc === 1 && des > this.distance)) {
this.distance += 30 * direc
} else {
window.clearInterval(temp)
this.distance = des
if (des < -3000) this.distance = -600
if (des > -600) this.distance = -3000
}
}, 20)
}
}
4. Простое дросселирование
Пишу сюда, эффект кончился, но будет небольшая проблема.Если много раз быстро нажимать, то может возникнуть следующая ситуация:
Причина этого очень проста, потому что используется переход по таймеру, поэтому непрерывные и быстрые нажатия будут вызывать путаницу, и достаточно просто дросселировать:Щелчок по стрелке до завершения перехода недействителен.Фактически ворота установлены.Первый щелчок открывает ворота.До повторного открытия ворот часть кода не может быть выполнена,и тогда ворота открываются на правильное время.
Мы помещаем эти ворота в функцию перемещения:
move(offset, direction) {
if (!this.transitionEnd) return //这里是闸
this.transitionEnd = false //开闸以后再把闸关上
direction === -1 ? this.currentIndex++ : this.currentIndex--
if (this.currentIndex > 5) this.currentIndex = 1
if (this.currentIndex < 1) this.currentIndex = 5
const destination = this.distance + offset * direction
this.animate(destination, direction)
}
this.transitionEndявляется ключом к этим воротам, мы помещаем его в данные:
this.transitionEnd: true
По умолчанию ворота вначале открыты, после первого щелчка ворота закрываются.this.tranisitonEnd = false, код не будет выполняться, пока он не будет открыт снова. Следующий шаг — открыть врата в нужный момент, а правильный момент — когда переход завершен, то есть когдаanimate函数внутри:
animate(des, direc) {
if (this.temp) {
window.clearInterval(this.temp)
this.temp = null
}
this.temp = window.setInterval(() => {
if ((direc === -1 && des < this.distance) || (direc === 1 && des > this.distance)) {
this.distance += 30 * direc
} else {
this.transitionEnd = true //闸再次打开
window.clearInterval(this.temp)
this.distance = des
if (des < -3000) this.distance = -600
if (des > -600) this.distance = -3000
}
}, 20)
}
Этот быстрый щелчок не имеет предыдущей проблемы:
5. Нажмите на маленькую точку, чтобы реализовать переход изображения
Код пока:
<template>
<div id="slider">
<div class="window">
<ul class="container" :style="containerStyle">
<li>
<img :src="sliders[sliders.length - 1].img" alt="">
</li>
<li v-for="(item, index) in sliders" :key="index">
<img :src="item.img" alt="">
</li>
<li>
<img :src="sliders[0].img" alt="">
</li>
</ul>
<ul class="direction">
<li class="left" @click="move(600, 1)">
<svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M481.233 904c8.189 0 16.379-3.124 22.628-9.372 12.496-12.497 12.496-32.759 0-45.256L166.488 512l337.373-337.373c12.496-12.497 12.496-32.758 0-45.255-12.498-12.497-32.758-12.497-45.256 0l-360 360c-12.496 12.497-12.496 32.758 0 45.255l360 360c6.249 6.249 14.439 9.373 22.628 9.373z" /></svg>
</li>
<li class="right" @click="move(600, -1)">
<svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M557.179 904c-8.189 0-16.379-3.124-22.628-9.372-12.496-12.497-12.496-32.759 0-45.256L871.924 512 534.551 174.627c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0l360 360c12.496 12.497 12.496 32.758 0 45.255l-360 360c-6.249 6.249-14.439 9.373-22.628 9.373z" /></svg>
</li>
</ul>
<ul class="dots">
<li v-for="(dot, i) in sliders" :key="i"
:class="{dotted: i === (currentIndex-1)}"
>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'slider',
data () {
return {
sliders:[
{
img:'../../static/images/1.jpg'
},
{
img:'../../static/images/2.jpg'
},
{
img:'../../static/images/3.jpg'
},
{
img:'../../static/images/4.jpg'
},
{
img:'../../static/images/5.jpg'
}
],
currentIndex:1,
distance:-600,
transitionEnd: true
}
},
computed:{
containerStyle() {
return {
transform:`translate3d(${this.distance}px, 0, 0)`
}
}
},
methods:{
move(offset, direction) {
if (!this.transitionEnd) return
this.transitionEnd = false
direction === -1 ? this.currentIndex++ : this.currentIndex--
if (this.currentIndex > 5) this.currentIndex = 1
if (this.currentIndex < 1) this.currentIndex = 5
const destination = this.distance + offset * direction
this.animate(destination, direction)
},
animate(des, direc) {
if (this.temp) {
window.clearInterval(this.temp)
this.temp = null
}
this.temp = window.setInterval(() => {
if ((direc === -1 && des < this.distance) || (direc === 1 && des > this.distance)) {
this.distance += 30 * direc
} else {
this.transitionEnd = true
window.clearInterval(this.temp)
this.distance = des
if (des < -3000) this.distance = -600
if (des > -600) this.distance = -3000
}
}, 20)
}
}
}
</script>
Далее нам нужно реализовать переход и переключение изображений, щелкнув маленькие точки внизу.
<ul class="dots">
<li v-for="(dot, i) in sliders" :key="i"
:class="{dotted: i === (currentIndex-1)}"
@click = jump(i+1)>
</li>
</ul>
Когда точка нажата, мы вызываемjumpфункционировать и будет индексироватьi+1перейти к нему.Здесь нужно обратить особое внимание.Индекс маленьких точек не соответствует индексу, соответствующему картинке.Всего 7 картинок, а 5 маленьких точек соответствуют 5 картинкам в середине картинки, поэтому мы только пройтиi+1.
jump(index) {
const direction = index - this.currentIndex >= 0 ? -1 : 1 //获取滑动方向
const offset = Math.abs(index - this.currentIndex) * 600 //获取滑动距离
this.move(offset, direction)
}
Проблема с приведенным выше кодом: в функции перехода вызывается метод перемещения, а текущий индекс в движении — это все+1, и нажатие точек можетcurrentIndexДобавьте или вычтите много, поэтому вам нужно изменить код в движении:
direction === -1 ? this.currentIndex += offset/600 : this.currentIndex -= offset/600
Измените строку и рассчитайте текущий режим в соответствии с смещением.
Но есть еще одна проблема, скорость переключения на большие расстояния слишком низкая, а именно:
Таким образом, нам нужно контролировать скорость, чтобы перемещение изображения занимало столько же времени, сколько требуется для перемещения нескольких изображений.Добавьте параметр скорости к функциям перемещения и анимации и повторите расчет:
jump(index) {
const direction = index - this.currentIndex >= 0 ? -1 : 1
const offset = Math.abs(index - this.currentIndex) * 600
const jumpSpeed = Math.abs(index - this.currentIndex) === 0 ? this.speed : Math.abs(index - this.currentIndex) * this.speed
this.move(offset, direction, jumpSpeed)
}
6. Автоматическое воспроизведение и пауза
Предыдущее написание почти такое же, здесь все очень просто, напишите функцию play:
play() {
if (this.timer) {
window.clearInterval(this.timer)
this.timer = null
}
this.timer = window.setInterval(() => {
this.move(600, -1, this.speed)
}, 4000)
}
В дополнение к автоматическому воспроизведению после инициализации, mouseover и mouseleave также используются для управления паузой и воспроизведением:
stop() {
window.clearInterval(this.timer)
this.timer = null
}
Семь, две ямы
1. window.onblurа такжеwindow.onfocus
Написано здесь, основные функции практически одинаковы. Однако, если вы переключите страницу на другую страницу, страница, на которой находится изображение карусели, будет не в фокусе, и вы обнаружите, что карусель бешено вращается, когда вы переключаетесь обратно через некоторое время. Причина в том, что после того, как страница не в фокусе, setInterval перестает работать, но если его переключить обратно, то он пойдет все сразу. Решение также очень простое: остановите вращение, когда страница не в фокусе, и начните вращение, когда страница окажется в фокусе.
window.onblur = function() { this.stop() }.bind(this)
window.onfocus = function() { this.play() }.bind(this)
2. window.setInterval()маленькая яма
когда таймерwindow.setInterval()При использовании в нескольких асинхронных обратных вызовах можно с определенной вероятностью открыть несколько очередей выполнения,Поэтому, чтобы быть в безопасности, вы должны не только очищать таймер, когда пришло время его очистить, но и очищать его перед каждым использованием..
Восемь, просто напишите два внешних интерфейса с пропсами
props: {
initialSpeed: {
type: Number,
default: 30
},
initialInterval: {
type: Number,
default: 4
}
},
data() {
......
speed: this.initialSpeed
},
computed:{
interval() {
return this.initialInterval * 1000
}
}
Затем вы можете изменить его в соответствующем месте.
Полный код выглядит следующим образом:
<template>
<div id="slider">
<div class="window" @mouseover="stop" @mouseleave="play">
<ul class="container" :style="containerStyle">
<li>
<img :src="sliders[sliders.length - 1].img" alt="">
</li>
<li v-for="(item, index) in sliders" :key="index">
<img :src="item.img" alt="">
</li>
<li>
<img :src="sliders[0].img" alt="">
</li>
</ul>
<ul class="direction">
<li class="left" @click="move(600, 1, speed)">
<svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M481.233 904c8.189 0 16.379-3.124 22.628-9.372 12.496-12.497 12.496-32.759 0-45.256L166.488 512l337.373-337.373c12.496-12.497 12.496-32.758 0-45.255-12.498-12.497-32.758-12.497-45.256 0l-360 360c-12.496 12.497-12.496 32.758 0 45.255l360 360c6.249 6.249 14.439 9.373 22.628 9.373z" /></svg>
</li>
<li class="right" @click="move(600, -1, speed)">
<svg class="icon" width="30px" height="30.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="#ffffff" d="M557.179 904c-8.189 0-16.379-3.124-22.628-9.372-12.496-12.497-12.496-32.759 0-45.256L871.924 512 534.551 174.627c-12.496-12.497-12.496-32.758 0-45.255 12.498-12.497 32.758-12.497 45.256 0l360 360c12.496 12.497 12.496 32.758 0 45.255l-360 360c-6.249 6.249-14.439 9.373-22.628 9.373z" /></svg>
</li>
</ul>
<ul class="dots">
<li v-for="(dot, i) in sliders" :key="i"
:class="{dotted: i === (currentIndex-1)}"
@click = jump(i+1)
>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'slider',
props: {
initialSpeed: {
type: Number,
default: 30
},
initialInterval: {
type: Number,
default: 4
}
},
data () {
return {
sliders:[
{
img:'../../static/images/1.jpg'
},
{
img:'../../static/images/2.jpg'
},
{
img:'../../static/images/3.jpg'
},
{
img:'../../static/images/4.jpg'
},
{
img:'../../static/images/5.jpg'
}
],
currentIndex:1,
distance:-600,
transitionEnd: true,
speed: this.initialSpeed
}
},
computed:{
containerStyle() {
return {
transform:`translate3d(${this.distance}px, 0, 0)`
}
},
interval() {
return this.initialInterval * 1000
}
},
mounted() {
this.init()
},
methods:{
init() {
this.play()
window.onblur = function() { this.stop() }.bind(this)
window.onfocus = function() { this.play() }.bind(this)
},
move(offset, direction, speed) {
if (!this.transitionEnd) return
this.transitionEnd = false
direction === -1 ? this.currentIndex += offset/600 : this.currentIndex -= offset/600
if (this.currentIndex > 5) this.currentIndex = 1
if (this.currentIndex < 1) this.currentIndex = 5
const destination = this.distance + offset * direction
this.animate(destination, direction, speed)
},
animate(des, direc, speed) {
if (this.temp) {
window.clearInterval(this.temp)
this.temp = null
}
this.temp = window.setInterval(() => {
if ((direc === -1 && des < this.distance) || (direc === 1 && des > this.distance)) {
this.distance += speed * direc
} else {
this.transitionEnd = true
window.clearInterval(this.temp)
this.distance = des
if (des < -3000) this.distance = -600
if (des > -600) this.distance = -3000
}
}, 20)
},
jump(index) {
const direction = index - this.currentIndex >= 0 ? -1 : 1
const offset = Math.abs(index - this.currentIndex) * 600
const jumpSpeed = Math.abs(index - this.currentIndex) === 0 ? this.speed : Math.abs(index - this.currentIndex) * this.speed
this.move(offset, direction, jumpSpeed)
},
play() {
if (this.timer) {
window.clearInterval(this.timer)
this.timer = null
}
this.timer = window.setInterval(() => {
this.move(600, -1, this.speed)
}, this.interval)
},
stop() {
window.clearInterval(this.timer)
this.timer = null
}
}
}
</script>
9. Заключение
Я, наверное, закончил писать этот компонент и обнаружил, что на самом деле есть много мест, которые можно оптимизировать.this.distanceа такжеthis.currentIndexВысокая связь, полностью соединенная вместе путем вычисления свойства. Существует переход с методом таймера или какого-то тупых, мы не играли к преимуществам VUE. Однако первый компонент будет завершен, но и потратил много усилий.
Это моя четвертая статья о Наггетс, спасибо за прочтение!