Я работаю над созданием компонента вкладки с vue и заметил следующее поведение.
Если я создаю свой компонент следующим образом:
<tabs-component>
<tab-component :title="1">
<h1>1</h1>
<p>Lorem ipsum dolor sit amet.</p>
</tab-component>
<tab-component :title="2">
<h1>2</h1>
<p>Lorem ipsum dolor sit amet.</p>
</tab-component>
</tabs-component>
Хуки жизни запускаются в следующем порядке:
- Создан компонент вкладок
- Создан компонент вкладок
- Установлен компонент вкладок
- Установлен компонент вкладок
Что кажетсяОднако, чтобы быть правильным, если вместо того, чтобы объявлять слоты вручную, я использую директиву v-for
, предполагая, что имею дело с некоторыми данными из службы, подобной этой:
<tabs-component>
<tab-component v-for="(type, index) in beerTypes" :key="type.slug" :title="type.slug">
<h1>{{ index }}</h1>
<p>Lorem ipsum dolor sit amet.</p>
</tab-component>
</tabs-component>
Хуки жизни запускаются в этом порядке:
- Создан компонент вкладок
- Установлен компонент вкладок
- Создан компонент вкладок
- Установлен компонент вкладок
Директива v-for
, кажется, портит порядок запуска ловушек.И это вызывает у меня проблемы, так как я запускаю метод selectTab
на смонтированном спасательном хуке, чтобы выбрать выбранную вкладку по умолчанию, но когда запущенные триггеры не смонтированы.
Кто-нибудь знает, как я могуправильно слушать события в правильном порядке или дождаться готовности дочерних компонентов, чтобы я мог выбрать панель по умолчанию?
Вот остаток кода для справки:
App.vue
<template>
<main>
<h1>Discover beer styles</h1>
<tabs-component>
<tab-component v-for="(type, index) in beerTypes" :key="type.slug" :title="type.slug">
<h1>{{ index }}</h1>
<p>Lorem ipsum dolor sit amet.</p>
</tab-component>
</tabs-component>
</main>
</template>
<script>
import axios from 'axios';
import TabsComponent from './components/tabs/Tabs.vue';
import TabComponent from './components/tabs/Tab.vue';
export default {
components: {
'tabs-component': TabsComponent,
'tab-component': TabComponent,
},
data() {
return {
beerTypes: null,
selectedType: null
}
},
filters: {
capitalize: function(value) {
if (!value) return '';
return `${value.charAt(0).toUpperCase()}${value.slice(1)}`;
}
},
mounted() {
axios.get('/data/data.json')
.then((response) => {
this.beerTypes = response.data;
this.selectedType = this.beerTypes[0].slug;
})
.catch((error) => console.log(error));
},
methods: {
selectActiveType: function(selected) {
this.selectedType = selected;
}
}
}
</script>
Tabs.vue
<template>
<div class="tabs-component">
<div>
<ul>
<li v-for="(tab, index) in tabs" :class="{'is-active': tab.isActive}" :key="index">
<a href="#" @click="selectTab(index)">{{ tab.title }}</a>
</li>
</ul>
</div>
<div>
<slot/>
</div>
</div>
</template>
<script>
export default {
data() {
return {
tabs: [],
activeTabIndex: 0
}
},
created() {
this.tabs = this.$children;
},
mounted() {
this.selectTab(this.activeTabIndex);
},
methods: {
selectTab(index) {
this.tabs.forEach(function(tab) {
tab.isActive = (this.tabs.indexOf(tab) === index);
}.bind(this));
}
}
};
</script>
Tab.vue
<template>
<section v-show="isActive">
<slot/>
</section>
</template>
Я ценю, если кто-то может найти время, чтобы помочь мне.
Спасибо!