当前位置: 首页 > article >正文

vue3-sfc-loader 加载远程.vue文件(sfc)案例

注意事项

  1. style标签如果增加了lang比如:lang=“scss”,需要提供scss-loader的处理器,这个暂时没研究,我的处理方式是将动态模版的css放在了全局
  2. 打包暂时还没有测试,后面测试了会同步更新

安装vue3-sfc-loader

npm install vue3-sfc-loader

后端vue模版 (sfc案例)

后端我用的是java加Velocity模版引擎(.vm模版)

vm模版引擎位置:
在这里插入图片描述

vm模版

<template>
  <view class="cus-tab theme theme-page">
    <uniForms ref="formRef" :modelValue="formData" validate-trigger="bind">
      <table class="tableCla">
        <colgroup>
          <col style="width: 20px;">
          <col style="width: 70px;">
          <col style="width: 130px;">
          <!-- <col style="width: 70px;"> -->
        </colgroup>
        <thead>
        <tr>
          <th class="slash-wrap" colspan="2">
            <div class="oline">
              <span class="span1">年级</span>
              <span class="span2">姓名</span>
            </div>
          </th>
          <th>高三二班</th>
          <th>异议数据</th>
        </tr>
        </thead>
        <tbody>
        <tr>
          <td colspan="2">身高</td>
          <td>身高</td>
          <td>
            <uniFormsItem name="sga">
              <view class="input-cla theme-flex">
                <uniEasyinput :clearable="false" v-model="formData.sga"
                               placeholder=""></uniEasyinput>
                <text>cm</text>
              </view>
            </uniFormsItem>
          </td>
        </tr>
        <tr>
          <td colspan="2">体重</td>
          <td>88888888</td>
          <td>
            <uniFormsItem name="tz">
              <view class="input-cla theme-flex">
                <uniEasyinput :clearable="false" v-model="formData.tz"
                               placeholder=""></uniEasyinput>
                <text>kg</text>
              </view>
            </uniFormsItem>
          </td>
        </tr>
        <tr>
          <td colspan="1" rowspan="3">眼科检查</td>
          <td>裸眼视力</td>
          <td>das</td>
          <td>
            <view class="theme-flex">
              <view class="input-cla theme-flex">
                <uniFormsItem name="lyz">
                  <view class="input-cla theme-flex">
                    <text>左</text>
                    <uniEasyinput :clearable="false" v-model="formData.lyz"
                                   placeholder=""></uniEasyinput>
                  </view>
                </uniFormsItem>
                <text>/</text>
                <uniFormsItem name="lyy">
                  <view class="input-cla theme-flex">
                    <text>右</text>
                    <uniEasyinput :clearable="false" v-model="formData.lyy"
                                   placeholder=""></uniEasyinput>
                  </view>
                </uniFormsItem>
              </view>
            </view>

          </td>
        </tr>
        <tr>
          <td>矫正视力</td>
          <td>John</td>
          <td>
            <view class="theme-flex">
              <view class="input-cla theme-flex">
                <uniFormsItem name="jzz">
                  <view class="input-cla theme-flex">
                    <text>左</text>
                    <uniEasyinput :clearable="false" v-model="formData.jzz"
                                   placeholder=""></uniEasyinput>
                  </view>
                </uniFormsItem>
                <text>/</text>
                <uniFormsItem name="jzy">
                  <view class="input-cla theme-flex">
                    <text>右</text>
                    <uniEasyinput :clearable="false" v-model="formData.jzy"
                                   placeholder=""></uniEasyinput>
                  </view>
                </uniFormsItem>
              </view>
            </view>
          </td>
        </tr>
        <tr>
          <td>角膜炎</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <wdCheckbox v-model="formData.jmy" shape="square">有异议</wdCheckbox>
            </view>
          </td>
        </tr>
        <tr>
          <td colspan="1" rowspan="4">内科检查</td>
          <td>心脏</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <wdCheckbox v-model="formData.xz" shape="square">有异议</wdCheckbox>
            </view>
          </td>
        </tr>
        <tr>
          <td>肺</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <wdCheckbox v-model="formData.fei" shape="square">有异议</wdCheckbox>
            </view>
          </td>
        </tr>
        <tr>
          <td>肝</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <wdCheckbox v-model="formData.gan" shape="square">有异议</wdCheckbox>
            </view>
          </td>
        </tr>
        <tr>
          <td>脾</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <wdCheckbox v-model="formData.pi" shape="square">有异议</wdCheckbox>
            </view>
          </td>
        </tr>
        <tr>
          <td colspan="1" rowspan="8">外科检查</td>
          <td>头部</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <wdCheckbox v-model="formData.tb" shape="square">有异议</wdCheckbox>
            </view>
          </td>
        </tr>
        <tr>
          <td>颈部</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <uniEasyinput :clearable="false" v-model="formData.sg" placeholder=""></uniEasyinput>
            </view>
          </td>
        </tr>
        <tr>
          <td>甲状腺</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <uniEasyinput :clearable="false" v-model="formData.sg" placeholder=""></uniEasyinput>
            </view>
          </td>
        </tr>
        <tr>
          <td>胸部</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <uniEasyinput :clearable="false" v-model="formData.sg" placeholder=""></uniEasyinput>
            </view>
          </td>
        </tr>
        <tr>
          <td>脊椎</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <uniEasyinput :clearable="false" v-model="formData.sg" placeholder=""></uniEasyinput>
            </view>
          </td>
        </tr>
        <tr>
          <td>四肢</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <uniEasyinput :clearable="false" v-model="formData.sg" placeholder=""></uniEasyinput>
            </view>
          </td>
        </tr>
        <tr>
          <td>皮肤</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <uniEasyinput :clearable="false" v-model="formData.sg" placeholder=""></uniEasyinput>
            </view>
          </td>
        </tr>
        <tr>
          <td>淋巴结</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <uniEasyinput :clearable="false" v-model="formData.sg" placeholder=""></uniEasyinput>
            </view>
          </td>
        </tr>
        <tr>
          <td colspan="1" rowspan="3">耳鼻喉科</td>
          <td>耳</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <uniEasyinput :clearable="false" v-model="formData.sg" placeholder=""></uniEasyinput>
            </view>
          </td>
        </tr>
        <tr>
          <td>鼻</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <uniEasyinput :clearable="false" v-model="formData.sg" placeholder=""></uniEasyinput>
            </view>
          </td>
        </tr>
        <tr>
          <td>扁桃体</td>
          <td>John</td>
          <td>
            <view class="input-cla theme-flex">
              <uniEasyinput :clearable="false" v-model="formData.sg" placeholder=""></uniEasyinput>
            </view>
          </td>
        </tr>
        <tr>
          <td colspan="4">
            <view class="input-text-cla">
              <uniFormsItem required name="fkyj" :rules="[{required: true,errorMessage: '请填写反馈意见',}]">
                <view class="theme-flex">
                  <uniEasyinput type="textarea" autoHeight :clearable="false" v-model="formData.fkyj"
                                 placeholder="请输入反馈意见"></uniEasyinput>
                </view>
              </uniFormsItem>
            </view>
          </td>
        </tr>
        </tbody>
      </table>
      <view>
        <view class="tips-clas theme-flex">
          <text>1. 请如实填写,填写完成后保存</text>
          <text>2. 异议数据需机构审核,请耐心等待</text>
        </view>
        <view class="bot-box">
          <wdButton @click="submit">提交审核</wdButton>
        </view>
      </view>
    </uniForms>
  </view>
