如何在vue class组件中访问$bvToast

How to access $bvToast in vue class component

我是 vue.js 的新手,但我可以弄清楚一些事情。我从普通的 js 开始,但现在切换到带有 class 样式 vue 组件的打字稿。对于组件样式,我使用 bootstrap-vue.

在我的 main.ts 文件中我导入了 bootstrap 以及 vuex store

...
import BootstrapVue from 'bootstrap-vue'
//use custom bootstrap styling
import '../src/bootstrap/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.use(BootstrapVue)

...//some more code

new Vue({
 router,
 store,
 i18n,
 render: h => h(App)
}).$mount('#app')

在商店里我动态注册了一个NotificationModule

NotificationModule.ts

//import node modules
import { Module, VuexModule, Mutation, Action } from "vuex-module-decorators";
import { store } from "@/store";

//import application modules
import i18n from '@/i18n';

import Notification from '../types/Notification';
import Message from '../types/Message';
import logger from '@/system/logger';

@Module({
    dynamic: true,
    store: store,
    name: "notification",
    namespaced: true,
})
export default class NotifcationModule extends VuexModule {

  //notification types definition with according prompts
  notificationTypes: Array<string> = ['info', 'success', 'warning', 'danger'];

  //definition of the notification object
  notification: Notification = {
      variant: '',
      prompt: '',
      message: ''
  }

  /**
   * prove the supported notification types
   */
  get getSupportedNotificationTypes(): Array<string> {
      return this.notificationTypes;
  }

  /**
   * provide the notification
   */
  get getNotification(): Notification {
    return this.notification;
  }

  @Action
  notify(msg: Message){

    logger.warn(`called notify with [type:${msg.variant}]:[text:${msg.text}]`);

    if(msg.variant === undefined || !Array.from(this.notificationTypes).includes(msg.variant)){
      msg.variant = 'info';
    }

    //configure custom notification data
    const notification = {
        variant: msg.variant,
        prompt: i18n.t(`notify.${msg.variant}`),
        message: msg.text || 'No message provided.'
    }

    this.context.commit('setNotification', notification);
  }

  @Mutation
  public setNotification(data: Notification) {
      if (data) {
          this.notification = data;
      }
  }
}

一切正常。我可以在生成通知的 vue 组件中获取该商店的一个实例,但我在以下 vue 组件中创建 toast 时遇到了问题。

Notification.vue

<template>
  <b-container></b-container>
</template>

<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator';
import { getModule, VuexModule } from 'vuex-module-decorators';
import NotificationModule from '../../util-notification/components/NotificationModule';
import Notification from '../types/Notification';
import logger from '../../../system/logger';

@Component
export default class UserNotification extends Vue {

  //get the instance of the NotificationModule
  noticationInstance: NotificationModule = getModule(NotificationModule);

  //watch the property 'notification' -> accessed via getter method
  @Watch('noticationInstance.getNotification')
  onPropertyChange(notification: Notification, oldValue: string) {
    logger.debug(`replaced [${JSON.stringify(oldValue)}] by [${JSON.stringify(notification)}]`);

    //create a toast
    this.$bvToast.toast(notification.message, {
      title: notification.prompt || 'Info',
      variant: notification.variant || 'warning',
      solid: true
    });


  }
}
</script>

在文件 Vetur 中,虽然它编译了,但它给我以下错误。但是没有制作和展示祝酒词。

属性 '$bvToast' 在类型 'UserNotification'.Vetur(2339) 上不存在

我创建了一个 TestView,其中我以不同的方式集成了 $bvToast,它在那里工作。

<template>
  <b-container fluid>
    <h1>This is the page for testing components and functionality</h1>
    <hr>
    <div>
      <h3>Trigger für vuex notification test</h3>
      <b-button @click="$bvToast.show('example-toast')" class="mb-2">Default</b-button>
    </div>

    <b-toast id="example-toast" title="BootstrapVue" static no-auto-hide>
      Hello, world! This is a toast message.
    </b-toast>

  </b-container>
</template>

你对我做错了什么有什么建议吗? 谢谢你

问题已解决或效果更好

我真的不知道为什么,但现在可以用了!没有进一步的变化。对不起,我不能再重现这个了。另外 webconsole 也没有显示任何错误。

看来我可以在我的 UserNotification 组件中访问 vue 实例。 UserNotification 扩展了 Vue,所以它是一个 Vue 实例而不是 VueX。答案中描述的解决方案不是必需的。

有没有可能只有 Vetur 不将 $vbToast 识别为 UserNotification 的 属性 甚至是 typscript 上下文中的扩展 Vue 实例?

VueX的this上下文不是Vue实例,所以this.$bvToast不能直接使用

但是有一种解决方法可以访问 VueX 中的主 Vue 实例。请改用 this._vm.$bvToast

参见: