今天在项目开发中,遇到从后端返回的vue文件(包含template,js,css)的文件,试过用v-html解析文件,渲染到页面,但是无法渲染,后来去查了一堆资料,自己写了一个全局方法来解析这类文件

1,在项目目录新建一个mixin文件,再创建一个strToVueFormMixin.js文件,文件内容为:

import {
invokeServiceWait,
checkRequestStatus,
handleCallbackFn,
} from "@/InitMethods/formHttp";
export default {
data() {
return {
_form: null,
isStartLoad: false,
};
},
methods: {
/**
* 替换元素的style font-size
*/
replaceStyleFontSize(templateStr){
let fontSize = localStorage.getItem('fontSizeMultiplier');
// 存在获取fontSizeMultiplier为null时 默认字体放大倍数取1
fontSize==null?fontSize=1:fontSize;
if(fontSize){
let fontSizeExp= /(\s?font-size:\s?)([0-9.]+)([a-zA-Z]*)/g //let fontSizeExp = /(\s?font-size:\s?)([0-9.]+)([a-zA-Z]*[\s|;|}|\)])/g;
templateStr= templateStr.replace(fontSizeExp,(match, key, n, unit) => {
console.log(match)
return key + Number(n) * fontSize + unit;
})
return templateStr
} },
/**
* 服务器表单字符串转化Vue表单挂在到对应DOM节点
*
* @param {String} formStr VueFrom文件的字符串
* @param {String} queryStr Vue实例需要挂在DOM节点的id或者class
*
*/
strToVueForm(formStr, queryStr) {
if (typeof formStr == "string" && formStr.length) {
// 检查id是否存在
if (!document.querySelector(`${queryStr}`)) {
console.error('"id" or "class" does not exist!');
return {};
}
let fromStyleDom = null;
let styleBegin = 0; // style截取开始位置
let styleEnd = 0; // style截取结束位置
let templateBegin = 0; // template截取开始位置
let templateEnd = 0; // template截取结束位置
let scriptBegin = 0; // script截取开始位置
let scriptEnd = 0; // script截取结束位置 // 解析Vue字符串文件中的样式并添加到app全局中
if (formStr.indexOf("<style") > -1) {
styleBegin = formStr.indexOf("<style") + "<style".length;
styleEnd = formStr.indexOf("</style>");
let styleStr = formStr.substring(styleBegin, styleEnd);
// 再次去除stlye中的属性设置(例如:lang="sass" scoped)
let styleStartIndex = styleStr.indexOf(">") + 1;
styleStr = styleStr.substring(styleStartIndex);
// 添加到全局样式中
if (styleStr) {
fromStyleDom = document.createElement("style");
fromStyleDom.innerHTML = styleStr;
// style样式插入header中
document.head.appendChild(fromStyleDom);
}
} // 解析Vue字符串模板中的template以及script并挂到对应的dom节点
templateBegin = formStr.indexOf("<template>") + "<template>".length;
templateEnd = formStr.lastIndexOf("</template>");
let templateStr = formStr.substring(templateBegin, templateEnd);
templateStr = templateStr
.replace(/\r\n/g, " ")
.replace(/\n/g, " ")
.replace(/"/g, '\\"');
console.log("templateStr前",templateStr)
templateStr=this.replaceStyleFontSize(templateStr)
console.log("templateStr后",templateStr)
templateStr = 'let formtemplate ="' + templateStr + '";\n';
scriptBegin = formStr.indexOf("<script>") + "<script>".length;
scriptEnd = formStr.indexOf("</script>");
let scriptStr = formStr.substring(scriptBegin, scriptEnd);
// 防止window.vue.extend之前还定义了变量导致Cusform赋值无法得到window.vue.extend
if (scriptStr.indexOf(window.vue.extend) != 0) {
scriptStr = scriptStr.replace(
/window.vue.extend/,
"var Cusform = window.vue.extend"
);
} else {
scriptStr = "let Cusform =" + scriptStr;
}
let insetIndex =
scriptStr.indexOf("window.vue.extend({") +
"window.vue.extend({".length;
// 添加beforeDestroy
let destroyMixinStr = `
mixins:[{
beforeDestroy: function() {
fromStyleDom && fromStyleDom.remove()
}
}],`;
scriptStr =
scriptStr.slice(0, insetIndex) +
destroyMixinStr +
scriptStr.slice(insetIndex);
// console.log("scriptStr:", scriptStr);
let Cusform = eval(templateStr + scriptStr + ";" + "Cusform");
this.isStartLoad = false;
Cusform.prototype.invokeServiceWait = invokeServiceWait;
Cusform.prototype.isStartLoad = false;
Cusform.prototype.checkRequestStatus = function () {
return checkRequestStatus(this.isStartLoad);
}; let vueForm = new Cusform().$mount(`${queryStr}`); this._form = vueForm;
vueForm.isStartLoad = true;
this.isStartLoad = true; return vueForm;
} else {
return {};
}
},
},
beforeDestroy() {
this._form && this._form.$destroy();
},
};

2,如何使用:

在新建文件是要用到mixin时,我们只要引入就可以使用了

新建MyPaidLeaveInfo.js文件:

import strToVueFormMixin from '@/mixins/strToVueFormMixin';
export default {
mixins: [strToVueFormMixin],
name: 'PaidLeaveInfoPC',
data() {
return {
fileStr:'',
myForm:{},
formLoadStatus: null,
}
},
mounted() {
this.init();
},
methods: {
// 获取PaidLeaveInfoPC表单
getFile() {
return new Promise((resolve, reject) => {
this.invokeService(
'AnnualLeave',
'GetCustomForm',
['PaidLeaveInfoPC'],
msg => {
const $ = msg.ReturnData.$;
if ($.Succeed) {
const fileStr = Lark.base64Decode($.Data);
this.fileStr = fileStr;
resolve(fileStr);
} else {
reject();
}
},
err => {
reject(err);
}
);
});
},
init() {
this.formLoadStatus = new Promise((resolve, reject) => {
this.getFile()
.then(file => this.fileToHtml(file))
.then(() => {
resolve();
})
.catch(err => {
console.log(err,'err');
reject();
});
});
},
// 后端返回的数据转为vhtml
fileToHtml(file) {
file = file.replace(/wfm-popup/g, 'paidleaveinfoPC-popup');
let vueForm = this.strToVueForm(file, '#paidLeaveInfoPC');
this.myForm = vueForm;
return Promise.resolve();
}
}
}

新建MyPaidLeaveInfo.vue文件

只需要定义一个容器包住就可以了

<template>
<el-row>
<el-header style="height: 30px" class="wfm-first-header"
><WFMBreadcrumb></WFMBreadcrumb
></el-header>
<div id="paidLeaveInfoPC"></div>
</el-row>
</template> <script>
import MyPaidLeaveInfoJS from './MyPaidLeaveInfo.js';
export default MyPaidLeaveInfoJS;
</script> <style lang="scss" scoped>
@import './MyPaidLeaveInfo.scss';
</style>

服务器表单字符串转化Vue表单挂在到对应DOM节点的更多相关文章

  1. React 事件对象、键盘事件、表单事件、ref获取dom节点、react实现类似Vue双向数据绑定

    1.案例实现代码 import React, { Component } from 'react'; /** * 事件对象.键盘事件.表单事件.ref获取dom节点.react实现类似Vue双向数据绑 ...

  2. vue 钩子函数中获取不到DOM节点

    原文链接:https://jingyan.baidu.com/article/f96699bbfe9c9d894f3c1b4b.html 两种解决方案: 1:官方解决方案: 受到 HTML 本身的一些 ...

  3. vue,在模块中动态添加dom节点,并监听

    在这里,onclick事件没有作用,因为它指向的是window,如果写为this.click页面显示为undefined, 我采用的是通过class绑定事件,但是会有一个问题,那就是当你渲染多个事件时 ...

  4. 六、React 键盘事件 表单事件 事件对象以及React中的ref获取dom节点 、React实现类似Vue的双向数据绑定

    接:https://www.cnblogs.com/chenxi188/p/11782349.html 事件对象 .键盘事件. 表单事件 .ref获取dom节点.React实现类似vue双向数据绑定 ...

  5. 第四节:Vue表单标签和组件的基本用法,父子组件间的通信

    vue表单标签和组件的基本用法,父子组件间的通信,直接看例子吧. <!DOCTYPE html> <html> <head> <meta charset=&q ...

  6. Vue表单

    gitHub地址: https://github.com/lily1010/vue_learn/tree/master/lesson11 一 vue表单 实在是太简单了,直接来个例子 <!DOC ...

  7. Vue表单控件绑定

    前面的话 本文将详细介绍Vue表单控件绑定 基础用法 可以用 v-model 指令在表单控件元素上创建双向数据绑定.它会根据控件类型自动选取正确的方法来更新元素.v-model本质上不过是语法糖,它负 ...

  8. Vue表单绑定(单选按钮,选择框(单选时,多选时,用 v-for 渲染的动态选项)

    <!DOCTYPE html><html>    <head>        <meta charset="utf-8">      ...

  9. vue 表单校验(二)

    vue 表单校验(二) vue element-ui表单校验 由于现在使用element-ui进行form表单校验,因而使用其自带的校验规则进行校验,发现有些并不是那么好校验,或者说是校验起来很繁琐, ...

随机推荐

  1. 关于某 App 请求参数 sign 字段加密分析

    受害者: 6ZqG5LyX5pWw5o2u 通过 Charles 抓包发现关键信息请求均携带 sign 参数,且每次请求的值都不一样: 使用 jadx 将对应的 apk 反编译并分析,全局搜素 &qu ...

  2. [BUUCTF]REVERSE——[FlareOn4]login

    [FlareOn4]login 附件 步骤: 是个网页,直接打开,查看网页源码 百度了几个函数 charCodeAt(0)是返回当前字符的Unicode 编码 String.fromCharCode返 ...

  3. FFmpeg开发笔记(十):ffmpeg在ubuntu上的交叉编译移植到海思HI35xx平台

    FFmpeg和SDL开发专栏(点击传送门) 上一篇:<FFmpeg开发笔记(九):ffmpeg解码rtsp流并使用SDL同步播放>下一篇:敬请期待   前言   将ffmpeg移植到海思H ...

  4. java 图形化小工具Abstract Window Toolit 常用组件

    基本组件 Button: 按钮,可接受单击操作 Canvas: 用于绘图的画布 Checkbox: 复选框组(也可变成单选框组件) CheckboxGroup: 用于将多个checkbox组件组合成一 ...

  5. IDE Goland DEBUG报错(could not launch process: decoding dwarf section info at offset 0x0: too short)

    背景: 在升级GO版本到1.11后发现Goland的Debug报错,如下:could not launch process: decoding dwarf section info at offset ...

  6. Qt5设置lineEdit正则表达式

    说明 本文演示Qt 版本: qt5.14 一个例子 下面的代码中演示 输入框只能输入 冒号.A-F.a-f,数字0~9,最长输入64个字符 /// 设置验证 auto le_set_check = [ ...

  7. 【LeetCode】33. Search in Rotated Sorted Array 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  8. E. Santa Claus and Tangerines

    E. Santa Claus and Tangerines time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

  9. java泛型中<?>和<T>

    T 代表一种类型 加在类上==============>class SuperClass<A>{} 加在方法上============>public <T>void ...

  10. 第四十个知识点 一般来说SPA和DPA的区别是什么

    第四十个知识点 一般来说SPA和DPA的区别是什么 原文地址:http://bristolcrypto.blogspot.com/2015/07/52-things-number-40-what-is ...