Vue.js 3 中,使用 vue3-sfc-loader 可以动态加载异步的 Vue 单文件组件(.vue 文件)。这个工具允许你在运行时根据需要加载和解析 .vue 文件,使得组件的加载变得更加灵活和动态。

下面是一个简单的示例,演示如何使用 vue3-sfc-loader 动态加载一个异步的 Vue 组件:

安装依赖: 首先,需要安装 vue3-sfc-loader@vue/compiler-sfc(Vue 3 的单文件组件编译器)。

import { loadModule } from "vue3-sfc-loader";

开始加载时需要知道的事

defineAsyncComponent 是 Vue 3 提供的用于定义异步组件的函数

<template>
  <div>
    <component :is="previewComp"></component>
  </div>
</template>
  • <component :is="previewComp"></component> 是动态组件,根据 previewComp 的值来决定显示哪个组件。

 

vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
import {
  ref,
  defineAsyncComponent,
  shallowRef,
  watch,
  onMounted,
  nextTick,
} from "vue";
import * as Vue from "vue";
import * as Cesium from "cesium";
import { loadModule } from "vue3-sfc-loader";
//映入你需要渲染的资源。包含js 在下面的代码中需要再次注册,

比如我们的vue下面仍然需要注册,第三方资源包也是如此

const init = (code: string) => {
  try {
    const options = {
      moduleCache: {
        vue: Vue,
        cesium: Cesium,
      },
      async getFile() {
        return code;
      },
      addStyle(textContent) {
        const style = Object.assign(document.createElement("style"), {
          textContent,
        });
        const ref = document.head.getElementsByTagName("style")[0] || null;
        document.head.insertBefore(style, ref);
      },
    };
    const comp = defineAsyncComponent(() =>
      loadModule("myComponent.vue", options)
    );
    previewComp.value = comp;
  } catch (err) {
    console.error(err);
  }
};
  • init 方法是初始化方法,根据传入的 code 加载模块并设置到 previewComp
  • moduleCache:这是一个对象,用来缓存模块。根据代码中的变量命名,它可能预先加载了一些模块,例如 VueFFCesiumCesiumturfCesiumNavigation。这些模块可以在加载 myComponent.vue 组件时使用。

  • etFile() 函数:这是一个异步函数,返回值是传入的 code 参数,即函数初始化时传入的字符串。

  • defineAsyncComponent() 是一个 Vue 3 提供的函数,用于定义异步组件。它接受一个函数作为参数,这个函数返回一个 Promise,用来加载和解析组件。
  • loadModule("myComponent.vue", options) 调用 loadModule 函数加载名为 myComponent.vue 的 Vue 组件,并传入之前定义的 options 对象作为配置。

 就是这样拉。

然而我的示例里面previewComp是外面编辑器传进来的。展示一下源码

<template>
  <div v-if="show" class="big">
    <component :is="previewComp"></component>
  </div>
</template>

<script setup lang="ts">
import {
  ref,
  defineAsyncComponent,
  shallowRef,
  watch,
  onMounted,
  nextTick,
} from "vue";
import * as Vue from "vue";
import * as Cesium from "cesium";
import { loadModule } from "vue3-sfc-loader";
import * as turf from "@turf/turf";
import * as CesiumNavigation from "cesium-navigation-es6"; //指南针插件
import FFCesium from "@/FFCesium/core/index.js";

let show = ref(false);
// import { particle } from "../cesium/resoure/index.ts";
const props = defineProps({
  code: {
    type: String,
    required: true,
  },
});
watch(
  () => props.code,
  (newValue, oldValue) => {
    // 这里可以执行其他操作
    console.log("监听");

    init(newValue);
  }
);

onMounted(() => {
  // 初始化
  show.value = true;
  // 初始化
  init(props.code);
});
const setCode = (code: string) => {
  show.value = false;
  // 重新渲染显示页,解决改错报错不再回归
  console.log("yunx,shuoax");
  nextTick(() => {
    show.value = true;
    // 在父组件里面再调用一次
    init(code);
  });
};

defineExpose({ setCode });

const previewComp = shallowRef();
const init = (code: string) => {
  // console.log("FFCesium12", FFCesium);
  try {
    const options = {
      moduleCache: {
        vue: Vue,
        FFCesium: FFCesium,
        cesium: Cesium,
        turf: turf,
        CesiumNavigation: CesiumNavigation,
      },
      async getFile() {
        return code;
      },
      addStyle(textContent) {
        const style = Object.assign(document.createElement("style"), {
          textContent,
        });
        const ref = document.head.getElementsByTagName("style")[0] || null;
        document.head.insertBefore(style, ref);
      },
    };
    const comp = defineAsyncComponent(() =>
      loadModule("myComponent.vue", options)
    );
    previewComp.value = comp;
  } catch (err) {
    console.error(err);
  }
};
// // 初始化
// init(props.code);
</script>
<style scoped>
.big {
  width: 100%;
  height: 100%;
}
</style>

GitHub 加速计划 / vu / vue
82
16
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:4 个月前 )
9e887079 [skip ci] 2 个月前
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 6 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