vueJS3.x:对于选项卡式导航,我如何引用组件而不加载它



版本:

VueJS: 3.x
Bootstrap: 5.x
Chrome: Version 93.0.4577.63 (Official Build) (x86_64)
macOS: Big Sur 11.5.2

我在这里概述的问题与我几天前提出的问题非常相似;请看我在那里的回答以获得简短的解释。

我通过Bootstrap 5.x样式使用选项卡导航;一个div看起来是这样的:

<div class="tab-content mt-5" id="myTabContent">
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
<Home/>
</div>
<div class="tab-pane fade" id="new-car" role="tabpanel" aria-labelledby="new-car-tab">
<Car/>
</div>
<div class="tab-pane fade" id="scan-barcode" role="tabpanel" aria-labelledby="scan-barcode-tab">
<ScanBarcode/>
</div>
<div class="tab-pane fade" id="about" role="tabpanel" aria-labelledby="about-tab">
<About/>
</div>
</div>

也就是说,我有这样的标签:

Home | New Car | Scan Barcode | About

这里的关键点是所有vueJS组件都作为选项卡导航的一部分呈现到主页上。最终的结果是,我无法使用路由器(即this.$router.push({name: 'Home'}实际上是一个no-op)在选项卡之间导航;也就是说,vueJS路由器正确地认为所有组件都已经在页面上,并且不会引发任何类型的页面刷新。此外,使用我的WebCam的条形码阅读器会立即打开流媒体视频——尽管我可能不在Scan Barcode选项卡上!

问题:如何设置选项卡导航(仍然使用Bootstrap 5.x样式),以便以某种方式延迟加载vueJS组件?IE,我不想加载/安装组件,除非我真的在那个选项卡上。

请参阅vueJS中关于动态组件的文档。

我通过使用类似于HTML单选按钮的<component>解决了这个问题:也就是说,在一个时间点上只有一个选项卡(隐含地说,只有一个组件)处于活动状态。

问题中列出的对我有效的代码的更改是:

<div class="tab-content mt-5" id="myTabContent">
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">
<component :is="getActiveComponentOrNull($options.components.Home.name)"></component>
</div>
<div class="tab-pane fade" id="new-car" role="tabpanel" aria-labelledby="new-car-tab">
<component :is="getActiveComponentOrNull($options.components.Car.name)"></component>
</div>
<div class="tab-pane fade" id="scan-barcode" role="tabpanel" aria-labelledby="scan-barcode-tab">
<component :is="getActiveComponentOrNull($options.components.ScanBarcode.name)"></component>
</div>
<div class="tab-pane fade" id="about" role="tabpanel" aria-labelledby="about-tab">
<component :is="getActiveComponentOrNull($options.components.About.name)"></component>
</div>
</div>

其中$options.components在封装组件/视图定义中提供:

export default {
name: "App",
components: {
About, Home, Car, ScanBarcode
},
...
};

CCD_ 6是在封闭组件上定义的方法,类似于:

methods: {
getActiveComponentOrNull(name) {
if (this.currentComponent == null || this.currentComponent.name != name) {
return null;
}
return this.currentComponent.name
}
}

在我使用的引导程序5个选项卡(即HTMLbutton)中,您需要设置一个@click处理程序,如下所示:

<button @click="currentComponent=$options.components.Home" class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home" type="button" role="tab" aria-controls="home" aria-selected="true">Home</button>

这个解决方案对我有效,尽管它有缺点。例如,对于每个选项卡单击,都会为每个选项卡调用方法getActiveComponentOrNull(在本例中为四次)。也许有一种聪明的方法可以通过计算/反应变量获得相同的行为。

此外,在该解决方案中,选项卡式组件正常卸载也很重要(例如,如果您正在为ScanBarcode使用流式视频,则需要确保在该组件卸载时,它使用的资源(在本例中为视频)正常关闭)。

最新更新