/vue-import

Vue SFC loader of es module in browser.

Primary LanguageJavaScriptMIT LicenseMIT

vue-import

NPM Version Licence Minified Size Build and Publish

English | 简体中文

Import Vue components in a browser environment, i.e. SFC (*.vue) file. If you don't want to maintain package.json and apply packaging tools such as webpack, then vue-import will help you.

ESM import:

import vueImport from 'https://cdn.jsdelivr.net/npm/vue-import/dist/vue-import.esm-browser.js';

Minified:

import vueImport from 'https://cdn.jsdelivr.net/npm/vue-import/dist/vue-import.esm-browser.prod.js';

Instructions

Basic Usage

import { createApp } from 'https://cdn.jsdelivr.net/npm/vue@3/dist/vue.esm-browser.prod.js';
import vueImport from 'https://cdn.jsdelivr.net/npm/vue-import/dist/vue-import.esm-browser.prod.js';

const app = createApp();
app.component('my-component', await vueImport('./some/component.vue'));

app.mount('#app');

Override Component Props

The Promise method is used, and you can also use the async/await method.

import { createApp } from 'https://cdn.jsdelivr.net/npm/vue@3/dist/vue.esm-browser.prod.js';
import vueImport from 'https://cdn.jsdelivr.net/npm/vue-import/dist/vue-import.esm-browser.js';

const app = createApp();

vueImport('./some/component.vue', {
  function beforeMount() {
    console.log('beforeMount');
  },
  function mounted() {
    console.log('mounted');
  },
}).then((component) => {
  app.component('my-component', component);

  app.mount('#app');
});
  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>vue-import</title>
  <script type="importmap">
    {
      "imports": {
        "vue": "https://cdn.jsdelivr.net/npm/vue@3/dist/vue.esm-browser.prod.js",
        "vue-import": "https://cdn.jsdelivr.net/npm/vue-import/dist/vue-import.esm-browser.js",
        "vue-router": "https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.esm-browser.js",
        "@vue/devtools-api": "https://cdn.jsdelivr.net/npm/@vue/devtools-api/lib/esm/index.js"
      }
    }
  </script>
</head>

<body>
  <div id="app" v-cloak>
    <my-component></my-component>
    <router-view></router-view>
  </div>
  <script type="module">
    import { createApp, defineAsyncComponent } from 'vue';
    import { createRouter, createWebHashHistory } from 'vue-router';
    import vueImport from 'vue-import';

    const routes = [
      { path: '/', redirect: '/welcome' },
      // route component import
      { 
        path: '/welcome',
        component: await vueImport('./component/welcome.vue'),
      },
      { 
        path: '/home',
        component: defineAsyncComponent(() => vueImport('./component/home.vue')),
      },
    ];

    const router = createRouter({
      history: createWebHashHistory(),
      routes,
    });

    const app = createApp();
    // custom component import
    app.component('my-component', await vueImport('./component/common.vue'))

    app.use(router);
    app.mount('#app');
  </script>
</body>
</html>
  • component/common.vue
    Support loading of <script></script> default export module
<template>
  <div class="common">
    Common component ({{ date }})
    <nav>
      <router-link to="/home">Home</router-link>
      <router-link to="/welcome">Welcome</router-link>
      <a href="https://github.com/kianfang/vue-import#readme">About</a>
    </nav>
  </div>
</template>

<script>
export default {
  data() {
    return {
      date: new Date().toLocaleString(),
    }
  },
}
</script>

<style>
.common {
  color: blue;
}
</style>
<style>
nav {
  display: flex;
  gap: 0 10px;
}
</style>
  • component/home.vue
    Load the Home component asynchronously
<template>
  <h1 class="title">{{ title }}</h1>
  <p>
    Home async component with router
  </p>
</template>

<script>
export default {
  data() {
    return {
      title: 'Home',
    }
  },
}
</script>

<style>
.title {
  color: blue;
}
</style>
  • component/welcome.vue
    Support multiple groups of <style></style> embedding methods,when the component is uninstalled, the embedded styles will also be uninstalled.
<template>
  <h1 class="title">Welcome</h1>
  <p>
    Welcome component with router
  </p>
</template>

<script>
export default {}
</script>

<style>
.title {
  color: green;
}
</style>
<style>
  p {
    color: gray;
  }
</style>
  • component/import.vue Support relative path to import module in script snippet, this is mainly achieved through regular replacement and polyfill.
<template>
  <div class="import">
    <h1 class="title">Import</h1>
    <p>
      <code>import.meta.url</code>: <b>{{ url }}</b>
    </p>
    <p>
      <code>import.meta.resolve('./file')</code>: <b>{{ resolveFile }}</b>
    </p>
    <p>
      <code>import.meta.resolve('vue-import')</code>: <b>{{ module }}</b>
    </p>
    <p>
      <code>await import('../util').getYear()</code>: <b>{{ importYear }}</b>
    </p>
  </div>
</template>

<script>
const util = await import('../util');

export default {
  data() {
    return {
      url: import.meta.url,
      resolveFile: import.meta.resolve('./file'),
      module: import.meta.resolve('vue-import'),
      importYear: util.getYear(),
    }
  },
}
</script>

<style>
.title {
  color: orange;
}

.import code {
  color: gray;
}

</style>