Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to access $store / Vue i18n / ... in custom toast component? #26

Open
Nicolas-Yazzoom opened this issue Feb 22, 2022 · 4 comments
Open

Comments

@Nicolas-Yazzoom
Copy link

Hello,

I've been using this plugin for a long time in fairly big Nuxt project. One long standing issue that I can't seem to get fixed has to do with #11

Here you explain creating a second root instance is intentional but one of the side effects of this is that it makes some important things unavailable in my custom toast component. These include Vue i18n, the store and some other plugins. How can I access these inside my custom component, preferably in a seamless way?

Thanks in advance,
-N

@mediv0
Copy link
Contributor

mediv0 commented Feb 22, 2022

hello,

For situations like this you can use an Event bus

for example when using i18n ( your main project )

const val = this.$i18n.t(ValueToChange);
bus.emit(data, val);

and in your toast:

bus.on(data, () => {} )

there is another way to fix this, by passing Main Vue Instance as parameter to the second instance but i dont think this package is maintained anymore

// when installing the plugin ( index.js )
Vue.prototype.$toasts = {
    ctx: Vue.prototype,
   . . .
  }

// after Vue.use you can access vue instance in your project like:
this.$toasts.ctx.$store()
this.$toasts.ctx.$I18n()

if you wanna go with second approach you can build the project yourself

@Nicolas-Yazzoom
Copy link
Author

Nicolas-Yazzoom commented Feb 23, 2022

I see how the second approach could solve the issue. So there's no way to achieve something similar without creating my own build of the project?

@mediv0
Copy link
Contributor

mediv0 commented Feb 23, 2022

hi again there is another way without building

in your plugin file when importing the package, you can do something like this:

import Vue from "vue";
import VueMyToasts from "vue-my-toasts";
import "vue-my-toasts/dist/vue-my-toasts.css";
import YourToastComponent from "~/components/YourToastComponent";

Vue.use(VueMyToasts, {
  component: YourToastComponent,
  options: {
    width: "400px",
    position: "bottom-right",
    padding: "1rem",
  },
});

Vue.prototype.$toasts = Object.assign(Vue.prototype.$toasts, {
  ctx: Vue.prototype,
});

let me know if it works for you
thanks

@Nicolas-Yazzoom
Copy link
Author

Nicolas-Yazzoom commented Feb 24, 2022

Hello again. I tried you example. Adding the prototype after the running the install works and makes the prototype functions available inside my toast component under this.$toasts.ctx as expected. This works fine for simple prototype functions (for example, I have one for capitalizing strings which behaves as expected) but for some reason not everything is present. $store and $i18n (required for making $t, $tc, etc work) appear to be missing and I can't seem to pinpoint why this could be happening so I'm not quite there yet. Any guesses?

I've also made this small mixin to make the prototype functions available in the same way as other places in the app. This makes it more seamless:

const toMap = [
  '$t',
  '$tc',
  '$te'
  // adjust to suit your needs
]

export default {
  computed: toMap.reduce((a, b) => {
    a[b] = function() {
      return this.$toasts.ctx[b]
    }
    return a
  }, {})
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants