Vue3.5 nextTick() 解决添加数据后,无法通过Ref获取数据

问题描述

思路:先 getSysPermissionListApi() 通过API获取权限树的模型,然后在通过 getSysRolePermissionApi() 选中当前用户的权限。

问题:打开权限树时,树出来了,但是用户的权限没有被选中

<template>
  <div>
    <p>{{ roleId }}</p>
    <el-tree
      ref="permTreeRef"
      style="max-width: 600px"
      :data="transformPermissionsToTree(permissionsBaseData)"
      node-key="id"
      show-checkbox
      default-expand-all
      v-loading="permissionsTreeLoading"
    />
  </div>
</template>
const initPermissionTree = async () => {
  try {
    permissionsTreeLoading.value = true

    const permList = await getSysPermissionListApi({
      pageNum: 1,
      pageSize: 9999
    })
    permissionsBaseData.value = permList.data

    if (roleId.value) {
      const rolePerms = await getSysRolePermissionApi(roleId.value)
      permissionsUserData.value = rolePerms.data.map((item) => item.permissionId)
      rolePerms.data.forEach((item) => permTreeRef.value?.setChecked(item.permissionId, true, false))
    }
  } catch (err) {
    console.error("Failed to init permission tree:", err)
  } finally {
    permissionsTreeLoading.value = false
  }
}

// // 监听 roleId 变化
watch(() => roleId.value, initPermissionTree, { immediate: true })

问题分析

问题出在 DOM

<el-tree
  ...
  :data="transformPermissionsToTree(permissionsBaseData)"
  ...
/>

首先 permissionsBaseData 数据需要经过 transformPermissionsToTree(permissionsBaseData) 给到 el-tree 树,那么el-tree才可以显示数据。

但是我获取完数据直接就是 permTreeRef.value?.setChecked 设置选中项,但是这个时候DOM还没更新,那么 el-tree 就无法从 transformPermissionsToTree(permissionsBaseData) 获取数据。

DOM 树中还没刷新,也就意味着当前 permTreeRef.value 是空的,那无法选中也合理了。

解决办法

第一种 计算属性

设置个计算属性,这样 Tree 就不再依赖 DOM 更新了,通过计算属性实时更新。

const treeData = computed<Tree[]>(() => {
  return transformPermissionsToTree(permissionsBaseData.value)
})
<el-tree
    ref="permTreeRef"
    style="max-width: 600px"
    :data="treeData"
    node-key="id"
    show-checkbox
    default-expand-all
    v-loading="permissionsTreeLoading"
/>

第二种 nextTick

使用 nextTick 等待 DOM 更新完成后,再运行。

nextTick(async () => {
    if (roleId.value) {
    const rolePerms = await getSysRolePermissionApi(roleId.value)
    permissionsUserData.value = rolePerms.data.map((item) => item.permissionId)
    rolePerms.data.forEach((item) => permTreeRef.value?.setChecked(item.permissionId, true, false))
    }
})
Licensed under CC BY-NC-SA 4.0
本博客已稳定运行
发表了53篇文章 · 总计28.17k字
使用 Hugo 构建
主题 StackJimmy 设计