tab-page-exp.tsx 3.2 KB
import { defineComponent, ref, watch } from 'vue';
import { useNamespace } from '@ibiz-template/vue-util';
import './tab-page-exp.scss';

interface RouteMsg {
  key: string;
  fullPath: string;
  modelPath?: string;
  caption?: string;
}
interface dropdownAction {
  text: string;
  value?: string;
}

export const TabPageExp = defineComponent({
  name: 'TabPageExp',
  props: {
    routeMsgs: {
      type: Array<RouteMsg>,
      required: true,
    },
    currentKey: {
      type: String,
      required: true,
    },
  },
  emits: ['tab-delete', 'tab-click', 'close-all', 'close-other'],
  setup(props, { emit }) {
    const ns = useNamespace('tab-page-exp');
    const tabsValue = ref('0');
    const actions: dropdownAction[] = [
      { text: '关闭所有', value: 'closeAll' },
      { text: '关闭其他', value: 'closeOther' },
    ];

    // 监听currentVal确认当前激活tab
    watch(
      () => props.currentKey,
      (newVal, _oldVal) => {
        const currentRouteMsgIndex = props.routeMsgs.findIndex(
          (msg: RouteMsg) => msg.key === newVal,
        );
        if (currentRouteMsgIndex !== -1) {
          tabsValue.value = `${currentRouteMsgIndex}`;
        }
      },
    );

    // 点击tab
    const changePage = (name: string) => {
      tabsValue.value = name;
      emit('tab-click', +name);
    };

    // 关闭tab
    const onClose = (name: string) => {
      emit('tab-delete', +name);
    };

    // 处理下拉点击
    const handleCommand = (command: string) => {
      if (command === 'closeAll') {
        emit('close-all');
      } else if (command === 'closeOther') {
        emit('close-other');
      }
    };

    return { ns, tabsValue, actions, changePage, onClose, handleCommand };
  },
  render() {
    return (
      <div class={this.ns.b()}>
        <div class={this.ns.e('left')}>
          <i-tabs
            type='card'
            v-model={this.tabsValue}
            closable
            on-on-click={this.changePage}
            on-on-tab-remove={this.onClose}
          >
            {this.routeMsgs?.map((msg: RouteMsg, index: number) => {
              return (
                <i-tab-pane
                  key={msg.key}
                  name={`${index}`}
                  label={msg.caption}
                ></i-tab-pane>
              );
            })}
          </i-tabs>
        </div>
        <div class={this.ns.e('right')}>
          <i-dropdown
            on-on-click={this.handleCommand}
            scopedSlots={{
              default: () => {
                return (
                  <i-button size='small' type='primary'>
                    更多 <ion-icon name='arrow-down'></ion-icon>
                  </i-button>
                );
              },
              list: () => {
                return (
                  <i-dropdown-menu>
                    {this.actions.map((action: dropdownAction) => {
                      return (
                        <i-dropdown-item name={action.value}>
                          {action.text}
                        </i-dropdown-item>
                      );
                    })}
                  </i-dropdown-menu>
                );
              },
            }}
          ></i-dropdown>
        </div>
      </div>
    );
  },
});