0.2.2 • Published 2 years ago

vue-browser-sfc v0.2.2

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

浏览器中Vue 3 的单文件组件插件

npm

从技术上来讲,在浏览器支持了模块化和 importmap 并且 Edge 和 chrome 统一内核后,使用模块化的方式开发已经可以脱离 webpack 和 bebel 了,如果不是开发库而是开发应用,node.js 也可以不用了。

从 Vue 本身来讲,Vue 3 本身已经不支持 IE 了,因此编译打包来支持低版本已经是个伪命题了。可以扩展或修改 Vue 在找不组件时,动态去服务端加载单文件组件,解析后调用 Vue 本身支持运行时定义异步组件的功能来避免单文件组件的编译问题。

有些项目需要动态加载单文件组件的能力,比如物联网相关的项目,后端对接设备后,前端需要增加对应设备的视图,对于一个节点下的设备,又有对设备的排列和布局自定义的需求,通常要做到配置模板内容后,刷新即可浏览效果的程度,不可能每次都编译后部署。

实现原理

  1. 使用 Vue 的 defineAsyncComponent 方法动态创建组件。
  2. 使用 浏览器原生的 fetch 和 import 加载并导入远程组件。
  3. 拦截 Vue 的 resolveComponent 和 resolveDynamicComponent 两个方法,在找不到组件时动态加载。

功能

  1. 远程加载单文件组件,包括路由组件。
  2. 根据组件的加载和卸载对 css 进行控制,包括style和link两种方式。
  3. 可直接源码调试组件。

缺点

  1. 单文件组件内的语法只支持浏览器端原生支持的功能。
  2. 不支持 css scoped。

使用

默认 /components 目录为组件目录;默认 /views 目录为路由组件目录。

script 加载方式

不需要对 Vue 源码进行修改。

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>script mode</title>
</head>

<body>
    <div id="app">
        <router-view />
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@3.2.21/dist/vue.global.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue-router@4.0.12/dist/vue-router.global.min.js"></script>
    <script src="vue-browser-sfc.js"></script>

    <script>
        const app = Vue.createApp({
            data() {
                return {};
            }
        });

        const router = new VueRouter.createRouter({
            history: VueRouter.createWebHashHistory(
                document.querySelector("base")?.getAttribute("href")
            ),
            routes: [],
        });

        app.use(router);
        app.use(VueBrowserSfc);
        app.mount("#app");
    </script>
</body>

</html>

esm 方式

需要对 Vue 源码进行修改,因为无法修改 esm 方式导出的函数。

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>esm mode</title>
</head>

<body>
    <div id="app">
        <router-view />
    </div>
    <script src="vue-browser-sfc.js"></script>
    <script type="importmap">
        {
            "imports": {
                "vue": "./vue-esm-browser.min.js",
                "vue-router": "https://cdn.jsdelivr.net/npm/vue-router@4.0.6/dist/vue-router.esm-browser.js",
                "vue-browser-sfc":"./vue-browser-sfc.esm.js"
            }
        }
    </script>

    <script type="module">
        import { createApp, defineAsyncComponent } from "vue";
        import { createRouter, createWebHistory, createWebHashHistory } from "vue-router";
        import * as VueBrowserSfc from "vue-browser-sfc";

        const app = createApp({
            data() {
                return {};
            }
        });

        const router = new createRouter({
            history: createWebHashHistory(
                document.querySelector("base")?.getAttribute("href")
            ),
            routes: [],
        });

        app.use(router);
        app.use(VueBrowserSfc, defineAsyncComponent);
        app.mount("#app");
    </script>
</body>

</html>
0.2.2

2 years ago

0.2.1

2 years ago

0.2.0

2 years ago

0.1.9

2 years ago

0.1.8

2 years ago

0.1.7

2 years ago

0.1.6

3 years ago

0.1.5

3 years ago

0.1.4

3 years ago

0.1.3

3 years ago

0.1.2

3 years ago

0.1.1

3 years ago

0.1.0

3 years ago