Vue.js + Bootstrap - question - invoking $bvToast from store.js - vue.js

I have probably very profoundly simple question: how to invoke methods located in components from store.js, for instance I want a toast popup from store mutation. Any ideas?

The $bvToast can be found in BToast export. You can import it to use it.
import { BToast } from 'bootstrap-vue'
Example Class
import { BToast } from 'bootstrap-vue'
class uiUtils
{
showToast(message : string,title : string){
let bootStrapToaster = new BToast();
bootStrapToaster.$bvToast.toast(message, {
title: title,
toaster: "b-toaster-top-right",
solid: true,
appendToast: false
})
}
}
export default new uiUtils();
The documentation does show the individual component exports at the bottom of the page and can be found here Bootstrap Vue Documentation.

Related

How can I access ngOffline directive in a component instead of html

I'm using this npm library https://www.npmjs.com/package/ng-offline to alert end user when offline.
<div class="alert alert-danger" ngOffline>You're offline. Check your connection!</div>
stackblitz here: https://stackblitz.com/edit/angular-ngoffline-npm?file=src%2Fapp%2Fapp.component.html
Works great - BUT I want to open a modal with this ngOffline directive, so I'm trying to access the directive from my angular 11 component but not sure how to approach this, any help on this would be greatly appreciated.
Is there away for me to open a ngx-bootstrap modal from the html with this directive?
Because the ng-offline module isn't exporting things as you might expect (i.e. you can't inject a standalone NgOfflineDirective for you to use without having it in your html file), you could add a block like this (where you've used #trigger to identify your ngOnline element):
import { AfterContentChecked, Component, ElementRef, OnDestroy, ViewChild } from '#angular/core';
import { BehaviorSubject, Subscription } from 'rxjs';
import { distinctUntilChanged, filter } from 'rxjs/operators';
#Component({ ... })
export class YourClass implements AfterContentChecked, OnDestroy {
offline$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>();
subscription: Subscription;
#ViewChild('trigger') trigger: ElementRef;
constructor() {
this.subscription = this.offline$.pipe(
distinctUntilChanged(),
filter((offline: boolean) => offline),
).subscribe(() => this.showModal());
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
ngAfterContentChecked() {
if (
this.trigger &&
this.trigger.nativeElement
) {
this.offline$.next(this.trigger.nativeElement.style.display === "none");
}
}
showModal() {
console.log('Show your modal here.');
}
}

Ionic 5, Vue 3 - How to use Ionic lifecycle hooks inside setup()?

The Ionic documentation describes how to use the Ionic lifecycle methods like ionViewWillEnter, ionViewDidEnter etc. inside Vue method.
https://ionicframework.com/docs/vue/lifecycle
I'm looking for a way to access them inside the new Vue 3 setup() method so that I can able to access the properties defined there. Is it something possible?
export default defineComponent({
...
setup(){
const list = ref([]);
// I need something like this
const ionViewDidEnter = () => {
list.value.push(...['some', 'array', 'here']);
},
return {
list,
ionViewDidEnter
};
}
});
This is now possible in a composition API style since this PR was merged
https://github.com/ionic-team/ionic-framework/pull/22970
export default defineComponent({
...,
components: { IonPage },
setup() {
onIonViewDidEnter(() => {
console.log('ionViewDidEnter!');
});
}
});
Unfortunately no, at least not yet, since the code firing the events is specifically looking for the lifecycle events to be registered as part of the component methods. Luckily I've submitted a PR which is going to fix this and allow you to define them the same way you would define mounted or any other Vue hooks.
I will make sure to add tests that cover the composition API scenario as well.
https://github.com/ionic-team/ionic-framework/pull/22241
Meaning that you'd be able to do it this way:
export default defineComponent({
...
ionViewDidEnter() {
...
},
setup(){
...
}
});
Just to add to what Mark Beech said, you will have to import onIonViewDidEnter
import { onIonViewDidEnter } from '#ionic/vue';
export default defineComponent({
...
ionViewDidEnter() {
console.log('Hompage');
},
setup(){
...
}
});

How to use my own class inside a Vue file

I'm making a webpage using Nuxt and I would like to make a class and use it in one of my .vue files. I've tried using an import: import Card from "~/assets/mylib/Card.js" but that doesn't work. Not sure how to access my Card.js file inside of a .vue file.
index.vue
import Card from "~/assets/mylib/Card.js"
created() {
let card = new Card("blue")
}
Card.js
class Card {
constructor(color) {
this.color = color
}
}
error:
_assets_mylib_Card_js__WEBPACK_IMPORTED_MODULE_4___default.a is not a constructor
Modify Card.js as follows:
export default class Card {
constructor(color) {
this.color = color
}
}
Then import it from within index.vue as follows:
import { Card } from "~/assets/mylib/Card"
you have to update your Card.js like beow
export class Card {
constructor(color) {
this.color = color
}
}
and import in vue file like below
import { Card } from "~/assets/mylib/Card"

Nuxtjs using Vuex-module-decorator doesn't wordk

I want to use my vuex modules as classes to make my code more clean and readable. I used the section (Accessing modules with NuxtJS) at the bottom of this document: https://github.com/championswimmer/vuex-module-decorators/blob/master/README.md
I've searched for the solution for almost 3 days and tried out this link:
vuex not loading module decorated with vuex-module-decorators
but, it didn't work.
Also, I used getModule directly in the component like the solution in this issue page: https://github.com/championswimmer/vuex-module-decorators/issues/80
import CounterModule from '../store/modules/test_module';
import { getModule } from 'vuex-module-decorators';
let counterModule: CounterModule;
Then
created() {
counterModule = getModule(CounterModule, this.$store);
}
Then, accessing method elsewhere
computed: {
counter() {
return counterModule.getCount
}
}
it didn't work for me!
This is my Module in store folder in Nuxtjs project:
import { ICurrentUser } from '~/models/ICurrentUser'
import { Module, VuexModule, Mutation, MutationAction } from 'vuex-module-decorators'
#Module({ stateFactory: true, namespaced: true, name: 'CurrentUserStore' })
export default class CurrentUser extends VuexModule {
user: ICurrentUser = {
DisplayName: null,
UserId: null,
};
#Mutation
setUser(userInfo: ICurrentUser) {
this.user = userInfo;
}
get userInfo() {
return this.user;
}
}
In index.ts file in sore folder:
import { Store } from 'vuex'
import { getModule } from 'vuex-module-decorators'
import CurrentUser from './currentUser'
let currentUserStore: CurrentUser
const initializer = (store: Store<any>): void => {
debugger
currentUserStore = getModule(CurrentUser, store)
}
export const plugins = [initializer]
export {
currentUserStore,
}
I think the problem stems from this line:
currentUserStore = getModule(CurrentUser, store)
currentUserStore is created as object but properties and methods are not recognizable.
when I want to use getters or mutation I get error. For instance, "unknown mutation type" for using mutation
Probably several months late but I struggled with a similar issue, and eventually found the solution in https://github.com/championswimmer/vuex-module-decorators/issues/179
It talks about multiple requirements (which are summarised elsewhere)
The one that relates to this issue is that the file name of the module has to match the name you specify in the #Module definition.
In your case, if you rename your file from currentUser to CurrentUserStore' or change the name of the module toCurrentUser`, it should fix the issue.

Loading component asynchronously in Vue.js does not work

I am trying to replace loading v-tooltip's VPopper component from standard loading to asynchronous loading.
Standard loading - component loaded and working normally
import { VPopover } from 'v-tooltip'
export default {
components: {
VPopover
}
}
Asynchronous load - component not loaded correctly
export default {
components: {
VPopover: () => import('v-tooltip')
},
}
For some reason above is not working and component is not loaded correctly. Maybe because it’s not a default export but named export in the v-tooltip Vue component?
I am using Webpack in-behind.
If I load my custom component asynchronously then it works as expected. For example this is working for me:
export default {
components: {
MyCustomComponent: () => import('#/components/MyCustomComponent.vue')
}
}
Like #gugadev has noted above
The lazy module import returns a Promise with the module export, in
your case an object containing the named export. Vue don't know what
of the named exports should import, so, simply does nothing.
I found this solution that works
export default {
components: {
VPopover: () => import('v-tooltip').then(m => m.VPopover)
}
}