el-button-group按钮组式导航

2,453 阅读1分钟

背景

为什么要实现这么一个玩意呢?因为在UI设计上,设计了一个把按钮组当做三级导航来使用。

image.png

准备工作

ElementUI框架+Vue

方案

UI库中的组件

  1. Button 按钮组

    • 问题:没有默认选中的样式,点击其他地方会失去选中态度。

    image.png

    • <el-button-group>
        <el-button>111111111</el-button>
        <el-button>222222222</el-button>
        <el-button>3333333333</el-button>
      </el-button-group>
      </template>
      
  2. Radio 单选框

    • 问题:不能使用v-show去控制节点的显示和隐藏,会丢失边框的样式。

    image.png

    • <template>
        <el-radio-group v-model="radio1">
          <el-radio-button v-for="(val, index) in data" v-show="index % 2" :label="val"></el-radio-button>
        </el-radio-group>
      </template>
      
      <script>
       export default {
          data () {
            return {
              data: ["上海","北京","广州","深圳"],
              radio1: '广州',
            };
          },
          mounted() {
            // this.init();
          },
          methods: {
            init() {
              setTimeout(() =>{
                this.data=["广州","深圳"];
              },5000);
            }
          }
        }
      </script> 
      

推出的解决方法

  1. Radio-group解决【比较完美】

    • 如上方法,调用init方法。
  2. 使用Button-group解决

    • 动态判断添加class类。默认选中的的样式。

    • <template>
        <div class="btn-group">
          <el-button-group>
            <el-button
              v-for="(value, index) in tabsData"
              :key="uniqueKey ? value[uniqueKey] : index"
              :size="size"
              :icon="value['icon'] || ''"
              :class="{ selectBtn: currSelectIndex === (uniqueKey ? value[uniqueKey] : index) }"
              :readonly="isReadonly"
              @click="handleBtn(value[uniqueKey] || '', index)"
            >
              {{ showField ? value[showField] : value }}
            </el-button>
          </el-button-group>
          <!-- @slot 右侧自定义-->
          <slot />
        </div>
      </template>
      <script>
      export default {
        name: 'NavBtnGroup',
        extends: 'ButtonGroup',
        props: {
          /**
           * 是否可读
           */
          isReadonly: {
            type: Boolean,
            default: false,
          },
          /**
           * 按钮组数据集
           */
          tabsData: {
            type: Array,
            default: ()=>([])
          },
          /**
           * v-for循环中的key值
           */
          uniqueKey: {
            type: String,
            default: '',
          },
          /**
           * 页面需要展示的字段
           */
          showField: {
            type: String,
            default: '',
          },
          /**
           * 按钮大小
           * medium / small / mini
           */
          size: {
            type: String,
            default: '',
          },
          /**
           * 图标
           */
          icon: {
            type: String,
            default: '',
          },
        },
        data() {
          return {
            currSelectIndex: 0,
          };
        },
        mounted () {
          this.currSelectIndex = this.uniqueKey ? this.tabsData[0][this.uniqueKey] : 0;
        },
        methods: {
          handleBtn(uniqueVal, index) {
            this.currSelectIndex = uniqueVal || index;
            this.$emit('handleBtn', { currSelectIndex: index, uniqueVal });
          },
        },
      };
      </script>
      
      <style scoped lang="scss">
      .selectBtn {
        color: #337dbf;
        border-color: #337dbf;
        background-color: #e6eeff;
        border-left-color: #337dbf;
        box-shadow: 1px 0 0 0;
        z-index: 1;
      
        &.el-button:not(:last-child) {
          margin-right: 0;
          border-right: none;
        }
      
        &.el-button--default:not(.is-disabled):last-child {
          border-left-color: #337dbf;
          border-right: none;
        }
      
        &.el-button--default:not(.is-disabled):not(:first-child):not(:last-child) {
          border-left-color: #337dbf;
        }
      }
      
      .btn-group {
        margin-bottom: 16px;
        display: flex;
        justify-content: space-between;
      }
      </style>
      
      

总结

  1. 使用radio-group去解决nav式的导航是最好的。但是需要注意,数据只做替换,不用v-show去控制节点显隐。
  2. 经验可以作为解决问题的一个参考,但也要求我们实事求是,全面的去考虑问题。也许你的问题早已被大家解决。