IT이야기

Vuetify 탭을 Vue-Router와 함께 사용하는 방법

cyworld 2022. 3. 7. 21:32
반응형

Vuetify 탭을 Vue-Router와 함께 사용하는 방법

나는 다음의 두 개의 Vuetify 탭이 있는 jsfiddle을 가지고 있다.설명서에 사용 예제가 표시되지 않음vue-router그들과 함께.

나는 Medium.com에 Vuetify를 사용하는 방법에 관한 을 발견했다.vue-router는 다음과 같은 코드를 가지고 있다.

<div id="app">
  <v-tabs grow light>
    <v-tabs-bar>
      <v-tabs-item href="/" router>
        <v-icon>motorcycle</v-icon>
      </v-tabs-item>
      <v-tabs-item href="/dog" router>
        <v-icon>pets</v-icon>
      </v-tabs-item>
    </v-tabs-bar>
  </v-tabs>

  <router-view />
</div>

그러나 Vuetify 1.0.13 설명서에 다음 항목이 지정되지 않아 코드가 오래된 경우router그들의 api에 소품을 넣어, 그래서 포스트에 내장된 예는 효과가 없다.

나는 또한 다음과 같은 코드를 가진 StackOverflow 답변을 발견했다.

<v-tabs-item :to="{path:'/path/to/somewhere'}">

그러나, 사용to프로펠러가 작동하지 않고 Vuetify api에도 나열되지 않는다.대조적으로, The는v-buttonVuetify 구성 요소가to지지하고 활용하다vue-router, 그래서 나는 a를 기대한다.vue-router하기 위해 요소는 다음과 같다.to받침대

낡은 뷔에티파이 0.17 문서들을 뒤적거리면서,to을 위해 소품이 지정되다.v-tabs-item. 1.0.13에 지원이 제거되었을 것으로 보인다.

사용 방법vue-router뷔에티파이 탭으로?

갱신하다

어머나!뷔에티파이 커뮤니티에 api에 문서를 추가해 달라고 했더니 방금 api를 추가한 것 같다.to다른 것뿐만 아니라 다른 것들도 지지하다.vue-routerVuetify문서에 대한 소품.정말로, 그곳의 공동체는 멋지다.

오리지널

Vuetify community Disclosure에 있는 사람들이 나를 도울 수 있었다.나의 업데이트된 jsfiddle은 이제 작동 코드를 가지고 있다.

본질적으로v-tab의 포장지다.router-link슬롯을 사용하여 소품을 전달할 경우router-link , , , , , ,,, . . . . .to을 떠받치다.v-tab효과가 좋다

작업 코드의 예는 다음과 같다.

html

<v-app dark>
  <v-tabs fixed-tabs>
    <v-tab to="/foo">Foo</v-tab>
    <v-tab to="/bar">Bar</v-tab>
  </v-tabs>
  <router-view></router-view>
</v-app>

js

const Foo = {
  template: '<div>Foo component!</div>'
};

const Bar = {
  template: '<div>Bar component!</div>'
};

const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar },
];

const router = new VueRouter({ routes });

new Vue({
  el: '#app',
  router,
});

결과

Foo 탭 예제 막대 탭 예제

템플릿 부분:

<div>
    <v-tabs
      class="tabs"
      centered
      grow
      height="60px"
      v-model="activeTab"
    >
      <v-tab v-for="tab in tabs" :key="tab.id" :to="tab.route" exact>
        {{ tab.name }}
      </v-tab>
    </v-tabs>
    <router-view></router-view>
</div>

그리고 js 부분:

  data() {
    return {
      activeTab: `/user/${this.id}`,
      tabs: [
        { id: 1, name: "Task", route: `/user/${this.id}` },
        { id: 2, name: "Project", route: `/user/${this.id}/project` }
      ]
    };
  }

경로:

{
  path: "/user/:id",
  component: User1,
  props: true,
  children: [
    {
      path: "", //selected tab by default
      component: TaskTab
    },
    {
      path: "project",
      component: ProjectTab
    }
  ]
}

코드 상자 예제 참조

여기에 애니메이션과 관련된 몇 가지 팁을 추가해서 사용법을 명확히 하는 겁니다.v-tab-itemsv-tab-item.

다음과 같은 작업 표시 기능을 사용하면 v-tab 탭 스위치 애니메이션이 작동하지 않을 수 있음:

<v-tabs v-model="activeTab">
  <v-tab key="tab-1" to="/tab-url-1">tab 1</v-tab>
  <v-tab key="tab-2" to="/tab-url-2">tab 2</v-tab>
</v-tabs>
<router-view />

탭 스위치 애니메이션을 유지하려면 이 방법을 사용하십시오.

<v-tabs v-model="activeTab">
  <v-tab key="tab-1" to="/tab-url-1" ripple>
    tab 1
  </v-tab>
  <v-tab key="tab-2" to="/tab-url-2" ripple>
    tab 2
  </v-tab>

  <v-tab-item id="/tab-url-1">
    <router-view v-if="activeTab === '/tab-url-1'" />
  </v-tab-item>
  <v-tab-item id="/tab-url-2">
    <router-view v-if="activeTab === '/tab-url-2'" />
  </v-tab-item>
</v-tabs>

또한 a를 사용할 수 있다는 점에 유의하십시오.v-for반복하다v-tab그리고v-tab-item태그가 당신의 것만큼 길다.to에서 id당신의 속성v-tab-items

탭 단추와 다른 위치에 탭 내용을 배치해야 하는 경우v-tab-items에 대한 것이다.당신은 그것을 배치할 수 있다.v-tab-item in a에 s a s.v-tab-items밖에서 술래잡기를 하다.v-tabs구성 요소반드시 a를 주어라.v-model="activeTab"기여하다