</template>

<script setup name="Abnormal">
  import { ref, reactive } from 'vue'
  import uniForms from 'uniForms'
  import uniFormsItem from 'uniFormsItem'
  import uniEasyinput from 'uniEasyinput'
  import wdCheckbox from 'wdCheckbox'
  import wdButton from 'wdButton'
  const formRef = ref();
  const formData = reactive({
    sga: '',
    sg: '',
    tz: '',
    lyz: '',
    lyy: '',
    jzz: '',
    jzy: '',
    fkyj: '',
    jmy: false,
    xz: false,
    fei: false,
    gan: false,
    pi: false,
    tb: false,
  });
  const submit = () => {
    formRef.value.validate().then((res) => {
      console.log('表单数据信息:', res);
    }).catch((err) => {
      console.log('表单错误信息:', err);
    })
  };
</script>

<style lang="scss">
  .oline {
    border-top: 50px #c5c5c5 solid;
    width: 0px;
    height: 0px;
    border-left: 90px #ffffff solid;
    position: relative;

  }

  .oline::before {
    position: absolute;
    top: -40px;
    left: -80px;
    width: 80px;
    height: 40px;
    /* background: #fff url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiPjxsaW5lIHgxPSIwIiB5MT0iMCIgeDI9IjEwMCUiIHkyPSIxMDAlIiBzdHJva2U9ImJsYWNrIiBzdHJva2Utd2lkdGg9IjEiLz48L3N2Zz4=) no-repeat 100% center; */
    content: '';
  }

  .span1 {
    font-style: normal;
    display: block;
    position: absolute;
    top: -40px;
    left: -40px;
    width: 35px;
  }

  .span2 {
    font-style: normal;
    display: block;
    position: absolute;
    top: -25px;
    left: -70px;
    width: 55px;
  }

  .top {
    padding: 10px;
    border-bottom: 1px solid #e8e8e8;
  }

  .aColor>a {
    color: rgba(0, 0, 0, 0.65);
  }

  .tableCla {
    width: 100%;
    border: 1px solid #e8e8e8;
    border-collapse: collapse;
  }

  .theadCla>tr>th {
    padding: 10px;
    color: rgba(0, 0, 0, 0.85);
    border: 1px solid #e8e8e8;
    background: #fafafa;
    font-weight: normal;
  }

  tbody>tr>td,
  th {
    text-align: center;
    font-weight: normal;
    color: rgba(0, 0, 0, 0.65);
    /* padding: 15px 10px; */
    border: 1px solid #e8e8e8;
    font-size: 12px;
  }



  tr:nth-child(even) {
    /* background: #effefd; */
  }

  td {
    font-size: 15px;
  }

  .input-cla {
    width: 100%;
    // border: 1px solid #888888;
    height: 30px;
    padding: 10px;
    box-sizing: border-box;
    align-items: center;
    text-align: center;
    justify-content: center;

    :deep(.uni-easyinput__content-input) {
      height: 20px;
      font-size: 14px;
      width: 40px;
    }

    :deep(.uni-easyinput__content) {
      height: 20px;
      font-size: 14px;
      width: 100%;
    }

    :deep(.uni-easyinput) {
      height: 20px;
      font-size: 14px;
      flex: 0;
      width: 40px !important;
    }

    :deep(.uni-input-input) {
      font-size: 11px !important;
    }

    :deep(.uni-easyinput__content-input) {
      height: 20px !important;
    }


  }

  .cus-tab {
    :deep(.uni-forms-item) {
      margin-bottom: 0px !important;
    }
  }

  .input-text-cla {
    padding: 10px 5px;
    padding-bottom: 20px;
    box-sizing: border-box;
  }

  .tips-clas {
    flex-direction: column;
    color: red;
    align-items: flex-start;
    gap: 5px;
    font-size: 14px;
    padding: 10px;
    box-sizing: border-box;
  }

  .bot-box {
    width: 100%;
    padding: 10px;
    padding-top: 5px;
    box-sizing: border-box;
    :deep(.wd-button) {
      width: 90%;
      display: block;
      margin: 0 auto;
    }

  }
