// import Vue from "vue"; // vue2
import { createApp } from 'vue' // vue3
import fabComponent from "./components/Fab.vue";
import SvgIcon from "./components/SvgIcon.vue";
// The body of class
window.fab = {
mount(options) {
var html = '<div data-vue-component="FabComponent"></div>';
document.body.insertAdjacentHTML('beforeend', html);
document
.querySelectorAll("[data-vue-component=FabComponent]")
.forEach((element) => {
// works in vue2
// const floatingButton = new Vue(fabComponent)
// floatingButton.options(options);
// floatingButton.$mount(element);
// what is the equivalent in vue3?
const app = createApp({});
app.component('fb',fabComponent);
const floatingButton = app.use(fabComponent);
floatingButton.options(options);
floatingButton.$mount(element);
});
}
}
<script>
// Fab.vue
export default {
name: 'app',
methods: {
options(options) {
// this was called in vue2
Object.keys(options).forEach(key => {
this[key] = options[key];
});
},
alert() {
alert('You have clicked me :)');
}
}
}
</script>
I'm not that proficient in vue but need to upgrade my vue2 widget (i.e. it can be loaded in any HTML by just including the bundled javascript) to a vue3 one.
I have spent 2 long days on this and tried about almost everything I can think of to translate this new Vue(fabComponent)
.
Webpack builds/transpiles without errors, but the issue surfaces when I try to load it in my browser. In vue2, floatingButton
was assigned as a Proxy(Object)
, but I just can't seem to replicate that in vue3, floatingButton
is an Object
. As a result, floatingButton.options(options);
throws an uncaught error.
I can use new Vue(fabComponent)
as-is in vue3, but how would I get my app
then? Because Fab.vue
relies on another SvgIcon.vue
component.
Any ideas? Thank you.
I added the <script>
of Fab.vue
where in vue2, the options
method was called. In the vue3 example, I only saw defineProps(...)
in <script setup>
, also need help with that. Thank you.
Upgrading to Vue3, it is possible to create multiple Vue-app instances. On the contrary, in Vue2, it is limited to one single global instance.
Another breaking change is how the app instance would bind to an element (there is a mount
function instead of $mount
).
To address your issue, you can create an app instance with FabComponent
for each element the query returned.
import { createApp } from 'vue';
import FabComponent from './FabComponent.vue';
import SvgIcon from './SvgIcon.vue';
window.fab = {
mount(options) {
var html = '<div data-vue-component="FabComponent">';
document.body.insertAdjacentHTML('beforeend', html);
document
.querySelectorAll('[data-vue-component=FabComponent]')
.forEach(element => {
createApp(FabComponent, options)
.mount(element);
});
},
};
window.fab.mount({
modelValue:'A GLOBAL PROP'
});