Laravel+Vue.js角色权限项目:全选后Reactive值未更新问题
问题
基于Laravel API后端、Vue.js前端的角色权限管理项目中,添加角色页面点击「全选」复选框后,所有权限复选框视觉上显示已勾选,但inputPermissions.permissions数组未同步填充对应权限数据。
相关代码
JavaScript部分
const permissions = ref([]) const inputPermissions = reactive({ all: false, name: [], permissions:[], }) async function getPermission() { await Axios.get(urlGenerator(PERMISSION)).then(res => { permissions.value = res.data.data }).catch(error => { console.log(error) return error; }) }
HTML部分
<form class="mt-5"> <div class="form-group"> <label for="exampleInputEmail1">Role<span class="text-danger px-1">*</span></label> <input type="text" name="name" v-model="inputPermissions.name" class="form-control" placeholder="Role name" /> <small v-if="error.name" class="form-text font-size-12 text-danger">{{ error.name }}</small> </div> <div class="form-group"> <label for="per">Permission</label> <div class="form-check"> <label class="form-check-label"> <input v-model="inputPermissions.all" type="checkbox" class="form-check-input" /> All </label> </div> <hr /> <div v-for="permission in permissions" :key="permission.id" class="pb-1 form-check"> <label class="form-check-label"> <input type="checkbox" v-model="inputPermissions.permissions" :checked="inputPermissions.all" class="form-check-input" :value="permission.name" /> {{ permission.name }} </label> </div> </div> <button @click.prevent="saveRole" type="submit" class="btn btn-light btn-outline-dark"> Save Role </button> </form>
问题原因
同时使用v-model和:checked指令在权限复选框上导致冲突::checked仅控制复选框视觉选中状态,但不会触发v-model绑定的permissions数组更新;而v-model的自动数据绑定被:checked的手动干预打断,最终数组未同步数据。
解决方案
步骤1:移除权限复选框的:checked属性
删除权限复选框上的:checked="inputPermissions.all",让v-model全权处理数据与选中状态的绑定。
步骤2:监听「全选」状态变化,同步更新权限数组
通过Vue的watch监听inputPermissions.all的变化,当全选状态切换时,手动更新inputPermissions.permissions数组:
修改后的JavaScript代码:
import { ref, reactive, watch } from 'vue' const permissions = ref([]) const inputPermissions = reactive({ all: false, name: [], permissions:[], }) async function getPermission() { try { const res = await Axios.get(urlGenerator(PERMISSION)) permissions.value = res.data.data } catch (error) { console.log(error) } } // 监听全选状态,同步权限数组 watch(() => inputPermissions.all, (isAllSelected) => { if (isAllSelected) { // 全选时,将所有权限name存入数组 inputPermissions.permissions = permissions.value.map(perm => perm.name) } else { // 取消全选时清空数组 inputPermissions.permissions = [] } }) // 可选:监听权限数组变化,同步全选状态(实现双向联动) watch(() => inputPermissions.permissions, (selectedPerms) => { inputPermissions.all = selectedPerms.length === permissions.value.length }, { deep: true })
修改后的HTML代码
<form class="mt-5"> <div class="form-group"> <label for="exampleInputEmail1">Role<span class="text-danger px-1">*</span></label> <input type="text" name="name" v-model="inputPermissions.name" class="form-control" placeholder="Role name" /> <small v-if="error.name" class="form-text font-size-12 text-danger">{{ error.name }}</small> </div> <div class="form-group"> <label for="per">Permission</label> <div class="form-check"> <label class="form-check-label"> <input v-model="inputPermissions.all" type="checkbox" class="form-check-input" /> All </label> </div> <hr /> <div v-for="permission in permissions" :key="permission.id" class="pb-1 form-check"> <label class="form-check-label"> <input type="checkbox" v-model="inputPermissions.permissions" class="form-check-input" :value="permission.name" /> {{ permission.name }} </label> </div> </div> <button @click.prevent="saveRole" type="submit" class="btn btn-light btn-outline-dark"> Save Role </button> </form>
这样修改后,点击「全选」时inputPermissions.permissions会自动填充所有权限名称,取消全选则清空数组;同时手动勾选/取消单个权限时,全选框也会自动同步状态(可选部分),数据与视图完全同步。
内容的提问来源于stack exchange,提问作者Sd Jibon
相关产品推荐
相关产品推荐

