论表单设计器(vue)-动态JS的可行性方案研究

前言

目前自己开源了一个低代码开发平台,里面主要包含流程设计器、表单设计器、代码生成器。其中在设计表单设计器时碰到了一些问题,在这里想与大家分享一下。

问题来源

在设计表单设计器的时候,如果针对开发者(而非业务人员时),经常需要手动写JS或者CSS调整样式,那么 平台如何去覆盖这一层需求呢?

问题分析

可不可以 针对每一个组件,都设置一个 动态JS属性和CSS属性变量,开发者将手动输入对应脚本。就会引出以下几个问题:

  1. 如何设置动态脚本呢?
  2. 这个脚本如何与vue 的method 关联呢?
  3. 可以做到动态method 吗?
  4. 如何触发这个脚本呢?
    下面带着几个问题进一步探讨。

提出方案

通过设置动态字符串,然后将 字符串渲染成可执行函数。将这个函数 通过动态事件绑定到组件中。
动态事件: v-on="{eventName:methodName(param),eventName1:methodName1(param1)}" 即v-on="{触发事件名称(如:click,change,bulr…):方法名(参数…)}"

解决方案

问题一 :如何设置动态脚本呢?

方案一:重新构造script标签(不推荐)

分析

这个思路其实非常简单,用innerHTML添加的script无法执行,但是我们script创建节点,并用appendChild追加上去是可以的,所以我们只需要做一下二次工作就可以了,看下面的例子:

示例
<div id="easyBpm"></div>
var html = '<div>html</div><script>console.log(1);<\/script>';
var easyBpm= document.getElementById('easyBpm');
cont.innerHTML = html;
var oldScript = cont.getElementsByTagName('script')[0];
easyBpm.removeChild(oldScript);
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.innerHTML = oldScript.innerHTML;
easyBpm.appendChild(newScript);

方案二: eavl()(不推荐)

分析

虽然eval因为其安全性不推荐使用,但是在此特殊场景,使用eval确是非常简单的解决方案,就是把script标签中的代码eval一下手动执行,就ok了,看下面代码:

示例
var html = '<div>html</div><script>console.log(1);<\/script>';
var easyBpm= document.getElementById('easyBpm');
cont.innerHTML = html;
var oldScript = cont.getElementsByTagName('script')[0];
easyBpm.removeChild(oldScript);
var scriptText = oldScript.innerHTML;
eval(scriptText);

方案三: new Function()(推荐)

分析

有一个很少被用到的新建函数的方法,但是有时候不得不使用它。new Function允许将任何字符串转换为函数,传入name参数和字符串函数体,字符串函数体由模板字符串提供,非常简洁方便。

语法 
let func = new Function ([arg1[, arg2[, ...argN]],] functionBody)

换句话说,函数的参数(或更确切地说,各参数的名称)首先出现,而函数体在最后。所有参数都写成字符串形式。

示例

通过查看示例,可以更容易理解。这是一个有两个参数的函数:

let sum = new Function('a', 'b', 'return a + b');
alert( sum(1, 2) ); // 3

如果所要新建的函数没有参数,那么new Function()只有一个函数体参数:

let sayHi = new Function('alert("Hello")');
sayHi(); // Hello

问题2 脚本如何与vue 的method 关联呢

解决方案:

通过定义一个固定的方法名,方法里调用 字符串解析的方法

问题3 可以做到动态method 吗?

答案显然是不可以的,可以通过 问题2 的解决方案 处理这个问题,就是方法名固定,具体方法是动态的。

问题 4. 如何触发这个脚本呢?

解决方案:

 v-on="{eventName:methodName(param),eventName1:methodName1(param1)}" 即v-on="{触发事件名称(如:click,change,bulr...):方法名(参数...)}" 

完整示例:

<template>
	<div id="app">
		<input   v-on="{change:dynamicFun}" />
	</div>
</template>
<script>
var app = new Vue({
  el: '#app',
  data() {
    return {
      myArray: [{id:1, name: 'aa'}],
      myArray2: [],
      funDetail: 'console.log(111)',
      eventName: 'change'
    }
  }, 

  methods: {
     dynamicFun() {
        var val = new Function(this.funDetail)
        val()
      
    }
  }
});
</script>

在这里插入图片描述
在这里插入图片描述

技术讨论群

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风中思絮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值