上篇說到,兩端元素會出現平行移動,看着不協調,應該是左移時第一個從左移出從右移入,右移時最后一個從右移出從左移入,現在開始優化。
1.我們控制數組移動實際上是再改變數組元素所綁定的下標數組indexList,如何做到第一個數組從左移出再從右移入呢?
我想到一個辦法,在原數組末位再添加一個元素,這個元素是原數組的第一個元素,在首位添加一個新元素,這個元素是原素組的最后一個元素;
我們看到的數組不變還是5個,只不過是處理后數組的中間五位,兩端被遮蓋了。
此時菜單數組有7位,我們修改下styleList數組,在原數組兩端添加兩個樣式

list: [{ title: "吃飯" }, { title: "睡覺" }, { title: "打游戲" }, { title: "逛街" }, { title: "撩妹" }], indexList: [], //下標列表 centerNum: 0, //中間位置的下標 theFirstIndex: 0, //存儲頁面展示的數組中第一位下標 theLastIndex: 0, //存儲頁面展示的數組中最后一位下標 styleList: [ { width: "160px", height: "240px", top: "210px", left: "-240px", transition: "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear", textStyle: { fontSize: "28px", lineHeight: "28px", transition: "font-size 0.4s linear, line-height 0.4s linear" } }, { width: "160px", height: "240px", top: "280px", left: "0", transition: "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear", textStyle: { fontSize: "28px", lineHeight: "28px", transition: "font-size 0.4s linear, line-height 0.4s linear" } }, { width: "180px", height: "260px", top: "350px", left: "260px", transition: "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear", textStyle: { fontSize: "34px", lineHeight: "34px", transition: "font-size 0.4s linear, line-height 0.4s linear" } }, { width: "200px", height: "280px", top: "420px", left: "530px", transition: "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear", textStyle: { fontSize: "40px", lineHeight: "40px", transition: "font-size 0.4s linear, line-height 0.4s linear" } }, { width: "180px", height: "260px", top: "350px", left: "820px", transition: "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear", textStyle: { fontSize: "34px", lineHeight: "34px", transition: "font-size 0.4s linear, line-height 0.4s linear" } }, { width: "160px", height: "240px", top: "280px", left: "1100px", transition: "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear", textStyle: { fontSize: "28px", lineHeight: "28px", transition: "font-size 0.4s linear, line-height 0.4s linear" } }, { width: "160px", height: "240px", top: "210px", left: "1350px", transition: "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear", textStyle: { fontSize: "28px", lineHeight: "28px", transition: "font-size 0.4s linear, line-height 0.4s linear" } } ]
2.需要一個方法,初始化數組並且每次移動后都要將數組首尾元素重新賦值
這里有個麻煩的地方,我們在頁面上看到的菜單數組順序是變化的,但是在代碼中,數組除了兩端,中間部分是不變的,只是每個元素的樣式變了,
當點擊了一個菜單,indexList數組內元素順序發生變化后,頁面展示的第一位並不是代碼中7位數組的第二位,
例如:開始時,第一位的下標時1,我點擊了第四個菜單,整體左移了一位,indexList數組整體右移了一位,這時,第一位的下標是2
所以我們需要記錄頁面展示的數組的第一位的下標,每次菜單整體左移時,++,整體右移時,--
初始化時,它是1,末位是5,
反之,末位下標也要記錄

//初始化菜單數組,在首尾添加新元素 initList(num) { const that = this; var start = []; var mid = []; var end = []; var newArray = []; if (num == 0) { //頁面初次加載時執行 mid = that.list; end = mid.slice(0, 1); start = mid.slice(mid.length - 1, mid.length); newArray = start.concat(mid); that.list = newArray.concat(end); //記錄改變后的數組在頁面展示的第一位(取styleList[1]樣式)下標 值(即indexList.indexOf(1)) that.theFirstIndex = that.indexList.indexOf(1); that.theLastIndex = that.indexList.indexOf(that.list.length - 2); } else { //移動后執行 mid = that.list.slice(1, that.list.length - 1); end = that.list.slice(that.theFirstIndex, that.theFirstIndex + 1); start = that.list.slice(that.theLastIndex, that.theLastIndex + 1); var startIndex = 0; var endIndex = 0; if (that.theFirstIndex <= 0) { startIndex = that.indexList.length - 1; } else { startIndex = that.theFirstIndex - 1; } if (that.theLastIndex >= that.indexList.length - 1) { endIndex = 0; } else { endIndex = that.theLastIndex + 1; } that.list[startIndex] = start[0]; that.list[endIndex] = end[0]; } }
3.每次移動后都要對兩個下表變量處理

