服务器表单字符串转化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表单校验,因而使用其自带的校验规则进行校验,发现有些并不是那么好校验,或者说是校验起来很繁琐, ...
随机推荐
- vscode提示提示安装似乎损坏,请重新安装
安装 Fix VSCode Checksums 插件 Ctrl+Shift+P , 输入Fix Checksums : Apply, 点击,重启即可
- CF1041B Buying a TV Set 题解
Content 给定四个数 \(a,b,c,d\),求满足以下条件的数对 \((x,y)\) 的个数: \(x\leqslant a,y\leqslant b\). \(\dfrac{x}{y}=\d ...
- JS自动播放音频 无效chrome设置 (Uncaught (in promise) DOMException: play() failed because the user didn't interact)
Chrome的autoplay政策在2018年4月做了更改.新的行为:浏览器为了提高用户体验,减少数据消耗,现在都在遵循autoplay政策,Chrome的autoplay 政策非常简单 muted ...
- python爬取信息到数据库与mysql简单的表操作
python 爬取豆瓣top250并导入到mysql数据库中 import pymysql import requests import re url='https://movie.douban.co ...
- Linux(centos)创建用户并分配权限
创建名为 elas的用户 adduser elas 初始化elas的密码 passwd elas 显示 新的 密码: 重新输入新的 密码: passwd:所有的身份验证令牌已经成功更新. 进行授权 个 ...
- Intellij IDEA添加插件
1. Lombok插件 IDEA增加对Lombok的支持 <!--lombok插件--> <dependency> <groupId>org.projectlomb ...
- 【LeetCode】1085. Sum of Digits in the Minimum Number 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 遍历 日期 题目地址:https://leetcode ...
- 【LeetCode】211. Add and Search Word - Data structure design 添加与搜索单词 - 数据结构设计
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 公众号:负雪明烛 本文关键词:Leetcode, 力扣,211,搜索单词,前缀树,字典树 ...
- LeetCode 1482. 制作 m 束花所需的最少天数
LeetCode 1482. 制作 m 束花所需的最少天数 题目 给你一个整数数组 bloomDay,以及两个整数 m 和 k . 现需要制作 m 束花.制作花束时,需要使用花园中 相邻的 k 朵花 ...
- Chapter 20 Treatment-Confounder Feedback
目录 20.1 The elements of treatment-confounder feedback 20.2 The bias of traditional methods 20.3 Why ...