使用reactive包裹数组正确赋值
需求:将接口请求到的列表数据赋值给响应数据arr
- const arr = reactive([]);
-
- const load = () => {
- const res = [2, 3, 4, 5]; //假设请求接口返回的数据
- // 方法1 失败,直接赋值丢失了响应性
- // arr = res;
- // 方法2 这样也是失败
- // arr.concat(res);
- // 方法3 可以,但是很麻烦
- res.forEach(e => {
- arr.push(e);
- });
- };
vue3使用proxy
,对于对象和数组都不能直接整个赋值。
使用方法1能理解,直接赋值给用reactive
包裹的对象也不能这么做。
方法2为什么不行?
只有push或者根据索引遍历赋值才可以保留reactive数组的响应性?
如何方便的将整个数组拼接到响应式数据上?
提供几种办法
- const state = reactive({
- arr: []
- });
-
- state.arr = [1, 2, 3]
或者
- const state = ref([])
-
- state.value = [1, 2, 3]
或者
- const arr = reactive([])
-
- arr.push(...[1, 2, 3])
这几种办法都可以触发响应性,推荐第一种
vue3的reactive重新赋值无效
vue3官方的文档说明
reactive() 返回一个对象的响应式代理
所以 reactive 方法应该作用于一个对象Object,如果要使用数组,则需要包装一下:
- let list = reactive({
- ?? ?data: [{id: 01, name: 'XXX'}]
- })
或者使用 ref:
- let list = ref([{id: 1, name: 'Andy'}])
已下引用原作者的代码:
- import { reactive, ref } from 'vue'
- export default {
- ? setup() {
- ? ? // 需要一个带默认值的数组list;
- ? ?? ?let list = reactive([{id: 1, name: 'Andy'}])
- ? ??
- ? ? // 每次触发事件重置list,把新值放入,此种方式不会触发视图更新
- ? ? const checkBtn = () => {
- ? ? ? // 此时重置操作 地址指向变成一个新的地址,不会触发视图更新
- ? ? ? list = [{id: 1, name: 'Andy'}]
- ? ? ? list.push({id: 2, name: 'Lucy'})
- ? ? }
- ? ??
- ? ? // --------------------------------------------------
- ? ? // 正确的重置处理方法如下:使用reactive将数组包裹到一个对象中
- ? ? let list = reactive({
- ? ? ? data: [{id: 1, name: 'Andy'}]
- ? ? });
- ? ? const checkBtn = () => {
- ? ? ? list.data = [{id: 1, name: 'Andy'}]
- ? ? ? list.data.push({id: 2, name: 'Lucy'})
- ? ? }
- ? ? // 或者使用ref
- ? ? let list = ref([{id: 1, name: 'Andy'}]);
- ? ? const checkBtn = () => {
- ? ? ? list.value = [{id: 1, name: 'Andy'}]
- ? ? ? list.value.push({id: 2, name: 'Lucy'})
- ? ? }
- ? ? return {
- ? ? ? list,
- ? ? ? checkBtn
- ? ? }
- ? },
- }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。