Vue 3 and Quasar 2 Upgrade

I’m putting forth an effort to migrate from vue 2 to 3 and quasar 1 to 2. Because vue2 has reached end of life https://v2.vuejs.org/eol/, and I think it’ll be interesting to upgrade to the newest version.

I figured we can start a discussion on it here.

I couldn’t find any existing progress on it.
Please let me know if there has already been progress on it.

1 Like

Hi Michael, sounds great! are you going to create a separate branch, develop in one-shot, or develop incrementally? If help is needed here I can pitch in as this solves many issues including performance, security and some features I’m really wanting in newer Vue and Quasar

I created a branch here: GitHub - moqui/moqui-runtime at vue3quasar2. I’m planning on developing incrementally while keeping most things working as I move along.

I’ve already got vapps mostly working with a compatibility library layer that supports vue 2 and vue 3. The compatibility layer doesn’t work with quasar so I’m going to start with vapps and by the time I finish that I should be able to get quasar working.

Thanks! Help would be great! I expect that there will be 3 phases. Learn about the breaking changes from vue 2 to vue 3, make necessary changes to the default macro components, and fix any bugs as needed. I expect that help will be needed most implementing macros and fixing bugs, but any help would be great.

Let me know what you think @taher

1 Like

Hello Michael,

I started by looking at your branch, two commits so far, what I detected mainly is just version upgrades while the rest seems to be refactoring I think? Anyway I’m unable to run anything on vapps and qapps, I’m getting an error WebrootVue.js?v=18d1b13:55 Uncaught TypeError: Vue.filter is not a function at WebrootVue.js?v=18d1b13:55:5

So not to step on your toes, and not to duplicate efforts, I’m checking if I need to work on this or if you’re already done or working locally on your computer or something? I’m assuming you’re working on the freemarker macros to resolve the issues maybe? Let me know if I can help.

I didn’t push a commit. My bad. It should be better now

This is basically what it looks like at the moment. I don’t have a ton of time to work on this, and it probably will take a bit of time as I work for free.

I’m currently working on getting the router and vue compilation working. I haven’t started on the freemarker macros yet. Thanks for reaching out! Let me know what you are interested in doing

We currently have a dependency on Comparing FranckFreiburger:master...jonesde:master · FranckFreiburger/http-vue-loader · GitHub.

http-vue-loader is currently depricated in favor of GitHub - FranckFreiburger/vue3-sfc-loader: Single File Component loader for Vue2 and Vue3. Load .vue files directly from your HTML. No node.js environment, no build step..

However, it adds 540kb of bloat see: https://github.com/FranckFreiburger/vue3-sfc-loader/blob/main/docs/migrationGuide.md

I’m at an impasse of what to do. The new package looks like it may not even be worth using. Any ideas @jonesde @taher?

Hi @michael

I believe this is because of the additional complexity and features of vue3. I think we only have two options that aren’t very pretty. Either use vue3-sfc-loader and live with the bloat, or simply roll out our own component loader probably using the code relevant from vue3-sfc-loader.

1 Like

I looked at this a bit and noticed that it does a Babel transpilation, and I wonder if that is where the bloat is from. Another possibility is the JSX support, which is not really needed with Vue like it is with React, and even if it is popular (I don’t know) we haven’t been using it with Moqui since the native Vue templates are so good. The source files are not so large on their own, so it might not be too difficult to do a build of it without the feature(s) that result in a very large built file.

Another option might be to update the old library to support Vue3, but I don’t know enough about the differences to know how much effort that might be. The changes I did to it were to support building a Vue component from a string field in memory so that the existing WebrootVue stuff that downloads pages could be used instead of the http loader that was built into the library. Overall it isn’t that big or complex and might not be all that difficult to modify for the Vue3 component API changes.

2 Likes

These are both good thoughts. As I continue I’ll see if any changes are really needed. It is a fairly simple library, and we are only using a couple methods from it. I think that going with the vue3-sfc-loader would just introduce too much bloat if a slightly modified http-vue-loader will work. I’ll keep you updated

1 Like

Anyone can help to review Use h() function to replace createEl() by hellozhangwei · Pull Request #230 · moqui/moqui-runtime · GitHub. vue3 and quasar2 are basically work. The only problem what I see is <q-btn to=“”/> still dose not work.

1 Like

Thanks for AI <q-btn to=“”/> can work now.

1 Like

Hi @michael, may I know if you are still working on this? Is there anything I can help? I think it’s crucial that we keep the sourcecode updated to have the community engaged and motivated.

1 Like

I am trying to rewrite all components using Vue 3 syntax. Can you please help me check if the following example is correct?

vue 2 code

moqui.webrootVue.component('m-container-box', {
    name: "mContainerBox",
    props: { type:{type:String,'default':'default'}, title:String, initialOpen:{type:Boolean,'default':true} },
    data: function() { return { isBodyOpen:this.initialOpen }},
    // TODO: handle type better, have text color (use text- additional styles instead of Bootstrap to Quasar mapping), can collor the border too?
    template:
    '<q-card flat bordered class="q-ma-sm m-container-box">' +
        '<q-card-actions @click.self="toggleBody">' +
            '<h5 v-if="title && title.length" @click="toggleBody" :class="\'text-\' + type">{{title}}</h5>' +
            '<slot name="header"></slot>' +
            '<q-space></q-space>' +
            '<slot name="toolbar"></slot>' +
            '  <q-btn color="grey"  round flat dense :icon="isBodyOpen ? \'keyboard_arrow_up\' : \'keyboard_arrow_down\'" @click="toggleBody" ></q-btn>' +
        '</q-card-actions>' +
        '  <div v-show="isBodyOpen">' +
        '<q-card-section :class="{in:isBodyOpen}"><slot></slot></q-card-section>' +
                        '  </div>' +
    '</q-card>',
    methods: { toggleBody: function() { this.isBodyOpen = !this.isBodyOpen; } }
});

vue 3 code

moqui.webrootVue.component('m-container-box', {
    name: "mContainerBox",
    props: { type:{type:String,'default':'default'}, title:String, initialOpen:{type:Boolean,'default':true} },

    setup(props, { slots }) {

        const isBodyOpen = ref(props.initialOpen);

        const toggleBody = () => {
            isBodyOpen.value = !isBodyOpen.value;
        };

        return {
            isBodyOpen,
            toggleBody
        }
    },
    template:
        `<q-card flat bordered class="q-ma-sm m-container-box">
          <q-card-actions @click.self="toggleBody">
            <h5 v-if="title && title.length" @click="toggleBody" :class="'text-' + type">{{title}}</h5>
            <slot name="header"></slot>
            <q-space></q-space>
            <slot name="toolbar"></slot>
            <q-btn color="grey" round flat dense :icon="isBodyOpen ? 'keyboard_arrow_up' : 'keyboard_arrow_down'" @click="toggleBody" />
          </q-card-actions>
          <div v-show="isBodyOpen">
            <q-card-section :class="{in:isBodyOpen}">
              <slot></slot>
            </q-card-section>
          </div>
        </q-card>`,
});
1 Like

It looks fine, as long as it works with Vue 3 and Quasar 2 initially. We can get a more solid way to program as we get more into the translation between versions

How can I help you out with the Vue 3 migration?

The problem I got is the menu tree in the q-drawer dose not work. Because the this.$root.navMenuList in m-menu-nav-item is not be populated before it is used. The mounted function in root app moqui.webrootVue dose not run before m-menu-nav-item loaded in vue 3.