@roli-rolli와 @antoni의 답은 큐브하지만 아주 작은 디테일이 부족하다.실제로 모바일 보기에서는 (거의 거의 동등한) 방법을 사용할 때 문제가 발생하며, 실제로 이러한 조건에서는 탭을 지울 수 있다.문제는 스위핑이 예상대로 경로를 업데이트하지 못해 구성요소 A가 있는 탭 A에서 구성요소 B가 있는 탭 B로 넘어가고, 대신 애니메이션이 발사되고 해당 경로에 대한 정보가 제공된다는 점이다.activeTab라우터는 변경되지만 업데이트되지 않는다.

TL;DR 스위핑v-tab-item라우터를 업데이트하지 않고 각 탭 아래에 동일한 구성요소가 있다.

솔루션이 의 스와이퍼 기능을 비활성화할 수 있음v-tab-item또는 의 변경 이벤트를 청취하는 것tab그에 따라 라우터를 업데이트하는 구성 요소.나는 이 두 번째 해결책을 조언하고 싶다. (스위핑은 어떤 상황에서는 꽤 유용하기 때문에) 그러나 나는 탭의 라벨을 클릭할 때 라우터 업데이트가 두 번 트리거될 것이라고 생각한다.

여기 @roli-rolli 답변을 바탕으로 한 작업 예가 있다.

템플릿

<template>
    <v-tabs v-model="activeTab">
        <v-tab v-for="tab in tabs" :key="tab.id" :to="tab.route">{{ tab.name }}</v-tab>

        <v-tabs-items v-model="activeTab" @change="updateRouter($event)">
            <v-tab-item v-for="tab in tabs" :key="tab.id" :to="tab.route">
                <router-view />          
            </v-tab-item>
        </v-tabs-items>
    </v-tabs>
</template>

스크립트

export default {
    data: () => ({
        activeTab: '',
        tabs: [
            {id: '1', name: 'Tab A', route: 'component-a'},
            {id: '2', name: 'Tab B', route: 'component-b'}
        ]
    }),
    methods: {
        updateRouter(val){
            this.$router.push(val)
        }
    }
}

라우터

이전 답변과 같이 설정하십시오.

//urls in some componet
<v-btn @click="goToUrl({name: 'RouteName1'})">
    .....
<v-list-item-title 
    @click="goToUrl({name: 'RouteName2'})"
>
    Some tab link text
 </v-list-item-title>
    ....


//tabs menu and content in other component
<v-tabs>
    <v-tab key="key_name1" :to="{ name: 'RouteName1'}">Some link 1</v-tab>
    <v-tab key="key_name2" :to="{ name: 'RouteName2'}">Some link 2</v-tab>

<v-tab-item key="key_name1" value="/url/for/route1">
    ....
<v-tab-item key="key_name2" value="/url/for/route2">
    ....

애니메이션 및 스와이프가 활성화된 경우

기존 쿼리 매개 변수를 유지하십시오. 예를 들어 URL에 :로케일이 있는 경우:

템플릿

<v-tabs v-model="activeTab">
   <v-tab v-for="tab in tabs" :key="tab.id" :to="tab.to">
    {{ tab.name }}
  </v-tab>
</v-tabs>

<v-tabs-items v-model="activeTab" @change="updateRouter($event)">
  <v-tab-item v-for="tab in tabs" :key="tab.id" :value="tab.to">
    <router-view />          
  </v-tab-item>
</v-tabs-items>

스크립트

export default {
  data: () => ({
    activeTab: '',
  }),
  computed: {
    tabs() {
      return [
        { id: 1, name: 'Tab one', to: this.getTabPath('routeName1') },
        { id: 2, name: 'Tab two', to: this.getTabPath('routeName2') },
        { id: 3, name: 'Tab three', to: this.getTabPath('routeName3') },
        { id: 4, name: 'Tab four', to: this.getTabPath('routeName4') },
      ]
    },
  },
  methods: {
    getTabPath(name) {
      // Get the path without losing params. Usefull e.g. if you have a :locale in your url:
      return this.$router.resolve({ name, params: this.$route.params }).href
    },
    updateRouter(path) {
      // Gets called upon swipe.
      this.$router.push(path)
    },
  },
}

사용.$router.resolve여기에 설명된 대로 경로 객체로부터 경로를 얻으십시오.

탭이 전환될 때 새 구성요소를 이중으로 장착하기 위한 수정사항을 추가하고자 한다.여기서 질문과 답변을 볼 수 있다.

TLDR은 에서 v-for를 사용하면 각 스위치에서 전환하려는 구성 요소가 생성, 제거 및 다시 생성되는 문제에 직면하게 된다는 것이다.만약, 나처럼, 당신이 그것의 창조측면에서 아약스콜을 한다면, 당신은 모든 탭스위치에 대해 당신의 백엔드를 두 번 칠 것이다.당신은 그것을 막기 위해 a로 포장할 수 있다.

왜 이런 일이 일어나는지에 대해 깊이 생각하게 된다.

다음 코드는 나에게 효과가 있다.

  <v-tabs fixed-tabs>
          <v-tab>Locations</v-tab>
          <v-tab>Employees</v-tab>
          <v-tab-item>Tab 1 content
            <locations-data/>
          </v-tab-item>
          <v-tab-item>Tab 2 content
            <employees-data/>
          </v-tab-item>
    </v-tabs>
   <script>
        import LocationsData from './Settings/Locations';
        import EmployeesData from './Settings/Employees';
        export default {
           components: {
            LocationsData,
            EmployeesData
          },
        }
   </script>

참조URL: https://stackoverflow.com/questions/49721710/how-to-use-vuetify-tabs-with-vue-router

반응형