programing

클릭한 Vuetify v-tab 항목의 강조 표시 중지 또는 역방향

projobs 2022. 8. 13. 11:36
반응형

클릭한 Vuetify v-tab 항목의 강조 표시 중지 또는 역방향

VueJS하고 있습니다.이 어플리케이션에는 VueJS/Vuetify를 사용하는 .v-tabs/v-tab컴포넌트를 사용하여 페이지 사이를 이동할 수 있습니다.는 이 를 구현했습니다.clickv-tab했을 때 되지 않은 를 하여 v-dialog사용자에게 경고합니다.사용자가 계속하도록 선택하면 원하는 탭/컴포넌트로 넘어갑니다.가 「 」를 했을 경우는, 「 」가 됩니다.Cancel모달에서는 페이지가 원래 있던 자리에 남습니다.

탭 구성 요소는 다음과 같습니다.

<template>
  <div>
    <!-- Tabs -->
    <v-tabs
      color="secondary"
      :value="currentTab"
    >
      <v-tab
        v-for="(tab, i) in userTabs"
        :key="i"
        :href="tab.href"
        @click="tabClick(tab.component, tab.link)"
        :disabled="isDisabled(tab)"
      >
        {{ tab.title }}
      </v-tab>
    </v-tabs>
    <BaseConfirmModal
      :value="showUnsaved"
      :title="unsavedContentTitle"
      :text="unsavedContentText"
      declineText="Cancel"
      @clicked="unsavedModalConfirm"
    />
  </div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex';
import baseTabMixin from '@/components/mixins/workspace/baseTabMixin';

export default {
  name: 'UserTabs',
  data: () => ({
    userTabs: [
      {
        title: 'General Info',
        href: '#tab-general',
        link: 'tab-general',
        component: 'UserEdit',
      },
      {
        title: 'Enrollments',
        href: '#tab-enrollments',
        link: 'tab-enrollments',
        component: 'UserEnrollmentEdit',
      },
      {
        title: 'Alerts',
        href: '#tab-alerts',
        link: 'tab-alerts',
        component: 'UserAlertEdit',
      },
      {
        title: 'Devices',
        href: '#tab-devices',
        link: 'tab-devices',
        component: 'UserDeviceEdit',
      },
    ],
  }),
  computed: {
    ...mapGetters('app', ['getStickyTenant', 'roleAtLeastTa', 'getUnsaved']),
    ...mapGetters('users', ['getCurrent']),
    ...mapGetters('tabs', {
      currentTab: 'getSelected',
    }),
  },
  methods: {
    ...mapActions('tabs', {
      setCurrentTab: 'setSelected',
    }),
    isDisabled(item) {
      if (item.component === 'UserEdit') {
        return false;
      }
      if (item.component === 'UserDeviceEdit' && !this.roleAtLeastTa) {
        return true;
      }

      return !this.getCurrent.userId;
    },
  },
  mixins: [baseTabMixin],
};
</script>

참조된 " " "baseTabMixin:

import { mapGetters, mapActions } from 'vuex';

const baseTabMixin = {
  data: () => ({
    showUnsaved: false,
    unsavedContentTitle: 'Unsaved Changes',
    unsavedContentText: 'You have made changes to this page that are not saved. Do you wish to continue?',
    destTabComponent: '',
    destTabLink: '',
  }),
  components: {
    BaseConfirmModal: () => import('@/components/base/BaseConfirmModal'),
  },
  computed: {
    ...mapGetters('app', ['getUnsaved']),
  },
  methods: {
    ...mapActions('app', ['setUnsaved']),
    tabClick(component, tab) {
      // Check to see if getUnsaved === true; if it is,
      // set variable to display warning modal.
      if (this.getUnsaved) {
        this.showUnsaved = true;
      } else {
        // There is no unsaved content, so continue to the desired tab.
        this.destTabComponent = component;
        this.destTabLink = tab;
        this.setCurrentTab(tab);
        this.$router.push({ name: component });
      }
    },
    unsavedModalConfirm(confirm) {
      if (confirm) {
        this.setCurrentTab(this.destTabLink);
        this.$router.push({ name: this.destTabComponent });
      }
      this.showUnsaved = false;
    },
  },
};

export default baseTabMixin;

