Bootstrap-Vue: реализация полномочий на роль в виде нескольких массивов b-form-checkbox, отображаемых в виде столбцов в b-таблице. Не работает
Проблема Я пытаюсь создать страницу для управления разрешениями по ролям, как показано на следующем рисунке:
В настоящее время реализовано, щелчок в любом поле приводит к тому, что все поля в этом столбце становятся отмеченными.
Пример: щелчок в "Создать пользователей" в разделе "Администратор" будет выглядеть следующим образом:
Аналогично, проверка в любом из других столбцов приведет к тому, что будут проверены все флажки для этого столбца. В любом случае, снятие любого флажка также снимает все флажки в этом столбце.
Я не уверен, что происходит, но учтите, что если я переверну комментарии в таблице и запустлю другие флажки, поведение будет таким, что все столбцы в разделе "Администратор" проверяются независимо от того, в каком столбце я установил флажок.
Вот соответствующий шаблон HTML и скрипт для компонента, а также соответствующий скрипт из хранилища vuex. Заранее благодарю за любую помощь!!
import {
store
} from "../store/store";
export default {
data() {
return {
items: this.$store.state.permissions,
roles: this.$store.state.roles,
adminRolePermissions: this.$store.state.roles[this.$store.state.roles.map(function(permission) {
return permission.name;
}).indexOf('Admin')].rolePermissions,
salesRolePermissions: this.$store.state.roles[this.$store.state.roles.map(function(permission) {
return permission.name;
}).indexOf('Sales')].rolePermissions,
maintRolePermissions: this.$store.state.roles[this.$store.state.roles.map(function(permission) {
return permission.name;
}).indexOf('Maintenance')].rolePermissions,
accouRolePermissions: this.$store.state.roles[this.$store.state.roles.map(function(permission) {
return permission.name;
}).indexOf('Accounting')].rolePermissions,
fields: [{
key: "name",
label: "Permission",
class: "text-right"
},
{
key: "admin",
label: "Admin",
class: "text-center"
},
{
key: "sales",
label: "Sales",
class: "text-center"
},
{
key: "maint",
label: "Maintenance",
class: "text-center"
},
{
key: "account",
label: "Accounting",
class: "text-center"
},
]
};
},
<b-table responsive :items="items" :fields="fields" head-variant="dark">
<template slot="admin" slot-scope="row">
<b-form-checkbox id="admin" v-model="adminRolePermissions" value="row.item.id"/>
<!-- <b-form-checkbox v-model="adminRolePermissions" v-bind:id="row.item.id"/> -->
</template>
<template slot="sales" slot-scope="row">
<b-form-checkbox id="sales" v-model="salesRolePermissions" value="row.item.id"/>
<!-- <b-form-checkbox v-model="salesRolePermissions" v-bind:id="row.item.id"/> -->
</template>
<template slot="maint" slot-scope="row">
<b-form-checkbox id="maint" v-model="maintRolePermissions" value="row.item.id"/>
<!-- <b-form-checkbox v-model="salesRolePermissions" v-bind:id="row.item.id"/> -->
</template>
<template slot="account" slot-scope="row">
<b-form-checkbox id="accou" v-model="accouRolePermissions" value="row.item.id"/>
<!-- <b-form-checkbox v-model="accouRolePermissions" v-bind:id="row.item.id"/> -->
</template>
</b-table>
В магазине (vuex):
permissions: [{
id: "u1",
name: "View Users",
grouping: "Users"
},
{
id: "u2",
name: "Create Users",
grouping: "Users"
},
{
id: "u3",
name: "Remove Users",
grouping: "Users"
},
{
id: "u4",
name: "Modify Users",
grouping: "Users"
},
{
id: "u5",
name: "Assign Users To Roles",
grouping: "Users"
},
{
id: "r1",
name: "Create Roles",
grouping: "Roles"
},
{
id: "r2",
name: "Modify Roles",
grouping: "Roles"
},
{
id: "a1",
name: "View Assets",
grouping: "Assets"
},
{
id: "a2",
name: "Create Asset",
grouping: "Assets"
},
{
id: "a3",
name: "Update Asset Info",
grouping: "Assets"
},
{
id: "a4",
name: "Locate Assets",
grouping: "Assets"
},
{
id: "a5",
name: "Change Asset Availability",
grouping: "Assets"
},
{
id: "m1",
name: "View Asset Maintenance Records",
grouping: "Maintenance"
},
{
id: "m2",
name: "Change Asset Maintenance Records",
grouping: "Maintenance"
},
{
id: "c1",
name: "View Customer",
grouping: "Customers"
},
{
id: "c2",
name: "Create Customer",
grouping: "Customers"
},
{
id: "c3",
name: "Modify Customer Info",
grouping: "Customers"
},
{
id: "b1",
name: "Create Booking",
grouping: "Booking"
},
{
id: "b2",
name: "Update Booking",
grouping: "Booking"
},
{
id: "b3",
name: "Remove Booking",
grouping: "Booking"
},
{
id: "f1",
name: "View Invoices",
grouping: "Accounting"
},
{
id: "f2",
name: "Create Invoice",
grouping: "Accounting"
},
{
id: "f3",
name: "Update Invoice",
grouping: "Accounting"
},
{
id: "f4",
name: "Pay Invoice",
grouping: "Acounting"
},
{
id: "f5",
name: "Update Customer Status",
grouping: "Accounting"
}
],
roles: [{
name: "Admin",
rolePermissions: ["u1", "u2", "u3", "u4", "u5", "r1", "r2", "a1", "a2", "a3", "a4", "a5", "m1", "m2", "c1", "c2", "c3", "b1", "b2", "b3", "f1", "f2", "f3", "f4", "f5"]
},
{
name: "Sales",
rolePermissions: ["a1", "a2", "a3", "a4", "a5", "c1", "c2", "c3", "b1", "b2", "b3", "m1"]
},
{
name: "Maintenance",
rolePermissions: ["a1", "a5", "m1", "m2"]
},
{
name: "Accounting",
rolePermissions: ["c1", "f1", "f2", "f3", "f4", "f5"]
}
],
3 ответа
Комбинируя предложение ittus относительно b-form-checkbox-group с несколькими попытками и перечитыванием документов bootstrap-vue, я придумываю следующее:
<script>
export default {
data() {
return {
permissions: [{
id: "a1",
name: "View Assets"
},
{
id: "a2",
name: "Add Asset"
},
{
id: "a3",
name: "Modifiy Assets"
}
],
roles: [{
name: "Admin",
permissions: ["a1", "a2", "a3"]
},
{
name: "Sales",
permissions: ["a1"]
},
{
name: "Maintenance",
permissions: ["a1"]
},
{
name: "Accounting",
permissions: ["a1"]
},
]
};
},
};
</script>
<style>
.headerRow {
padding: .75rem;
background-color: #000000;
color: #ffffff;
font-weight: bold;
vertical-align: bottom;
border-bottom: 2px solid #dee2e6;
}
.bodyRow {
padding: .75rem;
border-top: 1px solid #dee2e6;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.js"></script>
<template>
<div>
<b-row>
<b-col>
<b-container>
<div id='permissionsTable'>
<b-row class='headerRow'>
<b-col cols='3'>Permissions</b-col>
<b-col v-for="role in roles" v-bind:key="role.name">{{role.name}}</b-col>
</b-row>
<b-row v-for="permission in permissions" v-bind:key="permission.name" class="bodyRow">
<b-col cols='3'>{{permission.name}}</b-col>
<b-col v-for="(role, index) in roles" v-bind:key="role.name">
<b-form-checkbox-group v-bind:id="role.name" v-bind:name="role.name + 'Permissions'" v-model="roles[index].permissions" >
<b-form-checkbox v-bind:value="permission.id"/>
</b-form-checkbox-group>
</b-col>
</b-row>
</div>
</b-container>
</b-col>
</b-row>
</div>
</template>
Объяснение?
Как указано в документах ittus и bootstrap, мы должны <b-form-checkbox>
в <b-form-checkbox-group>
а затем использовать v-model
связать группу с массивом. Поработав с ним некоторое время (около 10 часов), я наконец-то получил его через свой череп, который мне просто нужно было связать value
атрибут <b-form-checkbox>
к permission.id
переменная, полученная из v-for
в определении строки выше.
Я хотел бы получить дополнительные комментарии о том, почему или как это работает. Я думаю, я удивлен, что <b-form-checkbox>
имеет видимость переменных снаружи <b-form-checkbox-group>
Вот цитата соответствующей документации по начальной загрузке, найденной здесь
Ценности)
По умолчанию значение будет true, если отмечено, и false, если не отмечено. Вы можете настроить отмеченные и непроверенные значения, указав свойства value и unchecked-value.
v-модель привязывается к проверенному свойству. Если у вас есть несколько флажков, которые привязываются к одной переменной состояния данных, вы должны предоставить ссылку на массив [] на вашу v-модель!
Обратите внимание, что когда v-модель привязана к нескольким флажкам (т. Е. Ссылка на массив), непроверенное значение не используется. Только значения проверенных chcekboxes будут возвращены в связанный массив v-модели. Вы должны предоставить уникальные значения для каждого значения флажка prop.
Несколько флажков и доступность
При связывании нескольких флажков вместе вы должны установить одинаковое значение для имени prop для всех элементов в группе по отдельности или через имя> prop of . Это сообщит пользователям вспомогательных технологий, что флажки связаны.
При использовании нескольких флажков рекомендуется поместить их в компонент, чтобы связать метку со всей группой флажков.
Вам нужно использовать b-form-checkbox-group
связать V-модель в виде массива. Я не уверен, как это сделать внутри V-таблицы, но есть обходной путь с methods
<b-form-checkbox id="admin" v-model="adminRolePermissions"
@input="onInputAdminRoles($event, row.item.id)"
:checked="adminRolePermissions.includes(row.item.id)" value="row.item.id"/>
и определенный пользовательский метод:
methods: {
onInputAdminRoles (isCheck, roleId) {
if (isCheck) {
this.adminRolePermissions = this.adminRolePermissions.concat([roleId])
} else {
this.adminRolePermissions = this.adminRolePermissions.filter (item => item !== roleId)
}
}
}
Попробуйте установить ключ на свои флажки.
<b-table responsive :items="items" :fields="fields" head-variant="dark">
<template slot="admin" slot-scope="row">
<b-form-checkbox id="admin" :key="row.index" v-model="adminRolePermissions" value="row.item.id"/>
<!-- <b-form-checkbox v-model="adminRolePermissions" v-bind:id="row.item.id"/> -->
</template>
<template slot="sales" slot-scope="row">
<b-form-checkbox id="sales" :key="row.index" v-model="salesRolePermissions" value="row.item.id"/>
<!-- <b-form-checkbox v-model="salesRolePermissions" v-bind:id="row.item.id"/> -->
</template>
<template slot="maint" slot-scope="row">
<b-form-checkbox id="maint" :key="row.index" v-model="maintRolePermissions" value="row.item.id"/>
<!-- <b-form-checkbox v-model="salesRolePermissions" v-bind:id="row.item.id"/> -->
</template>
<template slot="account" slot-scope="row">
<b-form-checkbox id="accou" :key="row.index" v-model="accouRolePermissions" value="row.item.id"/>
<!-- <b-form-checkbox v-model="accouRolePermissions" v-bind:id="row.item.id"/> -->
</template>
</b-table>