js变量如何转字符串(函数序列化), 回显到在线编辑器?

71 阅读1分钟

楔子: 再基于 ag-grid 封装 table 组件时, 工具栏要加很多功能块, 不同的功能块以及自带的列拖拽排序, 列显隐等用户交互过程, 都会修改 col属性ns, 很容易随着功能的扩展而造成 bug, 因此,希望通过一个在线的代码编辑器,来手动编辑 columns, 所见即所得, 之后保存这段 columns 服务器,之后再回显, 之后扩展的功能也只是搞一个gui而已,实质还是修改这唯一的一份columns, 这种方式能避免交互过程中造成的很多 bug,

image.png

掘金搜函数系列化相关的,就只有徐小夕(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}
            />