在肝电商后台管理系统的项目时,希望对提交到表单对象做一个深拷贝从而对新对象中的数据进行后台数据匹配,教程中的方法是安装lodash依赖,其中提供了深拷贝的方法,一搜发现这个依赖居然有180M!不就是实现一个深拷贝嘛,于是我就想在methods中自己定义了一个深拷贝函数:

 methods: {
    //深拷贝
    deepClone(obj) {
      if (typeof obj !== 'object' || obj == null) {
          // obj 是 null ,或者不是对象和数组,直接返回
          return obj
      }
      // 初始化返回结果
      let result
      if (obj instanceof Array) {
          result = []
      } else {
          result = {}
      }

      for (let key in obj) {
          // 保证 key 不是原型的属性
          if (obj.hasOwnProperty(key)) {
              // 递归调用!!!
              result[key] = deepClone(obj[key])
          }
      }
      // 返回结果
      return result
    },
    // 获取分类列表
    
    //点击添加按钮添加商品到数据库
    addGoods(){
      this.$refs.addRefs.validate((valid)=>{
        console.log(this.deepClone);
        if(!valid){
          return this.$message.error('请填写必要的表单项')
        }
        console.log(this.addForm);
        // const form = JSON.parse(JSON.stringify(this.addForm))
        const form = this.deepClone(this.addForm)
        form.goods_cate = form.goods_cate.join(',')
        console.log(form);

      })
    }
  },

点击添加按钮后,好家伙报错了:

但是我发现在addGoods函数中打印this.deepClone是可以拿到deepClone这个方法的,仔细回过头去看deepClone发现使用递归时用的是result[key] = deepClone(obj[key])! 这就导致了在第二次“递归”时,vue就不认得deepClone这个东西了,后来我想着将递归项换成result[key] = arguments.callee(obj[key]),运行代码后又会报错:

这好像是因为caller callee arguments无法在严格模式下使用。当我想用JSON方法进行深拷贝的时候(const form = JSON.parse(JSON.stringify(this.addForm)) 事实证明是有效的~~),我发现好像可以在将递归项的deepClone前加上this

for (let key in obj) {
          // 保证 key 不是原型的属性
          if (obj.hasOwnProperty(key)) {
              // 递归调用!!!
              result[key] = this.deepClone(obj[key])
          }
      }

这样每次“递归”,Vue都拿到这个deepClone,问题圆满解决。
总结来说就是,在vue中使用递归函数时,一定要注意递归项的写法。但其实在vue中不管是调用methods中的方法还是data中的数据,this是一个经常被忽略的问题,一定要仔细对待,多码多码。

更多推荐

在vue方法中要谨慎定义递归函数