zoukankan      html  css  js  c++  java
  • Vue 轻量级滑动tab栏_选中的item自动居中组件

    可滑动,选定的tabItem自动居中,支持x和y两种模式

    <template>
      <div class="scrollBarWrapper" :style="scrollBarWrapperStyle">
        <div
          class="scrollBarContent"
          :class="direction === 'y' ? 'directionY' : 'directionX'"
          ref="scrollBarContent"
        >
          <slot></slot>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      props: {
        direction: {
          type: String,
          default: "x",
          validator(value) {
            return value === "x" || value === "y";
          }
        },
        activeIndex: {
          type: Number,
          default: 0,
          validator(value) {
            return value >= 0;
          }
        }
      },
      watch: {
        activeIndex(newVal, oldVal) {
          this.handleChange();
        }
      },
      computed: {
        scrollBarWrapperStyle() {
          return this.direction === "y"
            ? {
                height: "100%"
              }
            : {
                 "100%"
              };
        }
      },
      mounted() {
        this.initItemDisplay();
        this.handleChange();
      },
      methods: {
        initItemDisplay() {
          const content = this.$refs.scrollBarContent;
          const contentItem = content.children;
          [].forEach.call(contentItem, item => {
            if (this.direction === "y") {
              item.style.display = "block";
            } else {
              item.style.display = "inline-block";
            }
          });
        },
        handleChange() {
          this.$nextTick(() => {
            const content = this.$refs.scrollBarContent; // 发生滑动的元素
            const activeItem = content.children[this.activeIndex]; // 当前选中的元素
            if(!activeItem) return false;
            
            const scrollOption = {
              top: 0,
              left: 0,
              behavior: "smooth"
            };
    
            if (this.direction === "y") {
              const contentHeight = content.offsetHeight;
              const activeItemHeight = activeItem.offsetHeight;
              const activeItemTop = activeItem.offsetTop;
              const offset = activeItemTop - (contentHeight - activeItemHeight) / 2; // 需要移动的位置
              scrollOption.top = offset;
            } else {
              const contentWidth = content.offsetWidth; // 发生滑动元素的宽
              const activeItemWidth = activeItem.offsetWidth; // 当前元素的宽
              const activeItemLeft = activeItem.offsetLeft; // 当前元素的到他父盒子左侧的距离
              const offset = activeItemLeft - (contentWidth - activeItemWidth) / 2; // 需要移动的位置
              scrollOption.left = offset;
            }
    
            content.scrollTo(scrollOption);
          });
        }
      }
    };
    </script>
    
    <style lang="scss" scoped>
    .scrollBarWrapper {
      position: relative;
      overflow: hidden;
      user-select: none;
      vertical-align: middle;
    
      .scrollBarContent {
         100%;
        white-space: nowrap;
        word-break: keep-all;
        -webkit-overflow-scrolling: touch;
    
        &.directionX {
          overflow-x: scroll;
          overflow-y: hidden;
        }
    
        &.directionY {
          overflow-x: hidden;
          overflow-y: scroll;
          height: 100%;
        }
    
        &::-webkit-scrollbar {
          display: none;
        }
      }
    }
    </style>
    

    demo
    <template>
    	<scrollBar direction="x" :activeIndex="activeIndex">
    		<div
    			class="scrollBarItem"
    			v-for="(item, index) in options"
    			:key="index"
    			@click="changeNav(item, index)"
    			:class="index === activeIndex ? 'active' : null"
    		>
    			<div>{{item.name}}</div>
    		</div>
    	</scrollBar>
    </template>
    <script>
    	// 先导入再注册下
    	export default {
    		data() {
    			return {
    				activeIndex: 0,
    				options: [
    					{id: 1, name: '关注'},
    					{id: 2, name: '推荐'},
    					{id: 3, name: '本地'},
    					{id: 4, name: '新闻'},
    					{id: 5, name: '汽车'},
    					{id: 6, name: '直播'},
    					{id: 7, name: '游戏'},
    					{id: 8, name: '小说'},
    					{id: 9, name: '美女'}
    				]
    			}
    		},
    		methods: {
    			changeNav(item, index) {
    				this.activeIndex = index;
    			}
    		}
    	}
    </script>
    <style lang="scss" scoped>
    	.scrollBarItem {
    		padding: rem(8) rem(15);
    	}
    	.active {
    		color: red;
    		div {
    			border-bottom: 1px solid red;
    		}
    	}
    </style>
    
    为之则易,不为则难。
  • 相关阅读:
    HTML5 <meta> 标签属性,所有meta用法
    C#中导出数据到Excel表格中 逗号
    .net MVC 中缓存的使用 逗号
    MVC 过滤器 逗号
    .Net 分布式技术比较 逗号
    将DataTable导出为Excel (XML Spreadsheet).
    AntiTD
    三星WP7手机MANGO一分钟完美越狱
    SPGridView 研究笔记 Part 3 分组
    Silverlight 4 Binding Cheatsheet [转]
  • 原文地址:https://www.cnblogs.com/coderDemo/p/13304051.html
Copyright © 2011-2022 走看看