Bootstrap-Vue:将角色权限实现为多个 b-form-checkbox 数组,显示为 b-table 中的列。不工作

Bootstrap-Vue: Implementing Role Permissions as Multiple arrays of b-form-checkbox displayed as columns in b-table. Not working

问题 我正在尝试创建一个页面来按角色管理权限,如下图所示:

按照目前的实施方式,单击任何框都会导致该列中的所有框都被选中。

例如:在 "Admin" 的 "Create Users" 中单击将如下所示:

同样,选中任何其他列都会导致选中该列的所有复选框。在任何一种情况下,清除任何复选框也会清除该列中的所有复选框。

我不确定发生了什么,但请注意,如果我将 table 和 运行 中的注释与其他复选框反转,则行为是 [= 下的所有列52=] 无论我选中了哪一列,都会被选中。

这是组件的相关模板 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"]
    }
  ],

您需要使用b-form-checkbox-group 将v-model 绑定为数组。我不确定如何在 v-table 中执行此操作,但是 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>

将 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 到 link 组数组。在玩了一会儿(大约 10 小时)之后,我终于明白了我只需要将 <b-form-checkbox>value 属性绑定到 permission.id从上面行定义中的 v-for 获得的变量。

我很乐意就为什么或如何 发表任何其他评论。我想我很惊讶 <b-form-checkbox> 可以看到 <b-form-checkbox-group>

之外的变量

这里引用了相关的 bootstrap-vue 文档 here

Value(s)

By default, value will be true when checked and false when unchecked. You can customize the checked and unchecked values by specifying the value and unchecked-value properties.

v-model binds to the checked property. When you have multiple checkboxes that bind to a single data state variable, you must provide an array reference [] to your v-model!

Note that when v-model is bound to multiple checkboxes (i.e an array ref), the unchecked-value is not used. Only the value(s) of the checked chcekboxes will be returned in the v-model bound array. You should provide unique values for each checkbox's value prop.

Multiple checkboxes and accessibility

When binding multiple checkboxes together, you should set the name prop to the same value for all s in the group individually or via the name > prop of . This will inform users of assitive technologies that the checkboxes are related.

Whenever using multple checkboxes, it is recommended that the be placed in a component to associate a label with the entire group of checkboxes.