添加沙箱

This commit is contained in:
LittleBoy 2023-12-31 21:40:28 +08:00
parent c41039cdb5
commit 37e4e0d4a0

View File

@ -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;
}
// expressionvalues
// result
// valuesexpression
// valuesa,b,cexpressiona,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>