在 Vue 3 中,由于其响应式系统的特性(基于 reactive
和 ref
),修改数组的方式需要确保能够触发视图更新。以下是几种常见的修改数组的方法及其注意事项:
1. 使用响应式 API 修改数组
Vue 3 的 reactive
和 ref
是构建响应式数据的基础。修改数组时,直接操作这些响应式对象通常就能触发更新。
示例:使用 reactive
import { reactive } from 'vue';
export default {
setup() {
const state = reactive({
list: [1, 2, 3]
});
// 修改数组的几种方式
const pushItem = () => {
state.list.push(4); // 添加元素
};
const removeItem = () => {
state.list.pop(); // 删除末尾元素
};
const updateItem = () => {
state.list[0] = 10; // 修改指定索引元素
};
return { state, pushItem, removeItem, updateItem };
}
};
示例:使用 ref
import { ref } from 'vue';
export default {
setup() {
const list = ref([1, 2, 3]);
const pushItem = () => {
list.value.push(4); // 通过 .value 修改
};
const removeItem = () => {
list.value.pop();
};
const updateItem = () => {
list.value[0] = 10;
};
return { list, pushItem, removeItem, updateItem };
}
};
注意:
- 使用
ref
时,需通过.value
访问数组。 - 使用
reactive
时,直接操作对象属性即可。
2. 使用数组的原生方法
Vue 3 的响应式系统能够自动侦测数组的常见变更方法(例如 push
、pop
、shift
、unshift
、splice
等),这些方法会触发视图更新。
支持响应式更新的数组方法:
push()
:添加元素到末尾pop()
:删除末尾元素shift()
:删除开头元素unshift()
:添加元素到开头splice()
:删除、插入或替换元素sort()
:排序reverse()
:反转
示例:
import { reactive } from 'vue';
export default {
setup() {
const list = reactive([1, 2, 3]);
const addItem = () => {
list.push(4); // 会触发更新
};
const replaceItem = () => {
list.splice(1, 1, 10); // 将索引 1 的元素替换为 10
};
return { list, addItem, replaceItem };
}
};
3. 直接赋值新数组
如果需要完全替换数组,可以直接赋值一个新数组。Vue 3 的响应式系统会检测到整个数组的替换并更新视图。
示例:
import { ref } from 'vue';
export default {
setup() {
const list = ref([1, 2, 3]);
const replaceArray = () => {
list.value = [4, 5, 6]; // 替换整个数组
};
return { list, replaceArray };
}
};
4. 注意事项:非响应式情况
某些操作不会触发响应式更新,需要特别处理:
- 直接通过索引赋值新对象:如果数组中的元素是对象,直接修改对象的属性是响应式的,但替换整个对象需要特殊处理。
- 长度修改:直接设置
length
属性不会触发更新。
示例:非响应式修改问题
import { reactive } from 'vue';
export default {
setup() {
const state = reactive({
list: [{ id: 1 }, { id: 2 }]
});
const wrongWay = () => {
state.list[0] = { id: 3 }; // 不会触发更新
};
const rightWay = () => {
state.list.splice(0, 1, { id: 3 }); // 使用 splice 触发更新
};
return { state, wrongWay, rightWay };
}
};
解决方法:
- 使用
splice
替换元素。 - 如果需要修改对象属性,可以直接操作属性(如
state.list[0].id = 3
),因为对象的属性是响应式的。
5. 使用组合式 API 监听数组变化
如果需要在数组修改后执行特定逻辑,可以结合 watch
监听数组。
示例:
import { reactive, watch } from 'vue';
export default {
setup() {
const state = reactive({
list: [1, 2, 3]
});
watch(() => [...state.list], (newList, oldList) => {
console.log('数组变化:', newList, oldList);
});
const addItem = () => {
state.list.push(4);
};
return { state, addItem };
}
};
注意:
watch
需要深拷贝数组(如[...state.list]
),否则可能只监听引用而非内容变化。
总结
在 Vue 3 中修改数组的推荐方式:
- 使用
reactive
或ref
创建响应式数组。 - 优先使用支持响应式的数组方法(如
push
、splice
等)。 - 对于整体替换,直接赋值新数组。
- 避免非响应式操作(如直接通过索引替换对象),必要时使用
splice
。