Vue3.5 nextTick() 解决添加数据后,无法通过Ref获取数据
目录
1 问题描述
思路:先 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 })2 问题分析
问题出在 DOM
<el-tree
...
:data="transformPermissionsToTree(permissionsBaseData)"
...
/>首先 permissionsBaseData 数据需要经过 transformPermissionsToTree(permissionsBaseData) 给到 el-tree 树,那么el-tree才可以显示数据。
但是我获取完数据直接就是 permTreeRef.value?.setChecked 设置选中项,但是这个时候DOM还没更新,那么 el-tree 就无法从 transformPermissionsToTree(permissionsBaseData) 获取数据。
DOM 树中还没刷新,也就意味着当前 permTreeRef.value 是空的,那无法选中也合理了。
3 解决办法
3.1 第一种 计算属性
设置个计算属性,这样 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"
/>3.2 第二种 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))
}
})