多个对象合并的3种的简单方式,替换同key名的值

使用场景: 两个或多个对象需要合并,并且有相同的key时,用后面对象的value值
方法1: Object.assign(obj1, obj2)
这个方法是浅拷贝,则拷贝了对象的引用(也就是修改的话会影响到原对象)
特点: 若属性名相同,后面的属性会覆盖前面属性,对象和数组合并,数组会被转成对象,再被合并

const a = {
    name: 'Aimee',
    age: '19',
    phone: '18888888888'
}
const b = {
    name: 'lisa',
    age: '26',
    like: '13232231',
    objSon: {
        aaa: 'aaaaaa',
        bbb: 'bbbbbbb'
    }
}
const list = ['one', 'two', 'three']
const data = Object.assign(a, b)
console.log(data)
// 输出结果:{
//     name: 'lisa',
//     age: '26',
//     like: '13232231',
//     objSon: { aaa: 'aaaaaa', bbb: 'bbbbbbb' }
//   }
console.log(Object.assign(a, list))
// 输出结果:{
//     '0': 'one',
//     '1': 'two',
//     '2': 'three',
//     name: 'lisa',
//     age: '26',
//     like: '13232231',
//     objSon: { aaa: 'aaaaaa', bbb: 'bbbbbbb' }
//   }

方法2: 利用扩展运算符{…a, …b}
特点: 该方法不会改变对象a,不会改变对象b

// An highlighted block
const data2 = {...a, ...b}
console.log(data2)
// 输出:{
//     name: 'lisa',
//     age: '26',
//     like: '13232231',
//     objSon: { aaa: 'aaaaaa', bbb: 'bbbbbbb' }
//   }

