vue3 watch中赋值的ref数组数据不是响应式?

export function useRoomUsers(roomId) {
    let executorList = ref([])
    RoomApi.findRoomUsers({roomId}).then(res => {
        executorList.value = res.data;
    })
    return { executorList }
}
// const { executorList } = useRoomUsers(11)
        // console.log('executorList', executorList)
        let executorList = ref([])
        watch(() => searchForm.roomId, (val) => {
            if (val) {
                executorList.value = useRoomUsers(val).executorList
                console.log('executorList', executorList)
            }
        })
        return { executorList }

useRoomUsers是一个异步获取数据方法返回ref对象,用解构方式获取的数据是可以正常响应的。
但业务需要放在watch当中就不行了。试过把返回的地方改成reactive 直接这边数组都是空的,理解不了,求大神指点。

就很奇怪获取value是空的,但打印出来数组是有数据的

阅读 4.1k
3 个回答
✓ 已被采纳新手上路,请多包涵
export function useRoomUsers(roomId) {
    let executorList = ref([])
    function doFetch() {
        executorList.value = []
        if (unref(roomId)) {
            RoomApi.findRoomUsers({roomId: unref(roomId)}).then(res => {
                executorList.value = res.data;
            })
        }
    }
    if (isRef(roomId)) {
        // 若输入的 URL 是一个 ref,那么启动一个响应式的请求
        watchEffect(doFetch)
      } else {
        // 否则只请求一次
        doFetch()
      }
    return { executorList }
}
const roomId = computed(() => { 
    return searchForm.value.roomId
})
const { executorList } = useRoomUsers(roomId)

改成这样可以了,之前直接用的searchForm.value.roomId不会触发watchEffect,后面的判断也得用unref解包。说实话还是疑惑除了解构方式 直接value赋值为啥不行。

// 这行代码后 executorList.value 的值其实又包裹了一层代理,你在template上面也不可能用`executorList.value`进行访问
executorList.value = useRoomUsers(val).executorList

还不如改成直接返回Promise的值

export function useRoomUsers(roomId) {
    return RoomApi.findRoomUsers({roomId}).then(res => {
       return res.data;
    })
}
// 但是放在`watch`中异步可能出现返回数据时机不正确
useRoomUsers(val).then(data => {
    executorList.value = data
})
 

或许题主对于composition api的理解有些偏差!
可以这样写

export function useRoomUsers(roomId) {
    let executorList = ref([])
    

    // 或者使用watchEffect
    watch(roomId, (val) => {
        if (val) {
            RoomApi.findRoomUsers({roomId}).then(res => {
                executorList.value = res.data;
            })
        }
     },{immediate: true})
    
    return { executorList }
}


// 在组件中直接
const roomId = ref(1)
// 这里的executorList是响应式的,你可以直接用它
const { executorList } = useRoomUsers(roomId)

还有题主可能是对promise也不是很熟悉,建议抽时间再好好看看

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题