满口金牙 2022-06-25 14:27 采纳率: 91.5%
浏览 64
已结题

Vue 要做 一个 对象{} 的 修改后的 恢复功能,请教

要做 一个 对象{} 的 修改后的 恢复功能,

实现很简单。弄一个数组 arr
每次修改前深拷贝一个 对象, arr.push 一个进去。 恢复时依次取出就行。

但是我看了一下 wps 或 office 的恢复功能,所有操作步骤,可以一直恢复出来

这样,我的想法就太简单了。 当 对象{} 大的时候,会不会很占资源?。

其实有时 仅是修改了 对象 一个小局部。只要恢复这个局部就行。
如果是备份局部,我现的想法如下:

arr = 备份数组
function(){
obj 是要 修改的对象
a = obj 1 先备份一个 整体
b = obj 2 执行修改后的 整体

这里时进行 obj 1 与 obj 2 的 比对
c= 比对 a 和b,把不同的部份
把 c 加入 备份数组。arr.pusth(c)

恢复时,就把 c 再和 当前{} 比对,一个一个改回去
}

这里请教,一般你们遇到这种需求,会怎么做 ,有什么好方法

  • 写回答

3条回答 默认 最新

  • CSDN专家-showbo 2022-06-25 14:41
    关注

    用Proxy监控对象属性更改,arr数组直接压入被修改的操作,比如键名称和原始值。简单示例如下

    <script>
        var ops = [];//操作历史
        var obj = {old:111};
        var proxy = new Proxy(obj, {
            set: function (target, key, value, receiver) {
                let op = { key};
                if (target[key] === undefined) {//不存在这个属性则标记操作未新增
                    op.op = 'add';
                } else {
                    op.op = 'update';
                    op.value = target[key];//存储旧值
                }
                ops.push(op);
                return Reflect.set(target, key, value, receiver)
            },
            deleteProperty: function (target, key) {
                let op = { key, value:target[key], op: 'delete' };
                ops.push(op);
                delete target[key];//操作原对象
                return true;
            }
        });
    
        //设置内容,操作proxy对象
        delete proxy.old;
        console.log(JSON.stringify(obj))
        console.log(JSON.stringify(ops))
        console.log('\n\n')
    
        proxy.prop1 = 'prop1value'
        console.log(JSON.stringify(obj))
        console.log(JSON.stringify(ops))
        console.log('\n\n')
    
        proxy.prop1 = 'prop1-new-value'
        console.log(JSON.stringify(obj))
        console.log(JSON.stringify(ops))
        console.log('\n\n')
    
        //还原操作,直接操作obj对象,而不是proxy
        let op
        while (op = ops.pop()) {
            if (op.op == 'update') {//修改则还原原旧值
                obj[op.key] = op.value;//还原原来的值
            }
            else if (op.op == "add") {//新增,反向操作则是删除
                console.log(op.key)
                delete obj[op.key];
            }
            else if (op.op == 'delete') {//删除操作补回属性
                obj[op.key] = op.value;
            }
            console.log(JSON.stringify(obj))
            console.log(JSON.stringify(ops))
            console.log('\n\n')
        }
    </script>
    

    下面是 Proxy 支持的拦截操作一览,一共 13 种。
    get(target, propKey, receiver):拦截对象属性的读取,比如proxy.foo和proxy['foo']。
    set(target, propKey, value, receiver):拦截对象属性的设置,比如proxy.foo = v或proxy['foo'] = v,返回一个布尔值。
    has(target, propKey):拦截propKey in proxy的操作,返回一个布尔值。
    deleteProperty(target, propKey):拦截delete proxy[propKey]的操作,返回一个布尔值。
    ownKeys(target):拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。
    getOwnPropertyDescriptor(target, propKey):拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。
    defineProperty(target, propKey, propDesc):拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。
    preventExtensions(target):拦截Object.preventExtensions(proxy),返回一个布尔值。
    getPrototypeOf(target):拦截Object.getPrototypeOf(proxy),返回一个对象。
    isExtensible(target):拦截Object.isExtensible(proxy),返回一个布尔值。
    setPrototypeOf(target, proto):拦截Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
    apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。
    construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(...args)。

    具体可以参考阮一峰老师的教程

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 7月3日
  • 已采纳回答 6月25日
  • 创建了问题 6月25日

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?