美文网首页小程序
微信小程序组件: tab标签页

微信小程序组件: tab标签页

作者: 牛会骑自行车 | 来源:发表于2022-10-18 13:55 被阅读0次

    需求:

    1. 插槽为动态, 可以在使用页面自行设置
    2. 可以自定义设置每个tab的样式, 也可以设置容器的样式
    3. 如果tab太多, 容器可以横向滚动
    4. 设置当前tab值可以自动定位到当前tab位置

    思路:

    1. slot属性name动态设置
    2. 设置默认样式, 写好公共的方法, 将对象转换成style可以用的字符串
    3. scroll-x
    4. scroll-into-view
    效果图:

    组件代码 ⬇️
    wxml

    <view class="tabs-container">
      <scroll-view style="{{tabsConStyle}}" class="pane-con" scroll-x enhanced bounces scroll-into-view="{{currentTab}}">
        <view wx:for="{{tabs}}" wx:key="id" id="{{item.id}}" class="tabs-pane inline {{index === activeTab ? 'active' : ''}}" style="{{index === activeTab ? paneActiveStyle : paneStyle}}" bindtap="switchTab" data-index="{{index}}">{{item.label}}</view>
      </scroll-view>
      <block wx:for="{{tabs}}" wx:key="id">
        <!-- 可以使用每项对应的插槽 -->
        <view class="tabs-content" wx:if="{{activeTab === index}}">
          <slot name="{{index}}"></slot>
        </view>
        <!-- 如果使用页面中每tab只是数据不同或其它情况, 也可以使用这个默认插槽 -->
        <slot></slot>
      </block>
    </view>
    

    js

    Component({
      options: {
        multipleSlots: true
      },
      properties: {
        // 必传参: tabs数组, 每项需要传一个包含属性名为label和属性名为id唯一值的对象
        tabs: {
          required: true,
          type: Array,
          value: () => {
            return [{
              label: "",
              id: ""
            }]
          }
        },
        // 非必传: 当前tab初始值
        activeTab: {
          type: Number,
          value: 0
        },
        // 非必传: 每一项的样式
        tabStyle: Object,
        // 非必传: 当前项的样式
        tabActiveStyle: Object,
        // 非必传: 可滑动tabs容器的样式
        tabsStyle: Object,
      },
      data: {
        paneStyle: "",
        paneActiveStyle: "",
        tabsConStyle: "",
        flag: false,
        // 为固定tabCon左滑的位置
        currentTab: "",
      },
      methods: {
        initTabs() {
          // 共三个参数的赋值过程
          // 思路: 
          // 1. 都需要经过对象转字符串过程
          // 2. 如果有普通每项, 则先将当前项的特殊样式与普通项样式合并, 再进行字符串处理
          this.setData({
            paneStyle: this.transferObjToStr(this.data.tabStyle),
            paneActiveStyle: this.data.tabStyle ? this.transferObjToStr(Object.assign(this.data.tabStyle, this.data.tabActiveStyle)) : this.transferObjToStr(this.data.tabActiveStyle),
            tabsConStyle: this.transferObjToStr(this.data.tabsStyle),
          })
        },
        switchTab(event) {
          // 切换方法: 设置当前项, 并传值
          this.setData({
            activeTab: event.currentTarget.dataset.index,
          })
          this.triggerEvent('switchTab', this.data.activeTab);
        },
        transferObjToStr(obj) {
          // 小程序中style不可以像VUE一样直接使用对象, 而传入的是对象, 这一步是将传入的style对象转换成组件中可以直接使用的字符串
          if (!obj) return "";
    
          let str = "";
          for (let key in obj) {
            str += `${key}: ${obj[key]};`;
          }
          return str;
        },
      },
      lifetimes: {
        attached() {
          this.initTabs();
        }
      },
      observers: {
        tabs: function (tabs) {
          // 将来可能会做tabs增删改的功能(我自己想的哈哈哈哈哈)这步的意思是头一次进入页面才需要判断有无activeTab
          // 单拿出来监听tabs: activeTab的设置, 必须得在tabs赋值之后
          if (this.data.flag) return;
          if (tabs.length > 0) {
            // 代表tabs赋值完毕
            this.setData({
              flag: true,
              // 自动定位当前tab
              currentTab: this.data.activeTab === 0 ? "" : this.data.tabs[this.data.activeTab].id
            })
          }
        }
      },
    })
    

    wxss

    /* 样式重点是这个容器: 宽度为本身容器的100%, 横向溢出滑动并且不能换行 */
    .pane-con {
        width: 100%;
        overflow-x: scroll;
        overflow-y: hidden;
        white-space: nowrap;
    }
    /* 取消滚动条展示 */
    .pane-con::-webkit-scrollbar {
        display: none;
    }
    .inline {
        display: inline-block;
    }
    .tabs-pane {
        padding: 10rpx 20rpx;
        margin-right: 16rpx;
        border: 1px solid lightgrey;
        border-radius: 8rpx;
        transition: all .1s ease-in;
    }
    .tabs-pane:nth-last-child(1) {
      margin-right: 0;
    }
    .tabs-pane.active {
      background: #5495df;
      border-color: #5495df;
      color: #fff;
    }
    

    使用页面代码就不放了因为是正在研发的项目, 按照注释设置参数即可.
    需要传当前值的时候用trigger.event的方法将值传出去接收即可~

    tada~~~一个自定义的tab就完成啦

    相关文章

      网友评论

        本文标题:微信小程序组件: tab标签页

        本文链接:https://www.haomeiwen.com/subject/rpijzrtx.html