</style>

后端处理模版数据

之前写过类似的,就直接拿来用了,传送门

前端案例

前端使用的uniapp+vue3+ts+vite
moduleCache中需要存放你的vm模版中的组件及api差不类似运行时的东西,不然标签是不会被解析的,类似下面中的uni-ui的组件,如果不引入就不会被解析,注意:引入的模版key要与vm模板中的名称一致

<template>
	<!-- <div style=" margin: 0; padding: 0;overflow-y: scroll;"> -->
		<component :is="dynamicComponent" v-if="templateStr"></component>
		<wd-status-tip image="comment" tip="暂无报告数据~" v-else/>
		<Fab ref="fabRef" @selectAr="selectAr" />
	<!-- </div> -->
</template>
<script setup lang="ts" name="CalendarYear">
	import { onLoad } from '@dcloudio/uni-app'
	import uniForms from '@dcloudio/uni-ui/lib/uni-forms/uni-forms.vue'
	import uniFormsItem from '@dcloudio/uni-ui/lib/uni-forms-item/uni-forms-item.vue'
	import uniDataCheckbox from '@dcloudio/uni-ui/lib/uni-data-checkbox/uni-data-checkbox.vue'
	import uniEasyinput from '@dcloudio/uni-ui/lib/uni-easyinput/uni-easyinput.vue'
	import { abnormalReport } from '@/api/speExamineResService'
	import { loadModule } from "vue3-sfc-loader/dist/vue3-sfc-loader"
	import wdCheckbox from 'wot-design-uni/components/wd-checkbox/wd-checkbox.vue'
	import wdButton from 'wot-design-uni/components/wd-button/wd-button.vue'
	import * as Vue from 'vue'
	import Fab from '@/components/Fab/index.vue'
	import { compile } from 'sass';
	import useUserStore from "@/store/user";
	const fabRef = ref()
	const proxy = getCurrentInstance()?.proxy
	const dynamicComponent = shallowRef();
	const templateStr = ref('')
	const archiveInfo = computed(() => {
		return useUserStore().getSelectArchive()
	})
	const reportFun = (val : any) => {
		if (!val.archivesId) {
			proxy.$pop.toast('请选择学生')
			nextTick(() => {
				fabRef.value.openAr()
			})
			return;
		}
		console.log('uniForms', uniForms)
		abnormalReport(val.archivesId).then(async (res : any) => {
			console.log(res)
			templateStr.value = res.data
			const options = {
				moduleCache: {
					vue: Vue,
					'uniForms': uniForms,
					'uniFormsItem': uniFormsItem,
					'uniEasyinput': uniEasyinput,
					'wdCheckbox': wdCheckbox,
					'wdButton': wdButton,
					'scss': (source) => {
						console.log('======>source',source)
						return Object.assign(compile(source), { deps: () => [] })
					}
				},
				async getFile() {
					return res.data
				},
				addStyle(textContent) {
					console.log('textContent,', textContent)
					const style = Object.assign(document.createElement('style'), { textContent })
					console.log('style,', style)
					const ref = document.head.getElementsByTagName('style')[0] || null
					document.head.insertBefore(style, ref)
				},
				loader: {
					
				}
			};
			dynamicComponent.value = defineAsyncComponent(() => loadModule(res.fileName || "loader.vue", options))
		})
	}
	const selectAr = async (val : any) => {
		reportFun(val)
	}
	onLoad(() => {
		reportFun(archiveInfo.value)
	})
