Vue3 的 reactive 赋值问题

公司新项目是使用 Vue3(3.2.37) 框架,在编程过程中遇见框架问题,在此记录

问题

先说问题:Vue3 中直接对 reactive 变量本身进行赋值是没有效果的

筛选表单重置功能

1
2
3
4
5
// 数据结构
let filterForm = reactive({
createDate: null,
q: null
})

我原本的做法是直接给 filterForm 赋值为原来的状态

1
2
3
4
5
6
function reset() {
filterForm = {
createDate: null,
q: null
}
}

但测试之后,发现没有效果,于是改成了单个数据置空,就生效了

1
2
3
4
function reset() {
filterForm.createDate = null
filterForm.q = null
}

弹窗数据回显

1
2
3
4
5
6
7
8
9
10
11
12
13
const props = defineProps({
visible: {
type: Boolean,
default: false
},
data: {
type: Object,
default: {}
}
})

let visible = ref(false)
let modalData = reactive({})

我是直接监听 visible 变量,如果弹窗显示,就将数据回显

我原本是直接将 props.data 结构赋值给 modalData,结果没有生效,我使用 vue 插件查看,插件显示 modalData 是一个空对象

console.log 打印,发现数据是有值的,我百思不得其解

1
2
3
4
5
6
7
8
9
watch{
() => props.visible,
(newVal) => {
if(newVal) {
modalData = { ...props.data }
}
visible = newVal
}
}

查了一下资料,发现直接给 reactive 变量本身赋值是没有效果的

于是我就给 modalData 又套了一层 data,就生效了

1
2
3
4
5
6
7
8
9
10
11
12
13
let modalData = reactive({
data: {}
})

watch{
() => props.visible,
(newVal) => {
if(newVal) {
modalData.data = { ...props.data }
}
visible = newVal
}
}

解决方案

  1. 单个赋值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    let filterForm = reactive({
    createDate: null
    })

    filterForm.createDate = '2023-7-10'

    function reset() {
    filterForm.createDate = null
    }
  2. 多套一层

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    const props = defineProps({
    data:{
    type: Object,
    default: {}
    }
    })

    const modalData = reactive({
    data:{}
    })

    modalData.data = { ...props.data }

补充

在查阅资料时发现,reactive 赋值的数组同样有问题,如果需要清空数组不能直接赋值一个空数组,而是要将数组长度设置为 0

1
2
3
4
5
6
7
let arr = reactive([])

// 错误写法
arr = []

// 正确写法
arr.length = 0

Vue 真是一个版本一个坑,属于是 $set 的复刻版了