天天看点

vue 页码环组件

前言:因为这个功能要求的比较多,所以也没有找到合适的三方可以用,就自己写了一个但功能不是很完善,下面的代码是男朋友写的,可配置性比较高,自己想在页面上展示几个数组都可以自己定义

一、功能要求

vue 页码环组件
vue 页码环组件

 二、效果展示

注:没有做鼠标的禁选功能,所以点击的时候出现了背景色

1、点击上一层,可以一直向上一层,到最高层的时候,也不会结束,重新开始新的一轮的循环

vue 页码环组件

2、点击下一层,可以一直向下一层,到最底层的时候,也不会结束,重新开始新的一轮的循环

vue 页码环组件

3、可以单独点击楼层本身,点到那一个就会是那一层放到最中间,样式要求,显示的中间的楼层要永远有一个区别于其他楼层的之外的特殊样式进行区分

vue 页码环组件

4、数据不一定是纯数字,也有可能是字符串,比如就是1,2,3,4,5,5M(做这个功能的时候,是有关楼层,5M在实际生活中也是有可能存在,代表的是5楼的隔层)

三、代码展示

<style>
  #app {
    font-family: 'Avenir', Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 60px;
  }
</style>

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <Pages
      :data="option.data"
      :data-key="option.dataKey"
      :start="option.start"
      :end="option.end"
      :prev-text="option.prevText"
      :next-text="option.nextText"
      @change="changeHandler"
    />
  </div>
</template>

<script>
import Pages from './components/Pages.vue'
export default {
  name: 'app',
  data () {
    return {
      option: {
        start: 2,
        end: 2,
        prevText: '上一层',
        nextText: '下一层',
        dataKey: 'label',
        data: [
          { label: '1层' },
          { label: '2层' },
          { label: '3层' },
          { label: '4层' },
          { label: '5层' },
          { label: '6层' },
          { label: '7层' },
          { label: '8层' },
          { label: '9层' },
          { label: '10层' },
          { label: '10M层' },
          { label: '11层' },
          { label: '12层' },
          { label: '13层' },
          { label: '14层' },
          { label: '15层' },
          { label: '16层' },
          { label: '17层' },
          { label: '18层' },
          { label: '19层' },
          { label: '20层' },
          { label: '21层' },
          { label: '22层' }
        ]
      }
    }
  },
  methods: {
    changeHandler (item, index) {
      console.log(item, index)
    }
  },
  components: {
    [Pages.name]: Pages
  }
}
</script>
           
<style scoped>
  ul {
    list-style: none;
    padding: 0;
  }
  .active {
    color: #409eff;
  }
</style>

<template>
  <div class="pages">
    <span v-on:click="prev(active - 1)">{{ this.prevText }}</span>
    <ul class="pages">
      <li
        v-for="(item, index) in activeArr"
        v-bind:key="index"
        v-bind:class="activeClass(item)"
        v-on:click="jump(index)"
      >
        {{ item[dataKey] || item }}
      </li>
    </ul>
    <span v-on:click="next(active + 1)">{{ this.nextText }}</span>
  </div>
</template>

<script>
export default {
  name: 'Pages',
  props: {
    data: {
      type: Array,
      default: () => []
    },
    dataKey: {
      type: String,
      default: ''
    },
    start: {
      type: Number,
      default: 2
    },
    end: {
      type: Number,
      default: 2
    },
    prevText: {
      type: String,
      default: '上一页'
    },
    nextText: {
      type: String,
      default: '下一页'
    }
  },
  data () {
    return {
      active: null,
      arr: this.data.concat(this.data) // 这样就能实现循环
    }
  },
  created () {
    this.active = this.arr.length / 2 // 选中数组中间的第一个元素
  },
  computed: {
    activeArr () {
      return this.arr.slice(this.active - this.start, this.active + this.end + 1) // + 1 是因为该方法不包含最后一位元素
    }
  },
  methods: {
    prev (index) {
      let startIndex = this.start * 2 // 乘以2是早点进入判断边界的区间防止跃出边界
      let newIndex = index + this.data.length
      let dataIndex = index - this.data.length >= 0 ? index - this.data.length : index
      this.active = index < startIndex ? newIndex : index
      this.$emit('change', this.data[dataIndex], dataIndex)
    },
    jump (index) {
      let newIndex = this.active - this.start + index // 这样才可以让this.activeArr中的index和this.arr的index对应上
      this.active > newIndex && this.prev(newIndex)
      this.active < newIndex && this.next(newIndex)
    },
    next (index) {
      let endIndex = (this.arr.length - 1) - this.end * 2 // 乘以2是早点进入判断边界的区间防止跃出边界
      let newIndex = index - this.data.length
      let dataIndex = index - this.data.length >= 0 ? index - this.data.length : index
      this.active = index > endIndex ? newIndex : index
      this.$emit('change', this.data[dataIndex], dataIndex)
    },
    activeClass (item) {
      return {
        active: this.dataKey
          ? this.arr[this.active][this.dataKey] === item[this.dataKey]
          : this.arr[this.active] === item
      }
    }
  }
}
</script>
           

最终效果:可以实现页码结尾到页码开头的无缝衔接,样式自己优化一下。