カルーセルスライダーの仕組み

by flash_new52

HTML

<div id="slider">
	<button v-on:click="slidePrev">前へ</button>
	<button v-on:click="slideNext">次へ</button>
	<button v-on:click="addSlideItem">スライドアイテム追加</button>
	<button v-on:click="slideTo(7)">スライド03--02 に移動</button>
	
	<ul>
		<li v-for="item in items" v-bind:class="item.isCurrent ? 'is-current' : ''">{{ item.value }}</li>
	</ul>
</div>

CSS

.is-current,
.is-current + li,
.is-current + li + li {color: red;}
ul {display: flex; flex-wrap: wrap; width: 620px; max-width: 100%; padding: 0;}
li {width: 33.333%; flex: 0 1 auto; list-style: none; margin-bottom: 1em;}
button {
	width: 150px;
	height: 50px;
	border-radius: 8px;
	border: 1px solid;
}

Vue

const slider = new Vue({
	el: '#slider',
	data: {
		test: '',
		currentIndex: 0,
		prevIndex: 0,
		nextIndex: 0,
		lastIndex: 0,
		items: [
			{value: 'スライド01--01', isCurrent: false},
			{value: 'スライド01--02', isCurrent: false},
			{value: 'スライド01--03', isCurrent: false},
			{value: 'スライド02--01', isCurrent: false},
			{value: 'スライド02--02', isCurrent: false},
			{value: 'スライド02--03', isCurrent: false},
			{value: 'スライド03--01', isCurrent: false},
			{value: 'スライド03--02', isCurrent: false},
			{value: 'スライド03--03', isCurrent: false},
			{value: 'スライド04--01', isCurrent: false},
			{value: 'スライド04--02', isCurrent: false},
			{value: 'スライド04--03', isCurrent: false},
			{value: 'スライド05--01', isCurrent: false},
			{value: 'スライド05--02', isCurrent: false},
		],
		max: 0,
		amari: 0,
		groupingItems: 3,
		lastGroupItem: 0,
	},
	created: function () {
		this.updateData()
	},
	methods: {
		updateData: function () {
			this.max = this.items.length
			this.lastIndex = this.max - 1
			this.amari = this.max % this.groupingItems
			this.items[this.currentIndex].isCurrent = true
			this.lastGroupItem = this.amari > 0 ? this.lastIndex - (this.groupingItems - this.amari) : this.max - this.groupingItems
		},
		updateSlide: function () {
 		 	this.items[this.prevIndex].isCurrent = false
			this.items[this.currentIndex].isCurrent = true
		},
		addSlideItem: function () {
			this.items.push({
				value: '新たに追加されたスライド',
				isCurrent: false
			})
			this.updateData()
		},
		slideTo: function (slideIndex) {
			this.items[this.currentIndex].isCurrent = false
    	this.currentIndex = slideIndex - (slideIndex % this.groupingItems)
			this.updateData()
			this.items[this.currentIndex].isCurrent = true
		},
		slideNext: function (e) {
			e.preventDefault()
			this.prevIndex = this.currentIndex
			const nextIndex = this.currentIndex + this.groupingItems
			this.currentIndex = nextIndex <= this.lastIndex ? nextIndex : 0
			this.updateSlide()
		},
		slidePrev: function (e)...