方法3: _.merge(object, [sources])
如果要用深拷贝的小伙伴可以用lodash第三方库(https://www.lodashjs.com/docs/lodash.merge)
特点: 这方法会改变对象 object, 不会改变[sources],sources里面的子对象也可以被拷贝到

// An highlighted block
 let data3 = _.merge(a, b)
 console.log(data3)
 // 输出:{
//     name: 'lisa',
//     age: '26',
//     like: '13232231',
//     objSon: { aaa: 'aaaaaa', bbb: 'bbbbbbb' }
//   }

当然,自己手写函数也可以

<think>在Vue中,如果需要将多个对象合并成一个对象,可以使用JavaScript提供的方法。常见的有以下几种方式: 1. 使用`Object.assign()`方法 2. 使用扩展运算符(`...`) 3. 使用`Vue.set`或`this.$set`(当需要确保合并后的对象是响应式时) 注意:在Vue中直接给对象添加新属性不会触发视图更新,所以如果需要合并对象是响应式的,并且可能包含新属性,建议使用`Vue.set`或`this.$set`,或者使用`Object.assign`和响应式对象的已有属性进行覆盖(因为直接覆盖整个对象可能会失去响应性,所以更推荐使用覆盖已有对象方式)。 下面分别给出示例: ### 方法1:使用Object.assign ```javascript // 假设我们有两个对象 let obj1 = { a: 1, b: 2 }; let obj2 = { c: 3, d: 4 }; // 合并到一个新对象 let mergedObj = Object.assign({}, obj1, obj2); console.log(mergedObj); // { a:1, b:2, c:3, d:4 } // 在Vue组件中,如果希望将合并后的对象给组件的data属性,并且保持响应式,可以这样做: // 假设在data中有一个对象 data() { return { myObject: { a: 1 } } }, methods: { mergeObjects() { // 使用Object.assign将新属性合并到已有对象上(注意:第一个参数是目标对象) this.myObject = Object.assign({}, this.myObject, { b: 2 }, { c: 3 }); // 或者如果不想创建一个新对象,而是直接扩展原有对象,可以这样(但这样会改变原对象,Vue能够检测到变化): // Object.assign(this.myObject, { b: 2 }, { c: 3 }); } } ``` ### 方法2:使用扩展运算符 ```javascript let obj1 = { a: 1, b: 2 }; let obj2 = { c: 3, d: 4 }; let mergedObj = { ...obj1, ...obj2 }; console.log(mergedObj); // { a:1, b:2, c:3, d:4 } // 在Vue组件中的使用: methods: { mergeObjects() { // 将多个对象合并到data中的某个对象(创建一个新对象并赋) this.myObject = { ...this.myObject, ...{ b: 2 }, ...{ c: 3 } }; } } ``` ### 方法3:使用Vue.set(当需要动态添加响应式属性时) 如果只是需要将新属性合并到已有响应式对象上,并且确保新属性也是响应式的,可以使用`Vue.set`或`this.$set`,但是注意,`Vue.set`一次只能设置一个属性。所以对于多个属性,我们可以遍历新对象的属性,逐个设置。 ```javascript // 假设在Vue组件中 methods: { mergeObjects() { let newProps = { b: 2, c: 3 }; // 遍历newProps的属性,逐个使用$set Object.keys(newProps).forEach(key => { this.$set(this.myObject, key, newProps[key]); }); } } ``` 但是,如果我们需要合并多个对象,并且目标对象可能还不存在,或者需要深度合并,那么可能需要递归合并。对于深度合并,可以使用一些工具函数,比如`lodash.merge`。 ### 深度合并(使用lodash) ```javascript import _ from &#39;lodash&#39;; let obj1 = { a: 1, b: { c: 2 } }; let obj2 = { b: { d: 3 }, e: 4 }; let mergedObj = _.merge({}, obj1, obj2); // mergedObj: { a:1, b: { c:2, d:3 }, e:4 } // 在Vue组件中使用 this.myObject = _.merge({}, this.myObject, obj2); ``` 注意:使用`_.merge`会进行递归合并,而不仅仅是浅合并。 ### 在Vue中注意事项 在Vue中,直接给一个响应式对象添加新属性,这个属性不是响应式的。所以,如果合并对象包含新属性,并且希望这些新属性也是响应式的,那么: - 如果整个对象替换(使用`Object.assign`或扩展运算符创建一个新对象并赋),那么新对象的所有属性都是响应式的,因为Vue会重新将整个对象设置为响应式(在data中定义的属性,其重新赋会被Vue处理为响应式)。 - 如果使用`Object.assign`直接合并到现有对象(即第一个参数是现有对象),那么新添加的属性也会是响应式的吗?注意:Vue无法检测到对象属性的添加或删除(除了使用`Vue.set`)。但是,由于我们合并时使用的是`Object.assign`给已有对象添加新属性,Vue确实无法自动检测到。因此,在Vue中,推荐使用以下两种方式之一: 1. 创建一个全新的对象,然后赋给data中的属性(这样Vue会检测到整个对象替换,新对象的所有属性都会成为响应式)。 2. 使用`Vue.set`或`this.$set`来添加新属性。 然而,当使用`Object.assign`直接修改现有对象(如`Object.assign(this.myObject, newObject)`)时,Vue无法检测到属性的添加,所以不会触发视图更新。但是,如果修改的是已有属性,那么是可以检测到的。 因此,为了确保响应性,推荐: - 对于已知需要添加多个新属性的情况,使用创建一个新对象并赋方式(这样Vue会重新进行响应式处理)。 - 或者,使用`this.$set`逐个设置新属性(如果属性很多,可以循环)。 ### 示例:在Vue组件中安全合并 ```javascript // 方法1:创建新对象并赋(推荐) this.myObject = Object.assign({}, this.myObject, newObject1, newObject2); // 方法2:使用扩展运算符 this.myObject = { ...this.myObject, ...newObject1, ...newObject2 }; // 方法3:如果需要深度合并,使用lodash的merge this.myObject = _.merge({}, this.myObject, newObject1, newObject2); ``` 以上方法都会创建一个新对象,然后赋给`this.myObject`,这样Vue就能检测到变化,并且新对象的所有属性都会变成响应式。 ### 如果不想创建新对象,而是直接修改原对象,并且确保新属性是响应式的,可以这样: ```javascript // 使用$set逐个添加新属性 Object.keys(newObject).forEach(key => { // 如果该属性在原始对象中不存在,则使用$set添加 if (!(key in this.myObject)) { this.$set(this.myObject, key, newObject[key]); } else { // 如果已经存在,直接赋(因为已经是响应式,直接修改即可) this.myObject[key] = newObject[key]; } }); ``` 但是,如果属性很多,这种方法可能会影响性能,因为每个`$set`都会触发一次更新。所以,如果新属性很多,建议使用创建新对象替换方式。 ### 总结 在Vue中合并多个对象,推荐使用创建新对象并赋方式,这样能确保所有属性都是响应式的,并且代码简洁。 下面是一个在Vue组件中合并多个对象的完整示例: ```javascript export default { data() { return { obj1: { a: 1, b: 2 }, obj2: { c: 3, d: 4 }, mergedObj: {} }; }, created() { this.mergeObjects(); }, methods: { mergeObjects() { // 使用扩展运算符合并 this.mergedObj = { ...this.obj1, ...this.obj2 }; // 或者使用Object.assign // this.mergedObj = Object.assign({}, this.obj1, this.obj2); } } }; ``` 以上代码会在组件创建时合并两个对象,并将结果赋给`mergedObj`,这个对象的所有属性都是响应式的。 希望这个解释对你有帮助。 §§相关问题§§: 1. 在Vue中,如何确保对象新添加的属性是响应式的? 2. Vue中,使用Object.assign直接修改已有对象和创建一个新对象有什么区别? 3. 在Vue中,如何实现对象的深度合并? 4. 使用Vue.set一次只能设置一个属性,有没有办法一次性设置多个属性?</think>在 Vue 中合并多个对象有多种方法,下面是几种常用的实现方式及其详细解释: ### 方法1:使用 `Object.assign()`(浅合并) ```javascript // 在Vue组件中 methods: { mergeObjects() { const obj1 = { a: 1, b: 2 }; const obj2 = { c: 3, d: { e: 4 } }; const obj3 = { f: 5 }; // 合并对象(浅合并) const merged = Object.assign({}, obj1, obj2, obj3); // 在Vue中赋给响应式属性 this.mergedData = merged; console.log(merged); // 输出: { a: 1, b: 2, c: 3, d: { e: 4 }, f: 5 } } } ``` **说明**: - `Object.assign()` 执行浅合并(只合并第一层属性) - 第一个参数是目标对象(空对象 `{}` 避免修改原始对象) - 后续参数是源对象 - **注意**:属性会被后面的对象覆盖 ### 方法2:使用扩展运算符(浅合并) ```javascript // 在Vue组件中 methods: { mergeObjects() { const obj1 = { a: 1, b: 2 }; const obj2 = { b: 3, c: 4 }; // b会被覆盖 const obj3 = { d: 5 }; // 使用扩展符合并 const merged = { ...obj1, ...obj2, ...obj3 }; // 更新Vue响应式数据 this.mergedData = merged; console.log(merged); // 输出: { a: 1, b: 3, c: 4, d: 5 } } } ``` **说明**: - 语法更简洁 - 样是浅合并 - 属性后面覆盖前面 ### 方法3:使用 Lodash 的 `_.merge()`(深合并) ```javascript // 首先安装Lodash: npm install lodash import _ from &#39;lodash&#39;; // 在Vue组件中 methods: { mergeDeep() { const obj1 = { a: 1, b: { c: 2 } }; const obj2 = { b: { d: 3 }, e: 4 }; // 深度合并 const merged = _.merge({}, obj1, obj2); this.mergedData = merged; console.log(merged); // 输出: { a: 1, b: { c: 2, d: 3 }, e: 4 } } } ``` **说明**: - 执行递归深合并 - 嵌套对象也会被合并 - 需要安装 Lodash 库 ### 方法4:手动递归深合并 ```javascript function deepMerge(target, ...sources) { if (!sources.length) return target; const source = sources.shift(); if (isObject(target) && isObject(source)) { for (const key in source) { if (isObject(source[key])) { if (!target[key]) Object.assign(target, { [key]: {} }); deepMerge(target[key], source[key]); } else { Object.assign(target, { [key]: source[key] }); } } } return deepMerge(target, ...sources); } function isObject(item) { return item && typeof item === &#39;object&#39; && !Array.isArray(item); } // 在Vue中使用 methods: { customDeepMerge() { const obj1 = { a: 1, nested: { x: 10 } }; const obj2 = { b: 2, nested: { y: 20 } }; const merged = deepMerge({}, obj1, obj2); this.mergedData = merged; // 结果: { a: 1, b: 2, nested: { x: 10, y: 20 } } } } ``` ### Vue响应式注意事项 1. **直接赋**:使用上述方法创建新对象后,直接赋给Vue的data属性 ```javascript this.mergedData = Object.assign({}, ...objects); ``` 2. **保持响应式**: - 使用 `Vue.set` 或 `this.$set` 添加新属性 ```javascript // 添加新响应式属性 this.$set(this.existingObject, &#39;newProp&#39;, value); ``` - 需要深合并时建议使用 Lodash 或创建新对象 ### 完整Vue组件示例 ```vue <template> <div> <button @click="merge">合并对象</button> <pre>{{ mergedData }}</pre> </div> </template> <script> import _ from &#39;lodash&#39;; export default { data() { return { mergedData: {} } }, methods: { merge() { const user = { name: &#39;John&#39;, address: { city: &#39;NY&#39; } }; const account = { id: 1, address: { zip: &#39;10001&#39; } }; const preferences = { theme: &#39;dark&#39; }; // 方法1: 浅合并 // this.mergedData = Object.assign({}, user, account, preferences); // 方法2: 扩展运算符 // this.mergedData = { ...user, ...account, ...preferences }; // 方法3: 深合并 (推荐) this.mergedData = _.merge({}, user, account, preferences); // 结果: // { // name: &#39;John&#39;, // id: 1, // address: { city: &#39;NY&#39;, zip: &#39;10001&#39; }, // theme: &#39;dark&#39; // } } } } </script> ``` ### 选择建议: 1. 只需要合并第一层属性 → `Object.assign()` 或扩展运算符 2. 需要合并嵌套对象 → Lodash `_.merge()` 3. 需要自定义合并逻辑 → 手动递归实现 4. 在Vue中更新数据时,优先创建新对象而不是修改现有对象
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值