【问题标题】:How can I display immediately the new opened tab contents in BootstrapVue?如何在 BootstrapVue 中立即显示新打开的选项卡内容?
【发布时间】:2020-09-02 07:22:38
【问题描述】:

早上好,

我的目标如下:

每次打开新标签页时,它都会变为“活动”状态,并且浏览器会显示其内容

  • 问题:每次打开新选项卡时,之前打开的选项卡都保持“活动”状态。

Look at a trivial example of the problem.

为了重现问题:

  1. 访问BootstrapVue Playground;
  2. 滚动到页面底部,在标题为“动态选项卡 + 选项卡末端槽”的部​​分中(在高级示例部分中提供);
  3. 在代码区双击(可以修改);
  4. 粘贴以下代码
<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>
  1. 尝试通过单击呈现区域中的“+”按钮添加新选项卡,该按钮位于粘贴代码的开头。

我做错了什么?

【问题讨论】:

标签: javascript vue.js tabs bootstrap-vue


【解决方案1】:

使用 b-tabs

  1. 事件:changed
  2. 属性:v-model
<b-tabs v-model="tabActive" @changed="onTabChanged">

data() {
  return {
    tabActive: 0,
    tabs:[],
  }

onTabChanged() {
  this.tabActive = this.tabs.length - 1;
},

【讨论】:

  • 但是如果你删除一个标签,最后一个标签会变为活动状态。
【解决方案2】:

您可以通过将active 属性添加到&lt;b-tab&gt; 来做到这一点,这将使新创建的选项卡成为活动选项卡。

<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/bootstrap@4.5.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap-vue@2.16.0/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/bootstrap-vue@2.16.0/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>

【讨论】:

  • 对不起,我评论错了。非常感谢您的解决方案。
【解决方案3】:

你好,米歇尔·罗西托,

组件 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>

有帮助吗?

【讨论】:

  • 请不要使用我的“解决方案”,使用 Hiws one :)
  • 是的@Fabio Garcia,通过这个解决方案,我可以更好地理解问题并思考它:它解决了我的问题。现在要了解您提出的第二种解决方案在性能方面是否更好。
猜你喜欢
  • 2019-06-14
  • 2014-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-11
  • 1970-01-01
相关资源
最近更新 更多