服务器表单字符串转化Vue表单挂在到对应DOM节点
今天在项目开发中,遇到从后端返回的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节点的更多相关文章
- React 事件对象、键盘事件、表单事件、ref获取dom节点、react实现类似Vue双向数据绑定
1.案例实现代码 import React, { Component } from 'react'; /** * 事件对象.键盘事件.表单事件.ref获取dom节点.react实现类似Vue双向数据绑 ...
- vue 钩子函数中获取不到DOM节点
原文链接:https://jingyan.baidu.com/article/f96699bbfe9c9d894f3c1b4b.html 两种解决方案: 1:官方解决方案: 受到 HTML 本身的一些 ...
- vue,在模块中动态添加dom节点,并监听
在这里,onclick事件没有作用,因为它指向的是window,如果写为this.click页面显示为undefined, 我采用的是通过class绑定事件,但是会有一个问题,那就是当你渲染多个事件时 ...
- 六、React 键盘事件 表单事件 事件对象以及React中的ref获取dom节点 、React实现类似Vue的双向数据绑定
接:https://www.cnblogs.com/chenxi188/p/11782349.html 事件对象 .键盘事件. 表单事件 .ref获取dom节点.React实现类似vue双向数据绑定 ...
- 第四节:Vue表单标签和组件的基本用法,父子组件间的通信
vue表单标签和组件的基本用法,父子组件间的通信,直接看例子吧. <!DOCTYPE html> <html> <head> <meta charset=&q ...
- Vue表单
gitHub地址: https://github.com/lily1010/vue_learn/tree/master/lesson11 一 vue表单 实在是太简单了,直接来个例子 <!DOC ...
- Vue表单控件绑定
前面的话 本文将详细介绍Vue表单控件绑定 基础用法 可以用 v-model 指令在表单控件元素上创建双向数据绑定.它会根据控件类型自动选取正确的方法来更新元素.v-model本质上不过是语法糖,它负 ...
- Vue表单绑定(单选按钮,选择框(单选时,多选时,用 v-for 渲染的动态选项)
<!DOCTYPE html><html> <head> <meta charset="utf-8"> ...
- vue 表单校验(二)
vue 表单校验(二) vue element-ui表单校验 由于现在使用element-ui进行form表单校验,因而使用其自带的校验规则进行校验,发现有些并不是那么好校验,或者说是校验起来很繁琐, ...
随机推荐
- 突破类型限制的“数据透视图”(Excel技巧集团)
Excel中,图表一共16个大类,但是数据透视图却被"阉"了好几个-- 这也就是说,数据透视图无法与上图中高亮标出的图表类型并存了? 确实如此,但并不绝对,因为我们可以在" ...
- Docker从入门到精通(七)——容器数据共享
什么是容器数据共享?简单来说就是容器与容器之间数据共享,容器与宿主机数据共享. 1.为什么需要数据共享? ①.数据持久化 比如我们有一个MySQL集群,通过容器启动,那么项目运行过程中的数据是保存在容 ...
- vscode配置指南,美化技巧
vscode配置指南,美化技巧 vscode****选中部分高亮 "workbench.colorCustomizations": { "editor.selection ...
- Linux httpd搭建
Linux 搭建网站 配置网络 1 改对应配置文件 vi /etc/sysconfig/network-scripts/ifcfg-ens32 2 使用命令 nmcli connection add ...
- HttpServletResponse工具类和HttpServletRequest工具类,前台参数接收方式和后台返回(JSON)数据格式
RequestUtils.java 操作类 package cn.utils; import org.apache.commons.lang3.StringUtils; import org.slf4 ...
- 【剑指Offer】04. 二维数组中的查找 解题报告(Java & Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 日期 题目地址:https://leetcode-cn.com/ ...
- 最大流问题的Ford-Fulkerson模板
详细讲解:http://blog.csdn.net/smartxxyx/article/details/9293665 下面贴上我的第一道最大流的题: hdu3549 1 #include<st ...
- 洛谷1052——过河(DP+状态压缩)
题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数 ...
- 如何基于LSM-tree架构实现一写多读
一 前言 PolarDB是阿里巴巴自研的新一代云原生关系型数据库,在存储计算分离架构下,利用了软硬件结合的优势,为用户提供具备极致弹性.海量存储.高性能.低成本的数据库服务.X-Engine是阿里巴 ...
- 【优雅代码】01-lombok精选注解及原理
[优雅代码]01-lombok精选注解及原理 欢迎关注b站账号/公众号[六边形战士夏宁],一个要把各项指标拉满的男人.该文章已在github目录收录. 屏幕前的大帅比和大漂亮如果有帮助到你的话请顺手点 ...