使用 vue3-sfc-loader 加载远程Vue文件, 在运行时动态加载 .vue 文件。无需 Node.js 环境,无需 (webpack) 构建步骤

加载远程Vue文件

vue3-sfc-loader

vue3-sfc-loader ,它是Vue3/Vue2 单文件组件加载器。

在运行时从 html/js 动态加载 .vue 文件。无需 Node.js 环境,无需 (webpack) 构建步骤。

主要特征

  • 支持 Vue 3 和 Vue 2(参见dist/)
  • 仅需要 Vue 仅运行时构建
  • 提供esmumd捆绑包(示例)
  • 嵌入式ES6模块支持(含import()
  • TypeScript 支持、JSX 支持
  • 自定义 CSS、HTML 和脚本语言支持,请参阅pug和stylus示例
  • SFC 自定义块支持
  • 通过日志回调正确报告模板、样式或脚本错误
  • 专注于组件编译。网络、样式注入和缓存由您决定(参见下面的示例)
  • 轻松构建您自己的版本并自定义您需要支持的浏览器

编写Node接口

编写Node接口提供服务,用于返回vue文件

项目初始化和安装

mkdir nodeServe
cd nodeServe
npm iniy -y
npm install express cors

项目完整结构

nodeServer
├── index.js
├── loaderVue2.vue
├── loaderVue3.vue
├── package-lock.json
└── package.json

添加 index.js

// express 基于Node.js平台,快速、开放、极简的 Web 开发框架 https://www.expressjs.com.cn/
const express = require("express")
const app = express()
const cors = require("cors")
const fs = require('fs');

// 配置cors中间件,允许跨域
app.use(cors())

app.get("/getVue2Str", (req, res) => {
    // 服务端读取文件,并变成字符串。传递给前端
    const data = fs.readFileSync('./loaderVue2.vue', 'utf8');

    res.send({
        code:200,
        fileStr:data,
        fileName:"loaderVue2.vue"
    });
})

app.get("/getVue3Str", (req, res) => {
    // 服务端读取文件,并变成字符串。传递给前端
    const data = fs.readFileSync('./loaderVue3.vue', 'utf8');

    res.send({
        code:200,
        fileStr:data,
        fileName:"loaderVue2.vue"
    });
})

app.listen(3000, () => {
    console.log("服务启动成功:http://localhost:3000")
})

这里用到的两个vue文件代码如下

loaderVue2.vue

<template>
  <div>
    <h1>我是远程加载的组件</h1>
    <input :value="value" @input="changeName" />
    <button @click="patchParentEvent">触发父组件方法</button>
  </div>
</template>
<script>
export default {
  props: ["value"],
  methods: {
    changeName(e) {
      this.$emit("input", e.target.value);
    },
    patchParentEvent() {
      this.$emit("parentEvent");
    },
  },
};
</script>

<style scoped>
h1 {
  color: red;
}
</style>

loaderVue3.vue

<template>
  <div>
    <h1 class="text-red">我是远程加载的页面</h1>
    <input v-model="input" placeholder="placeholder" @input="changeValue"/>
    <button @click="emitParentFun">调用父组件的方法</button>
  </div>
</template>

<script setup>
import {defineProps,defineEmits,ref,onMounted} from "vue"

const props = defineProps(['modelValue'])
// 更新model绑定的值固定写法: update:modelValue
const emit = defineEmits(['update:modelValue',"childClick"])

let input = ref("")

onMounted(()=>{
  input.value = props.modelValue
  // window环境指向的是接收方的window环境
  console.log(window.testName);
})

const changeValue = (e) => {
  // 修改父组件的值
  emit('update:modelValue',e.target.value)
}

const emitParentFun = ()=>{
  emit('childClick',input.value)
}
</script>


<style scope>
.text-red{
  color: red;
}
</style>

运行

node index.js

image-20240411094407264

接口返回的格式如下

http://localhost:3000/getVue2Str

{
    "code": 200,
    "fileStr": "<template>\r\n  <div>\r\n    <h1>我是远程加载的组件</h1>\r\n    <input :value=\"value\" @input=\"changeName\" />\r\n    <button @click=\"patchParentEvent\">触发父组件方法</button>\r\n  </div>\r\n</template>\r\n<script>\r\nexport default {\r\n  props: [\"value\"],\r\n  methods: {\r\n    changeName(e) {\r\n      this.$emit(\"input\", e.target.value);\r\n    },\r\n    patchParentEvent() {\r\n      this.$emit(\"parentEvent\");\r\n    },\r\n  },\r\n};\r\n</script>\r\n\r\n<style scoped>\r\nh1 {\r\n  color: red;\r\n}\r\n</style>\r\n",
    "fileName": "loaderVue2.vue"
}

Vue2项目使用

安装 vue3-sfc-loader

npm install vue3-sfc-loader

使用

注意:

vue2要从dist/vue2-sfc-loader这个目录下引入loadModule使用

vue2要从dist/vue3-sfc-loader这个目录下引入loadModule使用

<template>
  <div>
    <component :is="remote" v-bind="$attrs" v-if="remote" v-model="name" @parentEvent="parentEvent"></component>
  </div>
</template>

<script>
import * as Vue from "vue"
import {loadModule} from "vue3-sfc-loader/dist/vue2-sfc-loader"

export default {
  name: 'App',
  data() {
    return {
      name: "李四",
      remote: null,
      url: "http://localhost:3000/getVue2Str",
    }
  },
  mounted() {
    this.load(this.url)
  },
  watch: {
    name(newName) {
      console.log(newName, "监听到变化")
    }
  },
  methods: {
    // 加载
    async load(url) {
      let res = await fetch(url).then(res => res.json());

      const options = {
        moduleCache: {
          vue: Vue
        },
        async getFile() {
          return res.fileStr
        },
        addStyle(textContent) {
          const style = Object.assign(document.createElement('style'), {textContent})
          const ref = document.head.getElementsByTagName('style')[0] || null
          document.head.insertBefore(style, ref)
        },
      };

      // 加载远程组件
      this.remote = await loadModule(res.fileName || "loader.vue", options)
    },
    // 子组件调用
    parentEvent() {
      console.log("父组件事件触发")
    }
  }
}
</script>

效果显示

image-20240411094551171

Vue3项目使用

安装

npm install vue3-sfc-loader

使用

注意:

vue2要从dist/vue2-sfc-loader这个目录下引入loadModule使用

vue2要从dist/vue3-sfc-loader这个目录下引入loadModule使用

<template>
  <div>
    <component :is="remote" v-if="remote" v-model="name" @childClick="childClick"/>
  </div>
</template>

<script setup>
import {loadModule} from "vue3-sfc-loader/dist/vue3-sfc-loader"
import * as Vue from 'vue'
import {onMounted, defineAsyncComponent, ref, watchEffect} from "vue"


let remote = ref()
let name = ref("李四")
let url = "http://localhost:3000/getVue3Str"


onMounted(() => {
  load(url)
})

watchEffect(() => {
  console.log(name.value)
})

const childClick = (newVal) => {
  console.log("子组件点击事件", newVal)
}

// 加载远程文件
const load = async (url) => {
  let res = await fetch(url).then(res => res.json());

  const options = {
    moduleCache: {
      vue: Vue
    },
    async getFile() {
      return res.fileStr
    },
    addStyle(textContent) {
      const style = Object.assign(document.createElement('style'), {textContent})
      const ref = document.head.getElementsByTagName('style')[0] || null
      document.head.insertBefore(style, ref)
    },
  };

  // 加载远程组件
  remote.value = defineAsyncComponent(() => loadModule(res.fileName || "loader.vue", options))
}
</script>

image-20240411094814070

完整源码

https://gitee.com/szxio/load-remote-vue-components

😆 求Start

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/536437.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue数据检测原理

前言 Vue中的数据监听离不开Object.defineProperty()方法的使用&#xff0c;在了解数据监测原理之前&#xff0c;建议先掌握defineProperty的用法。 目标 1 数据监测问题 2 数据监测原理 3 如何实现数组更新 1 遇到的问题 数组更新问题 <button click"updatePeople&q…

Java使用OpenOffice将office文件转换为PDF

Java使用OpenOffice将office文件转换为PDF 1. 先行工作1.1 OpenOffice官网下载1.2 JODConverter官网下载1.3 下载内容 2.介绍3. 安装OpenOffice服务3.1.Windows环境3.2 Linux环境 4. maven依赖5. 转换代码 1. 先行工作 请注意&#xff0c;无论是windows还是liunx环境都需要安装…

第6章 6.3 正则表达式(MATLAB入门课程)

讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 在上一章中&#xff0c;我们学了许多文本处理的函数&#xff0c…

DS18B20与单片机的通信、DS18B20采集温度、MODBUS协议、练习框架

我要成为嵌入式高手之4月9日51单片机第四天&#xff01;&#xff01; ———————————————————————————— DS18B20温度传感器 单总线数字温度计 异步的半双工的串行通信 测量范围从-55℃ ~ 125℃&#xff0c;增量值为0.5℃ 要用DS18B20采集温度&am…

STM32之FreeRTOS移植

1.FreeRTOS的移植过程是将系统需要的文件和代码进行移植和裁剪&#xff0c;其移植的主要过程为&#xff1a; &#xff08;1&#xff09;官网上下载FreeRTOS源码&#xff1a;https://www.freertos.org/ &#xff08;2&#xff09;移植文件夹&#xff0c;在portable文件夹中只需…

【数字化转型】上市公司智能制造词频统计数据(1991-2022年)

数据来源&#xff1a;上市公司年报 时间跨度&#xff1a;1991-2022年 数据范围&#xff1a;上市公司 数据指标&#xff1a; 版本一 智能制造 智能机器 智能生产 机器人 全自动 全机器 版本二 宏观政策 中国制造2025 工业4.0 互联网 范式特征 自动化 信息化 信息…

多态【C/C++复习版】

目录 一、多态是什么&#xff1f;如何实现&#xff1f; 二、 什么是重写&#xff1f;有什么特点&#xff1f; 三、什么是协变&#xff1f; 四、析构函数能实现多态吗&#xff1f;为什么要实现&#xff1f; 五、override和final的作用是什么&#xff1f; 六、 多态的原理是…

【vscode】在本地加载远端环境并开发

【vscode】在本地利用远程服务器显卡跑代码 写在最前面vscode&#xff1a;远程到本地1、安装ssh插件2、添加服务器连接配置3、连接服务器4. SSH配置5. 在ssh中安装python解释器 vscode基本操作 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光…

得物 Zookeeper SLA 也可以 99.99% | 得物技术

一、背景 ZooKeeper&#xff08;ZK&#xff09;是一个诞生于2007年的分布式应用程序协调服务。尽管出于一些特殊的历史原因&#xff0c;许多业务场景仍然不得不依赖它。比如&#xff0c;Kafka、任务调度等。特别是在 Flink 混合部署 ETCD 解耦 时&#xff0c;业务方曾要求绝对…

双数据库的安装

双MySQL的安装 【0】前言 ​ 本地已经安装过mysql5.1版本&#xff0c;应项目需求需要安装mysql5.7版本&#xff1b; ​ 官方网站下载对应版本&#xff1a;https://downloads.mysql.com/archives/community/ 【1】压缩包下载完成后解压至本地磁盘 【2】进入根目录下bin文件夹…

Element-UI 自定义-下拉框选择年份

1.实现效果 场景表达&#xff1a; 默认展示当年的年份&#xff0c;默认展示前7年的年份 2.实现思路 创建一个新的Vue组件。 使用<select>元素和v-for指令来渲染年份下拉列表。 使用v-model来绑定选中的年份值。 3.实现代码展示 <template><div><el-…

数据结构复习指导之线性表(线性表的顺序表示)

文章目录 线性表的顺序表示 1.顺序表的定义 1.1知识总览 1.2顺序表 1.3静态分配 1.4动态分配 1.5顺序表的特点 1.6知识回顾与重要考点 线性表的顺序表示 1.顺序表的定义 1.1知识总览 1.2顺序表 线性表的顺序存储又称顺序表。它是用一组地址连续的存储单元依次存储线性…

spring04:注解使用

spring04&#xff1a;注解使用 文章目录 spring04&#xff1a;注解使用前言&#xff1a;一、 Autowired Qualifier和 Resource 和 nullable1. Autowired 2. Resource &#xff1a;使用在类的属性上面&#xff08;和Autowired类似&#xff09;3. nullable 二、 Component 和 Re…

JetBrains RubyMine 2024.1 发布 - 最智能的 Ruby 与 Rails IDE

JetBrains RubyMine 2024.1 发布 - 最智能的 Ruby 与 Rails IDE 请访问原文链接&#xff1a;JetBrains RubyMine 2024.1 (macOS, Linux, Windows) - 最智能的 Ruby 与 Rails IDE&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org…

ELK日志

​​​​​​​

JavaGUI编程

目录 GUI概念 Swing概念 组件 容器组件 窗口&#xff08;JFrame&#xff09; 代码 运行 面板&#xff08;JPanel&#xff09; 代码 运行 布局管理器 FlowLayout 代码 运行 BorderLayout 代码 运行 GridLayout 代码 运行 常用组件 标签(JLabel) 代码 运…

Vue列表渲染

一、Vue列表渲染 1.用 v-for 把一个数组对应为一组元素 我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法&#xff0c;其中 items 是源数据数组&#xff0c;而 item 则是被迭代的数组元素的别名。 <ul id"exampl…

Agent调研--19类Agent框架对比

代理&#xff08;Agent&#xff09;指能自主感知环境并采取行动实现目标的智能体&#xff0c;即AI作为一个人或一个组织的代表&#xff0c;进行某种特定行为和交易&#xff0c;降低一个人或组织的工作复杂程度&#xff0c;减少工作量和沟通成本。 背景 目前&#xff0c;我们在探…

Qt 4.8中的ftp 功能在Qt 5.9.4 之前版本中的应用

很久以前也就是在Qt 4.8版本后&#xff0c; 如果想要用Qt ftp功能&#xff0c;是把Qt 4.8中的QFtp源码拉出来&#xff0c;编译、修改然后就能在Qt 其他版本使用。 但每一次升级Qt 版本&#xff0c;就要把Qt ftp 源码在相应的Qt 版本编译&#xff0c;修改。太麻烦了&#xff0c;…

C#下Httpclient post请求获取令牌

1.postman测试ok 2.C#代码 public static async Task<string> testGetToken(string URL, string param){string responseBody "eee";//using (var clientHandler new HttpClientHandler()){ var handler new HttpClientHandler();handler.ServerCertificat…
最新文章