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.
MIT License
1.03k stars 116 forks source link

http-vue-loader migration guide #43

Closed TheJaredWilcurt closed 2 years ago

TheJaredWilcurt commented 3 years ago

I just updated a repo from http-vue-loader to vue3-sfc-loader. Here are my notes which could be used as part of a migration guide.

Notes:

  1. Convert from Vue 2 to Vue 3:
    • Change const app = new Vue({ el: '#app' });
    • To const app = Vue.createApp({}); app.mount('#app');
  2. Convert components from module.exports = {}; to export default {};
  3. Convert data: {} to data: function () { return {}; }
    • Otherwise you get Uncaught TypeError: dataFn.call is not a function error

I created this function which meant I didn't need to change the components section at all, keeping it much cleaner:

function httpVueLoader (componentPath) {
  const sfcLoaderOptions = {
    moduleCache: {
      vue: Vue
    },
    getFile: async function (url) {
      const response = await fetch(url);
      if (!response.ok) {
        throw Object.assign(new Error(response.statusText + ' ' + url), { response });
      }
      return await response.text();
    },
    addStyle: function (textContent) {
      const style = Object.assign(document.createElement('style'), { textContent });
      const reference = document.head.getElementsByTagName('style')[0] || null;
      document.head.insertBefore(style, reference);
    }
  };
  return Vue.defineAsyncComponent(function () {
    return window['vue3-sfc-loader'].loadModule(componentPath, sfcLoaderOptions);
  });
}

so my components still look like this, and it works:

  components: {
    'github-corner': httpVueLoader('/_components/github-corner.vue'),
    'site-logo': httpVueLoader('/_components/site-logo.vue'),
    'news-alerts': httpVueLoader('/_components/news-alerts.vue'),
    'base-card': httpVueLoader('/_components/base-card.vue'),
    'unreviewed-card': httpVueLoader('/_components/unreviewed-card.vue')
  },
FranckFreiburger commented 3 years ago

Thanks for your suggestion !

Just beware that sfcLoaderOptions (or at least moduleCache) must be shared between all loadModule() calls (see https://github.com/FranckFreiburger/vue3-sfc-loader/issues/16#issuecomment-770179744).

SMen1 commented 3 years ago

For someone just coming from http-vue-loader where the example in your docs is incredibly straightforward:

The docs example using vue2 with vue3-sfc-loader does not in any way relate!

I think a simple migration guide, firstly to using vue2 is a very good suggestion.

If I am not mistaken though, this enhancement is to move to using vue3, as it uses Vue.defineAsyncComponent ...

I think one of the tremendous benefits of your vue-loader, is for new users to start using components directly in the browser.

Is understanding vue3 a pre-requisite to using vue3-sfc-loader with vue2?!

I am actually hoping to use vue3-sfc-loader firstly with vue2 as a stepping stone to learning vue3, so a straightforward migration example for moving from http-vue-loader to vue3-sfc-loader would be greatly appreciated. Possibly using a vue2 version of TheJaredWilcurt suggestion (assuming I have not miss-understood that vue2 won't work with Vue.defineAsyncComponent).

Going to go back to http-vue-loader for now.

FranckFreiburger commented 2 years ago

work in progress : https://github.com/FranckFreiburger/vue3-sfc-loader/blob/main/docs/migrationGuide.md

SMen1 commented 2 years ago

Spot on.