一、核心概念
Vue 项目中常见的 ... 三个点语法 ,本质是 ES6 扩展运算符(展开运算符) 与剩余参数运算符,并非 Vue 专属语法,属于原生 JavaScript 核心语法,是 Vue 日常开发中使用率极高的精简写法。
该语法包含两大核心能力,各司其职:
- 扩展(展开) :将数组、对象、可迭代数据结构拆解为独立单个元素,多用于数据拷贝、合并、传参
- 剩余(收纳) :自动收集剩余零散元素,打包封装为数组/对象,多用于解构赋值取值
高频适用场景:数组处理、对象合并、函数批量传参、解构赋值、数据浅拷贝、去重、参数整合等。
二、数组场景九大实战用法(最全可运行示例)
1. 展开数组,拆分独立元素
可将完整数组一键拆解为零散独立元素,常用于快速打印输出、函数批量传参场景,精简循环代码。
javascript
let iArray = ['1', '2', '3']
console.log(...iArray) // 输出:1 2 3
2. 数组头部/尾部追加元素
通过展开原数组,快速在头部或尾部拼接新元素,生成全新数组,不修改原数组数据,符合不可变数据开发规范。
css
let iArray = ['1', '2', '3']
const newArr = ['0', ...iArray, '4']
console.log(newArr) // 输出:["0", "1", "2", "3", "4"]
3. 结合解构赋值:截取元素、剩余收纳
硬性语法规则 :扩展运算符用于数组解构赋值时,只能放置在解构表达式最后一位,置于开头或中间会直接抛出语法错误。
scss
// 示例1:截取首位元素,剩余所有元素统一收纳
const [first, ...rest] = [1, 2, 3, 4, 5]
console.log(first) // 输出:1
console.log(rest) // 输出:[2, 3, 4, 5]
// 示例2:数组元素数量不足时,剩余参数默认返回空数组
const [one, ...last] = ["foo"]
console.log(one) // 输出:foo
console.log(last) // 输出:[]
4. 数组合并(推荐优雅写法)
可替代传统 push、concat 方法,写法简洁优雅,不会污染原数组,是项目中数组合并的最优写法。
scss
var arr1 = [0, 1, 2]
var arr2 = [3, 4, 5]
// 写法1:push合并(会修改原数组,存在副作用,不推荐)
arr1.push(...arr2)
console.log(arr1) // 输出:[0, 1, 2, 3, 4, 5]
// 写法2:扩展运算符合并(推荐,生成全新数组,无副作用)
const mergeArr = [...arr1, ...arr2]
console.log(mergeArr) // 输出:[0, 1, 2, 3, 4, 5]
5. 字符串快速转数组
相较于 split 方法,扩展运算符可更简洁、高效地将完整字符串拆解为单个字符数组,无多余语法冗余。
bash
let iString = 'zhongguoren'
console.log([...iString])
// 输出:["z", "h", "o", "n", "g", "g", "u", "o", "r", "e", "n"]
6. 遍历 Map/Set 可迭代对象
支持所有实现 Iterator 迭代接口的数据结构,可快速将 Map、Set 转换为普通数组,简化数据处理逻辑。
javascript
let map = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
])
// 快速提取 Map 所有 key 并转为数组
let arr = [...map.keys()]
console.log(arr) // 输出:[1, 2, 3]
7. 函数数组传参(批量传参)
可将数组批量拆解为函数的多个独立参数,无需手动遍历取值传参,大幅简化代码。
javascript
methods: {
test() {
let iArray = ['1', '2', '3']
// 数组展开,批量向函数传参
this.hanshu(...iArray)
},
// 剩余参数收纳所有传入的参数
hanshu(...args) {
console.log(...args) // 输出:1 2 3
}
}
8. 快速求取数组最大值/最小值
结合 Math 内置方法,无需循环遍历,一行代码即可获取数组极值,极简高效。
javascript
let iArray = [1, 2, 3, 99, 44, 66, 21, 85, 77]
let maxNum = Math.max(...iArray)
console.log(maxNum) // 输出:99
9. 数组浅拷贝
通过展开原数组生成新数组,实现数组浅拷贝,新数组与原数组内存地址独立,修改新数据不会影响原数据。
ini
const oldArr = [1, 2, 3]
const newArr = [...oldArr]
newArr[0] = 99
console.log(oldArr) // [1,2,3] 原数组数据不变
三、对象场景四大实战用法(Vue 开发高频)
1. 合并对象、新增属性
展开原有对象,搭配新属性快速实现对象合并与属性新增,生成全新对象,不改动原始数据源。
bash
let a = {age: 18, id: 10}
let c = {name: 'zh', ...a}
console.log(c)
// 输出:{name: "zh", age: 18, id: 10}
2. 覆盖/修改对象原有属性
后置覆盖核心原则 :对象扩展合并时,若存在同名属性,后置属性会覆盖前置同名属性,可用于快速更新对象字段。
bash
let a = {name: 'zh', age: 18, id: 10}
// 展开原对象,覆盖原有 name 属性
let c = {...a, name: 'zh1'}
console.log(c)
// 输出:{name: "zh1", age: 18, id: 10}
3. 对象解构:剔除属性、保留剩余属性
结合解构赋值,可精准提取、剔除对象指定字段,剩余所有属性自动收纳为新对象,是数据过滤的常用优雅写法。
javascript
let a = {name: 'zh', age: 18, id: 10}
// 单独提取 name 属性,剩余字段统一收纳到 c 对象
let {name, ...c} = a
console.log(name, c)
// 输出:zh {age: 18, id: 10}
4. 对象浅拷贝
Vue 开发核心常用写法,用于浅拷贝对象数据,避免直接修改原响应式数据产生的副作用,保证数据稳定性。
javascript
let obj1 = {
name: 'zh',
age: '20'
}
let obj2 = { ...obj1 }
obj2.name = 'li'
// 新旧对象相互独立,互不影响
console.log('obj1', obj1) // {name: 'zh', age: '20'}
console.log('obj2', obj2) // {name: 'li', age: '20'}
四、核心避坑注意事项(必看)
- 解构位置限制 :数组、对象解构赋值中,
...剩余参数语法必须置于表达式最后一位,放置任意前置位置都会直接报语法错误。 - 浅拷贝层级限制 :扩展运算符仅支持单层数据浅拷贝,仅顶层数据独立,多层嵌套的对象、数组无法实现深拷贝,修改嵌套数据仍会影响原数据。
- 数据迭代限制 :该语法仅支持拥有 Iterator 迭代接口的数据类型,包含数组、字符串、Map、Set;普通对象无迭代器,早期浏览器不支持展开,现代浏览器已兼容对象展开语法。
- 属性覆盖规则 :多个对象合并时遵循后置优先原则,后方同名属性会直接覆盖前方属性,可用于更新字段,也需避免属性意外覆盖问题。
五、核心总结
- 扩展展开(...数据) :将整体数据拆解为零散元素,核心用于数据拷贝、对象数组合并、函数批量传参。
- 剩余收纳(...变量) :收集剩余零散元素并打包,核心用于解构赋值、批量收纳参数。
- 在 Vue 项目中,该语法是数据拷贝、参数合并、解构取值、精简代码的核心写法,熟练使用可大幅简化冗余代码、提升代码优雅度。