问题描述
早上好
我的目标是:
每次打开新标签页时,该标签页都将变为“活动”状态,并且浏览器会显示其内容
Look at a trivial example of the problem.
为了重现问题:
- 访问BootstrapVue Playground;
- 滚动到页面底部的“ Dynamic tabs + tabs-end slot”部分(在高级示例部分中提供);
- 双击代码区域(以便进行修改);
- 粘贴以下代码
<template>
<div>
<b-card no-body>
<b-tabs card>
<!-- Render Tabs,supply a unique `key` to each tab -->
<b-tab v-for="tab in tabs" :key="tab.id" :class="{active:tab.isActive}" :title="'Tab ' + tab.id">
Tab contents {{ tab.id }}
<b-button size="sm" variant="danger" class="float-right" @click="closeTab(tab.id)">
Close tab
</b-button>
</b-tab>
<!-- New Tab Button (Using tabs-end slot) -->
<template v-slot:tabs-end>
<b-nav-item role="presentation" @click.prevent="newTab" href="#"><b>+</b></b-nav-item>
</template>
<!-- Render this if no tabs -->
<template v-slot:empty>
<div class="text-center text-muted">
There are no open tabs<br>
Open a new tab using the <b>+</b> button above.
</div>
</template>
</b-tabs>
</b-card>
</div>
</template>
<script>
export default {
data() {
return {
tabs: [],tabCounter: 0,activeTab: {}
}
},methods: {
closeTab(x) {
for (let i = 0; i < this.tabs.length; i++) {
if (this.tabs[i].id === x) {
this.tabs.splice(i,1)
}
}
},newTab() {
const newTab = {
id: this.tabCounter,isActive: true
};
this.tabCounter++;
this.tabs.push(newTab);
this.setActive(newTab);
},setActive(tab) {
tab.isActive = true;
this.activeTab = tab;
this.tabs.forEach((tab) => {
if (tab.id !== this.activeTab.id) {
tab.isActive = false;
}
})
}
}
}
</script>
我在做什么错了?
解决方法
使用 b-tabs
<b-tabs v-model="tabActive" @changed="onTabChanged">
data() {
return {
tabActive: 0,tabs:[],}
onTabChanged() {
this.tabActive = this.tabs.length - 1;
},
,
您可以通过在active
上添加<b-tab>
道具来完成此操作,这将使新创建的标签页成为活动标签页。
<b-tab active ...>
示例
new Vue({
el: "#app",data() {
return {
tabs: [],tabCounter: 0
}
},methods: {
closeTab(x) {
for (let i = 0; i < this.tabs.length; i++) {
if (this.tabs[i] === x) {
this.tabs.splice(i,1)
}
}
},newTab() {
this.tabs.push(this.tabCounter++)
}
}
});
<link href="https://unpkg.com/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/[email protected]/dist/bootstrap-vue.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/bootstrap-vue.js"></script>
<div id="app">
<b-card no-body>
<b-tabs card>
<!-- Render Tabs,supply a unique `key` to each tab -->
<b-tab v-for="i in tabs" :key="'dyn-tab-' + i" :title="'Tab ' + i" active>
Tab contents {{ i }}
<b-button size="sm" variant="danger" class="float-right" @click="closeTab(i)">
Close tab
</b-button>
</b-tab>
<!-- New Tab Button (Using tabs-end slot) -->
<template v-slot:tabs-end>
<b-nav-item role="presentation" @click.prevent="newTab" href="#"><b>+</b></b-nav-item>
</template>
<!-- Render this if no tabs -->
<template v-slot:empty>
<div class="text-center text-muted">
There are no open tabs<br>
Open a new tab using the <b>+</b> button above.
</div>
</template>
</b-tabs>
</b-card>
</div>
,
您好,MIchele Rosito,
b-tabs组件接受一个值,该值是选定的选项卡索引(通过v-model传递)
下面我有一个工作原型的简化版本,我认为它可以完成您的工作。
但是有一个陷阱,添加一个新选项卡时,将通过在(虚拟)DOM上引导来呈现它,这将花费一些时间,并且我们无法选择尚未呈现的选项卡。
“解决方案”(不是很好的绷带)是给它几毫秒的时间,然后才更改“ tabIndex”以给标签渲染一些时间。
这不是最佳的生产解决方案,但我认为它可以为您指明正确的方向。
<template>
<div>
<b-card no-body>
<b-tabs card v-model="tabIndex">
<!-- Render Tabs,supply a unique `key` to each tab -->
<b-tab v-for="tab in tabs" :key="tab.id" :class="{active:tab.isActive}" :title="'Tab ' + tab.id">
Tab contents {{ tab.id }}
<b-button size="sm" variant="danger" class="float-right" @click="closeTab(tab.id)">
Close tab
</b-button>
</b-tab>
<!-- New Tab Button (Using tabs-end slot) -->
<template v-slot:tabs-end>
<b-nav-item role="presentation" @click.prevent="newTab" href="#"><b>+</b></b-nav-item>
</template>
<!-- Render this if no tabs -->
<template v-slot:empty>
<div class="text-center text-muted">
There are no open tabs<br>
Open a new tab using the <b>+</b> button above.
</div>
</template>
</b-tabs>
</b-card>
</div>
</template>
<script>
export default {
data() {
return {
tabs: [],tabIndex: 0,tabCounter: 0,activeTab: {}
}
},methods: {
closeTab(x) {
for (let i = 0; i < this.tabs.length; i++) {
if (this.tabs[i].id === x) {
this.tabs.splice(i,1)
}
}
},newTab() {
const newTab = {
id: this.tabCounter,};
this.tabCounter++;
this.$set(this,tabs,this.tabs.push(newTab));
setTimeout(() => { this.tabIndex = this.tabs.length;},100);
}
}
}
</script>
有帮助吗?