//菜單整體向左移一位,下標數組向右移一位 moveToRight() { this.styleList[0].transition = "none"; this.styleList[0].textStyle.transition = "none"; this.styleList[this.styleList.length - 1].transition = "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear"; this.styleList[this.styleList.length - 1].textStyle.transition = "font-size 0.4s linear, line-height 0.4s linear"; this.indexList = this.indexList.splice(1, this.indexList.length).concat(this.indexList); if (this.theFirstIndex <= 0) { this.theFirstIndex = this.indexList.length - 1; } else { this.theFirstIndex--; } if (this.theLastIndex <= 0) { this.theLastIndex = this.indexList.length - 1; } else { this.theLastIndex--; } this.initList(1); }, //菜單 整體向右移一位,下標數組向左移一位 moveToLeft() { this.styleList[this.styleList.length - 1].transition = "none"; this.styleList[this.styleList.length - 1].textStyle.transition = "none"; this.styleList[0].transition = "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear"; this.styleList[0].textStyle.transition = "font-size 0.4s linear, line-height 0.4s linear"; this.indexList = this.indexList.splice(this.indexList.length - 1, this.indexList.length).concat(this.indexList); if (this.theFirstIndex >= this.indexList.length - 1) { this.theFirstIndex = 0; } else { this.theFirstIndex++; } if (this.theLastIndex >= this.indexList.length - 1) { this.theLastIndex = 0; } else { this.theLastIndex++; } this.initList(1); }
4.這樣的,我們去掉styleList兩端元素的transition屬性
效果圖:
但是這樣的話,移出效果沒有了,因為它的transition屬性沒有了,就會導致這個現象,那么我們動態控制它的transition屬性,
因為在移出時需要移動效果,我們向左移動時,先把styleList[0]添加transition屬性,把styleList[6]去掉transition屬性,右移反之,代碼見第3點移動方法
5.最后隱藏掉兩端就可以了,在盒子樣式中添加overflow:hidden;完成!
6.完整代碼,有不好的地方還請多多指教!

