添加沙箱
This commit is contained in:
parent
c41039cdb5
commit
37e4e0d4a0
@ -1,11 +1,73 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { Button, Input, Space, Message } from "view-ui-plus";
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
const values = ref({ a: 1, b: 22, c: 3 })
|
||||||
|
const expression = ref('a+b')
|
||||||
|
const result = ref('')//, message = ref('')
|
||||||
|
|
||||||
|
// 沙箱
|
||||||
|
function sandbox(code: string) {
|
||||||
|
code = 'with (sandbox) {return ' + code + '}'
|
||||||
|
const fn = new Function('sandbox', code)
|
||||||
|
// const unscopables = { testB: true };
|
||||||
|
return function (sandbox: any) {
|
||||||
|
const sandboxProxy = new Proxy(sandbox, {
|
||||||
|
has: (target: Object, prop: string) => {
|
||||||
|
// console.log('has->', target, prop)
|
||||||
|
return target.hasOwnProperty(prop) || prop in target;
|
||||||
|
},
|
||||||
|
get(target, key) {
|
||||||
|
// console.log('get->', target, key)
|
||||||
|
if (key === Symbol.unscopables) return null;
|
||||||
|
return target[key]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return fn(sandboxProxy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onCalculate = () => {
|
||||||
|
if (expression.value.length === 0) {
|
||||||
|
Message.warning("请输入表达式")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 从expression获取计算表达式并读取values中的参数计算最终数据
|
||||||
|
// 然后将结果赋值给result
|
||||||
|
// 注意:values中的参数名要与expression中的参数名一致
|
||||||
|
// 例如:values中的参数名为a,b,c,则expression中的参数名也要为a,b,c
|
||||||
|
|
||||||
|
try {
|
||||||
|
const func = sandbox(expression.value)
|
||||||
|
Object.keys(values.value).forEach(key => {
|
||||||
|
// 转换成数字
|
||||||
|
//@ts-ignore
|
||||||
|
values.value[key] = Number(values.value[key])
|
||||||
|
})
|
||||||
|
const value = func(values.value);
|
||||||
|
result.value = value; //eval(expression.value)
|
||||||
|
} catch (e) {
|
||||||
|
result.value = "计算错误:" + (e as Error).message
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<h1>product</h1>
|
<div>
|
||||||
|
<h1>动态计算</h1>
|
||||||
|
<Space direction="vertical" style="width: 100%">
|
||||||
|
<Space>
|
||||||
|
<Input type="number" v-model="values.a" />
|
||||||
|
<Input type="number" v-model="values.b" />
|
||||||
|
<Input type="number" v-model="values.c" />
|
||||||
|
</Space>
|
||||||
|
<div class="calculator">
|
||||||
|
<Input v-model="expression" type="textarea" :rows="4" placeholder="请输入计算公式" />
|
||||||
|
</div>
|
||||||
|
<Button @click="onCalculate">计算</Button>
|
||||||
|
<div v-if="expression.length > 0 && result">结果:{{ expression }} = {{ result }}</div>
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss"></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user