이 문제는 탭 항목의 강조 표시와 관련이 있습니다.새하고 새 탭 전에 글씨로 됩니다.tabClick()이 경우)가 호출됩니다.[ Cancel모달에서는 페이지가 원래 위치에 남지만(예상대로) 클릭된 탭은 아래 슬라이더와 굵은 글씨로 강조 표시됩니다.이 모든 것은 클릭 핸들러가 호출되기 전에 이루어지기 때문에 a) 클릭 이벤트가 호출되기 전에 강조 표시를 중지하거나 b) 강조 표시를 현재 탭으로 되돌리는 방법이 있습니까?

작동 중인 펜에 링크합니다.

코드의 주요 부분에 주의해 주세요.-

<v-tabs :value="currentTab" @change="onTabChange">
      <v-tab v-for="(tab, i) in tabs" :key="i">{{tab.title}}</v-tab>
</v-tabs>
async onTabChange(clickedTab)
{
    this.currentTab = clickedTab;
    await this.$nextTick();
    if (!this.allowTabChange) this.currentTab = this.previousTab;
    else this.previousTab = this.currentTab;
}

v-tabs구성 요소는 내부 모델을 사용하여 현재 활성 탭과 같은 상태를 유지합니다.「 」의 :value을 사용하다사용자가 다른 탭을 클릭하면 내부 모델이 업데이트되어 클릭한 탭이 강조 표시됩니다. v-tabs는 이 변경을 부모 컴포넌트에 통지하는 변경 이벤트도 내보냅니다.을 잘 .:value부모 상태를 유지하기 위해 스스로 변수를 지정합니다.★★v-model입니다.:value ★★★★★★★★★★★★★★★★★」@change이 경우, 이 경우, 이 경우.

이벤트를하려면 , 「」를 합니다.@change로로 합니다.v-tabs. 수 @click로로 합니다.@change더 깨끗한 코드를 만들 수 있습니다.

되지 않도록 는 '다'의이기 때문에 까다로운 코드를 해야 합니다.v-tabs을 사용하다.currentTab후.previousTab$nextTick즉, Vue에 의해 현재 업데이트 배치가 픽업된 후.탭 아래의 하이라이트는 다음에 표시됩니다.$nextTick에 우리가 .:value로로 합니다.previousTab그때까지.

가 일시적으로 가 없다면 .currentTab다음 탭의 인덱스로 이동하면 강조 표시가 정상적으로 전환됩니다.을 수 있습니다.currentTab로로 합니다.previousTab , 할 수 .previousTab 값 「」을 .currentTab탭입니다., 「」는,$nextTick해킹은 불필요합니다.

@ParaBolt 그pen CodePen @ @ @ @ 。은 그의 . 왜냐하면 나의 대답은 나의 것이었다.currentTab되어 있습니다. 저는 이 컴포넌트를 했습니다.★★★★★★★★★★★★★★★★★★,filter「」를 component값은 동일하지만 구조는 동일합니다.

믹스인의 중요한 부분은 다음과 같습니다.

 data: () => ({
    ..
    previousTab: '',
  }),
  methods: {
    ...mapActions('app', ['setUnsaved']),
    async tabChange(newTab) {
      this.setCurrentTab(newTab);
      // We need to get the corresponding component value from the tabs array.
      const newComponent = this.tabList.filter(tab => tab.link === newTab)[0].component;
      // Stash these in case we need then in unsavedModalConfirm()
      this.destTabComponent = newComponent;
      this.destTabLink = newTab;
      // Check to see if getUnsaved === true; if it is,
      // set variable to display warning modal.
      await this.$nextTick();
      if (this.getUnsaved) {
        this.setCurrentTab(this.previousTab);
        this.showUnsaved = true;
      } else {
        // There is no unsaved content, so continue to the desired tab.
        this.setCurrentTab(newTab);
        this.$router.push({ name: newComponent });
      }
    },
    unsavedModalConfirm(confirm) {
      if (confirm) {
        // User selected Continue from modal.
        this.setCurrentTab(this.destTabLink);
        this.$router.push({ name: this.destTabComponent });
        this.setUnsaved(false);
      } else {
        // User selected Cancel
        this.setCurrentTab(this.previousTab);
      }
      this.showUnsaved = false;
    },
  },
  mounted() {
    this.previousTab = this.currentTab;
  },

모달에서 취소하면 원래 상태로 유지되며, 계속 진행하면 원하는 탭으로 이동합니다.

언급URL : https://stackoverflow.com/questions/59167213/stop-or-reverse-highlighting-of-clicked-vuetify-v-tab-item

반응형