<template> <el-row id="myMenu"> <el-row class="nav"> <el-row class="setPosition borderBox" v-for="(item,index) in list" :key="index" :style="styleList[indexList[index]]"> <span class="titleText" :style="styleList[indexList[index]].textStyle" @click="moveToCenter(indexList[index])">{{item.title}}</span> <!-- <br>我取的是indexList[{{index}}]={{indexList[index]}} --> <!-- <br>我是頁面中展示的第{{indexList[index]}}位 --> </el-row> </el-row> </el-row> </template> <script> export default { data() { return { list: [{ title: "吃飯" }, { title: "睡覺" }, { title: "打游戲" }, { title: "逛街" }, { title: "撩妹" }], indexList: [], //下標列表 centerNum: 0, //中間位置的下標 theFirstIndex: 0, //存儲頁面展示的數組中第一位下標 theLastIndex: 0, //存儲頁面展示的數組中最后一位下標 styleList: [ { width: "160px", height: "240px", top: "210px", left: "-240px", transition: "none", textStyle: { fontSize: "28px", lineHeight: "28px", transition: "none" } }, { width: "160px", height: "240px", top: "280px", left: "0", transition: "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear", textStyle: { fontSize: "28px", lineHeight: "28px", transition: "font-size 0.4s linear, line-height 0.4s linear" } }, { width: "180px", height: "260px", top: "350px", left: "260px", transition: "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear", textStyle: { fontSize: "34px", lineHeight: "34px", transition: "font-size 0.4s linear, line-height 0.4s linear" } }, { width: "200px", height: "280px", top: "420px", left: "530px", transition: "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear", textStyle: { fontSize: "40px", lineHeight: "40px", transition: "font-size 0.4s linear, line-height 0.4s linear" } }, { width: "180px", height: "260px", top: "350px", left: "820px", transition: "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear", textStyle: { fontSize: "34px", lineHeight: "34px", transition: "font-size 0.4s linear, line-height 0.4s linear" } }, { width: "160px", height: "240px", top: "280px", left: "1100px", transition: "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear", textStyle: { fontSize: "28px", lineHeight: "28px", transition: "font-size 0.4s linear, line-height 0.4s linear" } }, { width: "160px", height: "240px", top: "210px", left: "1350px", transition: "none", textStyle: { fontSize: "28px", lineHeight: "28px", transition: "none" } } ] }; }, created() { this.initIndexList(7); this.initList(0); this.centerNum = 3; }, methods: { //初始化下標數組,num為數組長度 initIndexList(num) { this.indexList = []; for (var i = 0; i < num; i++) { this.indexList[i] = i; } }, //初始化菜單數組,在首尾添加新元素 initList(num) { const that = this; var start = []; var mid = []; var end = []; var newArray = []; if (num == 0) { //頁面初次加載時執行 mid = that.list; end = mid.slice(0, 1); start = mid.slice(mid.length - 1, mid.length); newArray = start.concat(mid); that.list = newArray.concat(end); //記錄改變后的數組在頁面展示的第一位(取styleList[1]樣式)下標值(即indexList.indexOf(1)) that.theFirstIndex = that.indexList.indexOf(1); that.theLastIndex = that.indexList.indexOf(that.list.length - 2); } else { //移動后執行 mid = that.list.slice(1, that.list.length - 1); end = that.list.slice(that.theFirstIndex, that.theFirstIndex + 1); start = that.list.slice(that.theLastIndex, that.theLastIndex + 1); var startIndex = 0; var endIndex = 0; if (that.theFirstIndex <= 0) { startIndex = that.indexList.length - 1; } else { startIndex = that.theFirstIndex - 1; } if (that.theLastIndex >= that.indexList.length - 1) { endIndex = 0; } else { endIndex = that.theLastIndex + 1; } that.list[startIndex] = start[0]; that.list[endIndex] = end[0]; } }, moveToCenter(index) { const that = this; var count = this.centerNum; if (index > count) { that.moveToLeft(); var interval = setInterval(function() { if (index > count + 1) { that.moveToLeft(); count++; } else { clearInterval(interval); } }, 4 * 100); } else if (index < count) { that.moveToRight(); var interval = setInterval(function() { if (index < count - 1) { that.moveToRight(); count--; } else { clearInterval(interval); } }, 4 * 100); } }, //菜單整體向左移一位,下標數組向右移一位 moveToRight() { this.styleList[0].transition = "none"; this.styleList[0].textStyle.transition = "none"; this.styleList[this.styleList.length - 1].transition = "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear"; this.styleList[this.styleList.length - 1].textStyle.transition = "font-size 0.4s linear, line-height 0.4s linear"; this.indexList = this.indexList.splice(1, this.indexList.length).concat(this.indexList); if (this.theFirstIndex <= 0) { this.theFirstIndex = this.indexList.length - 1; } else { this.theFirstIndex--; } if (this.theLastIndex <= 0) { this.theLastIndex = this.indexList.length - 1; } else { this.theLastIndex--; } this.initList(1); }, //菜單 整體向右移一位,下標數組向左移一位 moveToLeft() { this.styleList[this.styleList.length - 1].transition = "none"; this.styleList[this.styleList.length - 1].textStyle.transition = "none"; this.styleList[0].transition = "left 0.4s linear, top 0.4s linear, width 0.4s linear,height 0.4s linear"; this.styleList[0].textStyle.transition = "font-size 0.4s linear, line-height 0.4s linear"; this.indexList = this.indexList.splice(this.indexList.length - 1, this.indexList.length).concat(this.indexList); if (this.theFirstIndex >= this.indexList.length - 1) { this.theFirstIndex = 0; } else { this.theFirstIndex++; } if (this.theLastIndex >= this.indexList.length - 1) { this.theLastIndex = 0; } else { this.theLastIndex++; } this.initList(1); } } }; </script> <style scoped> #myMenu { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .nav { width: 1260px; height: 700px; margin: 0 auto; background: #0157909d; overflow: hidden; } .setPosition { position: absolute; } .borderBox { border: 1px red solid; text-align: center; } .titleText { font-weight: 400; text-align: center; font-family: Microsoft YaHei; cursor: pointer; } </style>