楔子: 再基于 ag-grid 封装 table 组件时, 工具栏要加很多功能块, 不同的功能块以及自带的列拖拽排序, 列显隐等用户交互过程, 都会修改 col属性ns, 很容易随着功能的扩展而造成 bug, 因此,希望通过一个在线的代码编辑器,来手动编辑 columns, 所见即所得, 之后保存这段 columns 服务器,之后再回显, 之后扩展的功能也只是搞一个gui而已,实质还是修改这唯一的一份columns, 这种方式能避免交互过程中造成的很多 bug,
掘金搜函数系列化相关的,就只有徐小夕(xijs)的这一篇, 以及GitHub上的 jsonfn
,
他的方式是在函数前➕前缀来作为标记, 也实现了函数序列化,但是在 在线代码编辑器里编辑时,没有用户体验而言,考虑自己实现
使用方式
const input = [
{
title: '分日',
compare: () => 0,
cellStyle: ()=> ({color:'red'}),
},
]
const ouput = variantToString(input)
console.log(ouput) //
实现方式
ps: 也可以不使用 json5 , 使用 json5 是因为它较为宽松,适合在线编辑这种场景
import JSON5 from 'json5'
export const variantToString = (
input,
space?: number | string,
prefix = '@'
): string => {
const jsonStr = JSON5.stringify(
input,
(k, v) => (typeof v === 'function' ? `${prefix}${v}${prefix}` : v),
space
)
const regExp = new RegExp(`(['"]${prefix})|(${prefix}['"])`, 'g')
const codeString = jsonStr.replace(regExp, '')
return codeString
}
export const tryEval = (input: string) => {
return eval(input)
}
在编辑器里使用时
import Editor, { loader } from '@monaco-editor/react'
import { tryEval, variantToString } from '@/utils/variantToString'
const [code, setCode] = useState(columnDefs)
useDidUpdate(() => {
setCode(variantToString(columnDefs, 2))
}, [columnDefs])
// 保存时,回显时
const onSubmit = useCallback(() => {
const value = tryEval(code)
onColumnDefsChange(value)
}, [code, onColumnDefsChange])
<Editor
height="50vh"
defaultLanguage="typescript"
value={code}
onChange={setCode}
/>