vue-toastr icon indicating copy to clipboard operation
vue-toastr copied to clipboard

Can't use with Vue 3 in browser

Open nikriaz opened this issue 1 year ago • 1 comments

Your nice toasts were used for a while in my simple Vue 2 app. Now I upgraded to Vue 3, also upgraded plugin to 3,0.5 but can't figure out how to adjust to continue to use in browser, without bundlers.

I add script like this:

    <script src="~/lib/vue-toastr/dist/vue-toastr.umd.js"></script>

and my Vue app looks like this:

import { createApp } from '../lib/vue/vue.esm-browser.min.js';
const app = createApp({
... 
    mounted() {
        this.$toastr.defaultClassNames = ["animated", "fadeInDown"];
    },
...
});
//app.use(VueToastr);
app.mount('#app');

I'm getting the following errors:

plugin-vue:export-helper:7 Uncaught TypeError: Cannot read properties of undefined (reading 'defineComponent')
    at plugin-vue:export-helper:7:10
    at vue-toastr.umd.js:1:382
    at vue-toastr.umd.js:1:408
   TypeError: Cannot set properties of undefined (setting 'defaultClassNames')
    at app.js

if uncomment app.use(VueToastr); then additionally: [Vue warn]: A plugin must either be a function or an object with an "install" function.

I tried many different things but no luck. Can you help?

nikriaz avatar Aug 15 '23 06:08 nikriaz

Okay, it seems like problem is solved.

The problem is that umd version of your plugin requires Vue globally available so I changed the way how I load Vue to global:

<script src="~/lib/vue/vue.global.js"></script> //in html
 const { createApp } = Vue; //in main.js

Second, install function in your umd plugin version is nested under VueToastr so working syntax is: app.use(VueToastr.VueToastr) I think it is a bug/typo.

Third, after this started to work, it's turned out that this.$toastr.defaultClassNames = ["animated", "fadeInDown"]; doesn't work anymore because defaultClassNames are read-only for some reason. I think, this is bug too but thankfully, passing defaults through plugin options works.

app.use(VueToastr.VueToastr, {
    defaultClassNames: ["animated", "fadeInDown"]
});

I also discovered that using import in my main.js to load toastr is only possible with es version of the plugin. However, in this case plugin need to resolve Vue as 'vue' which is not possible without bundler or "import map" feature in browser to match 'vue' literal with actual path. Since "import map" seems not reliable or readily available for all users, it looks like the only available method to add plugin via

nikriaz avatar Aug 15 '23 19:08 nikriaz

I am going to close this issue. It looks like you have solved it on your end.

s4l1h avatar Mar 24 '24 00:03 s4l1h