vue.js+element-ui實現菜單移動輪播二


上篇說到,兩端元素會出現平行移動,看着不協調,應該是左移時第一個從左移出從右移入,右移時最后一個從右移出從左移入,現在開始優化。

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"
          }
        }
      ]
data全局變量

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>
menu.vue

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM