【问题标题】:Bootstrap-Vue: Implementing Role Permissions as Multiple arrays of b-form-checkbox displayed as columns in b-table. Not workingBootstrap-Vue:将角色权限实现为多个 b-form-checkbox 数组,在 b-table 中显示为列。不工作
【发布时间】:2019-05-06 12:57:15
【问题描述】:

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

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

例如:单击“管理员”的“创建用户”将如下所示:

同样,选中任何其他列都会导致该列的所有复选框都被选中。无论哪种情况,清除任何复选框也会清除该列中的所有复选框。

我不确定发生了什么,但请注意,如果我反转表中的 cmets 并使用其他复选框运行,则无论我检查了哪一列,都会检查“Admin”下的所有列盒子。

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

【问题讨论】:

    标签: javascript arrays vue.js vuex bootstrap-vue


    【解决方案1】:

    您需要使用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)
          }
        }
      }
    

    【讨论】:

    • 很遗憾,这不起作用,但感谢您提供帮助。解决方法导致相同的行为。此外,您需要在 @input 之后添加一个 :stop 以停止否则会发生的无限循环...
    • 我最终构建了您答案中的第一句话。我将在下面提供我自己的答案来展示结果。谢谢!!
    【解决方案2】:

    尝试在复选框上设置一个键。

    <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>
    

    【讨论】:

      【解决方案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 文档所指定的,我们必须将 &lt;b-form-checkbox&gt; 包装在 &lt;b-form-checkbox-group&gt; 中,然后使用 v-model 将组与数组链接起来。在玩了一会儿(大约 10 小时)之后,我终于明白了,我只需要将 &lt;b-form-checkbox&gt;value 属性绑定到从 @987654331 获得的 permission.id 变量@ 在上面的行定义中。

      我希望有更多关于为什么或如何起作用的 cmets。我想我很惊讶&lt;b-form-checkbox&gt; 可以看到来自&lt;b-form-checkbox-group&gt; 之外的变量

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

      默认情况下,选中时 value 为 true 并且 未选中时为假。您可以自定义选中和 通过指定 value 和 unchecked-value 来取消选中值 属性。

      v-model 绑定到选中的属性。当你有多个 绑定到单个数据状态变量的复选框,您必须提供 对您的 v-model 的数组引用 []!

      请注意,当 v-model 绑定到多个复选框时(即数组 ref),不使用未检查的值。只有 选中的 chcekboxes 将在 v-model 绑定数组中返回。你 应该为每个复选框的 value 属性提供唯一的值。

      多个复选框和可访问性

      将多个复选框绑定在一起时,应将 name 属性设置为 单独或通过 name > prop of 为组中的所有 s 提供相同的值。这将通知用户 复选框相关的技术。

      每当使用多个复选框时,建议 被放置在一个组件中 将标签与整个复选框组相关联。

      【讨论】:

        猜你喜欢
        • 2018-04-06
        • 1970-01-01
        • 1970-01-01
        • 2021-07-19
        • 2020-12-17
        • 2019-02-14
        • 1970-01-01
        • 2019-01-03
        • 2023-03-08
        相关资源
        最近更新 更多