</script>
<style lang="scss">

</style>

页面效果图

在这里插入图片描述


http://www.kler.cn/a/511756.html

相关文章:

  • 和优秀的人一起共事,你会越来越优秀!
  • kubernetes学习-Service(七)
  • 数据库管理-第285期 Oracle 23ai:深入浅出向量索引(20250117)
  • Vue3数据响应式原理
  • IO进程----进程
  • 华为HuaweiCloudStack(一)介绍与架构
  • React总结
  • 合合信息DocFlow产品解析与体验:人人可搭建的AI自动化单据处理工作流
  • UE虚幻引擎No Google Play Store Key:No OBB found报错如何处理?
  • 【spring boot统一功能处理】拦截器
  • 梯度提升决策树树(GBDT)公式推导
  • 【面试题】JVM部分[2025/1/13 ~ 2025/1/19]
  • pytest+playwright落地实战大纲
  • leetcode242-有效字母异位词
  • RoCE网络及其协议栈详解(没有中间商赚差价的网络)
  • 快速排序练习
  • Linux:生产者消费者模型
  • 第 3 章 核心处理层(上)
  • Bash 中 nohup 与 的区别及用法解析
  • leetcode416.分割等和子集
  • nginx作为下载服务器配置
  • Python人脸识别库DeepFace使用教程及源码解析
  • imbinarize函数用法详解与示例
  • python 基础类json和csv
  • 深入剖析iOS网络优化策略,提升App性能
  • 【LC】2239. 找到最接近 0 的数字