支持es5函数和es6箭头的JSON.parse(JSON.stringify()) ?

问题

需求: 对象转成字符串,保存到数据库,返回前端后再转回对象?
想要2个方法:
一个是类似JSON.stringify转成字符串,不能丢失函数,支持function和箭头函数
另一个是类似JSON.parse转成对象,要还原对象中原来的函数

数据

      rule: [
        {
          type: "input",
          field: "goods_name",
          title: "商品名称",
          on: {
            change: function (val) {
              console.log("aa", val);
            },
            input: (val) => {
              console.log("bb", val);
            },
          },
        },
        {
          type: "datePicker",
          field: "created_at",
          title: "创建时间",
          on: {
            change: function (val) {
              console.log("cc", val);
            },
            input: (val) => {
              console.log("dd", val);
            },
          },
        },
      ],

方法

    function toJson(){

    }

    function toString(){
      
    }
阅读 1k
2 个回答

你可以学一下 form-create的方案,

具体使用是这种效果
1704423947916.png

import deepExtend from './deepextend';
import {err} from './console';
import is, {hasProperty} from './type';

const PREFIX = '[[FORM-CREATE-PREFIX-';
const SUFFIX = '-FORM-CREATE-SUFFIX]]';

const $T = '$FN:';
const $TX = '$FNX:';
const FUNCTION = 'function';

export function toJson(obj, space) {
    return JSON.stringify(deepExtend([], obj, true), function (key, val) {
        if (val && val._isVue === true)
            return undefined;

        if (typeof val !== FUNCTION) {
            return val;
        }
        if (val.__json) {
            return val.__json;
        }
        if (val.__origin)
            val = val.__origin;

        if (val.__emit)
            return undefined;
        return PREFIX + val + SUFFIX;
    }, space);
}

function makeFn(fn) {
    return (new Function('return ' + fn))();
}

export function parseFn(fn, mode) {
    if (fn && is.String(fn) && fn.length > 4) {
        let v = fn.trim();
        let flag = false;
        try {
            if (v.indexOf(SUFFIX) > 0 && v.indexOf(PREFIX) === 0) {
                v = v.replace(SUFFIX, '').replace(PREFIX, '');
                flag = true;
            } else if (v.indexOf($T) === 0) {
                v = v.replace($T, '');
                flag = true;
            } else if (v.indexOf($TX) === 0) {
                v = makeFn('function($inject){' + v.replace($TX, '') + '}');
                v.__json = fn;
                v.__inject = true;
                return v;
            } else if (!mode && v.indexOf(FUNCTION) === 0 && v !== FUNCTION) {
                flag = true;
            }
            if (!flag) return fn;
            const val = makeFn((v.indexOf(FUNCTION) === -1 && v.indexOf('(') !== 0) ? (FUNCTION + ' ' + v) : v);
            val.__json = fn;
            return val;
        } catch (e) {
            err(`解析失败:${v}\n\nerr: ${e}`);
            return undefined;
        }
    }
    return fn;
}

export function parseJson(json, mode) {
    return JSON.parse(json, function (k, v) {
        if (is.Undef(v) || !v.indexOf) return v;
        return parseFn(v, mode);
    });
}

借助eval函数的话,JSON自带的方法就能处理你这个需求

const obj = [
  {
    type: "input",
    field: "goods_name",
    title: "商品名称",
    on: {
      change: function (val) {
        console.log("aa", val);
      },
      input: (val) => {
        console.log("bb", val);
      },
    },
  },
  {
    type: "datePicker",
    field: "created_at",
    title: "创建时间",
    on: {
      change: function (val) {
        console.log("cc", val);
      },
      input: (val) => {
        console.log("dd", val);
      },
    },
  },
]

const jsonStr = JSON.stringify(obj, (k, v) => {
  return v instanceof Function ? v.toString() : v
})

console.log(jsonStr)

const result = JSON.parse(jsonStr, (k, v) => {
  if (v?.includes?.('function')) {
    const { fn } = eval(`"use strict";({fn:${v}})`)
    return fn
  }
  if (v?.includes?.('=>')) {
    return eval(v)
  }
  return v
})

console.log(result)
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题