I. Create a sub-branch of Rights and push it to the cloud

  • 1. Git branch: View the current branch
  • Git checkout -b rights
  • 3.git branch
  • Git push -u origin rights

2. Display the permission list component through routing

Create the power folder under components with the rights. vue component

<template>
  <div>
    <h1>User permission list component</h1>
  </div>
</template>
<script>
export default {
  data: () = >({})}</script>
<style lang="less" scoped>
</style>

Copy the code

2. Configure routes

import Rights from '.. /components/power/Rights.vue'

// The permissions list is in the home component

  {
    path: '/home'.component: Home,
    redirect: '/welcome'.children: [{path: '/welcome'.component: Welcome
      },
      {
        path: '/users'.component: Users
      },
      {
        path: '/rights'.component: Rights
      }
    ]
  }
Copy the code

Draw breadcrumb navigation and card view

<template>
  <div>
    <! Breadcrumb navigation area -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">Home page</el-breadcrumb-item>
      <el-breadcrumb-item>Rights management</el-breadcrumb-item>
      <el-breadcrumb-item>Permissions list</el-breadcrumb-item>
    </el-breadcrumb>
    <! -- Card View area -->
    <el-card>111</el-card>
  </div>
</template>
<script>
export default {
  data: () = >({})}</script>
<style lang="less" scoped>
</style>

Copy the code

4. Call THE API to obtain the data of the permission list

  data: () = > ({
    // Get all permissions
    rightsList: []}),created() {
    this.getRightsList()
  },
  methods: {
    // Get permission list
    async getRightsList() {
      const { data: res } = await this.$http.get('rights/list')
      if(res.meta.status ! = =200) return this.$message.error('Failed to get permission list! ')
      this.rightsList = res.data
      console.log(this.rightsList)
    }
  }
Copy the code

5. Render permission list

<! -- Card View area --><el-card>
      <el-table :data="rightsList" border stripe>
        <el-table-column type="index"></el-table-column>
        <el-table-column label="Permission Name" prop="authName"></el-table-column>
        <el-table-column label="Path" prop="path"></el-table-column>
        <el-table-column label="Permission level" prop="level">
          <template slot-scope="scope">
            <el-tag v-if="scope.row.level === '0'">Level 1</el-tag>
            <el-tag type="success" v-else-if="scope.row.level === '1'">The secondary</el-tag>
            <el-tag type="warning" v-else>Level 3</el-tag>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
Copy the code
  • The stripe is interlaced with color

6. The relationship between user – role – permission

  • Users are divided into A and B, and their permissions are different. For example, some users have the permission to modify but not delete, and some users have the permission to delete but not modify

7. Display the role list component through routing

1. Create roles. vue under power

<template>
  <div><h1>Role list component</h1></div>
</template>
<script>
export default {
  data: () = >({})}</script>
<style lang="less" scoped>
</style>

Copy the code

2. Configure routes

import Roles from '.. /components/power/Roles.vue'




  {
    path: '/home'.component: Home,
    redirect: '/welcome'.children: [{path: '/welcome'.component: Welcome
      },
      {
        path: '/users'.component: Users
      },
      {
        path: '/rights'.component: Rights
      },
      {
        path: '/roles'.component: Roles
      }
    ]
  }
Copy the code

8. Draw the basic layout structure of the role list and obtain the data of the role list (the same as the user list page)

<template>
  <div>
    <! Breadcrumb navigation area -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">Home page</el-breadcrumb-item>
      <el-breadcrumb-item>Role management</el-breadcrumb-item>
      <el-breadcrumb-item>The role list</el-breadcrumb-item>
    </el-breadcrumb>
    <! -- Card View area -->
    <el-card>
      <! Add role button area -->
      <el-row>
        <el-col>
          <el-button type="primary">Adding roles</el-button>
        </el-col>
      </el-row>
      <! -- Role list area -->
      <el-row>
        <el-table></el-table>
      </el-row>
    </el-card>
  </div>
</template>
<script>
export default {
  data: () = > ({
    // All role list data
    rolesList: []}),created() {
    this.getRolesList()
  },
  methods: {
  // Get user list data
    async getRolesList() {
      const { data: res } = await this.$http.get('roles')
      if(res.meta.status ! = =200) {
        return this.$message.error('Failed to get role list! ')}this.rolesList = res.data
      console.log(this.rolesList)
    }
  }
}
</script>
<style lang="less" scoped>
</style>

Copy the code

Render character list data

<! -- Role list area --><el-table :data="rolesList" border stripe>
          <! -- Expand column -->
          <el-table-column type="expand"></el-table-column>
          <! -- index column -->
          <el-table-column type="index"></el-table-column>
          <el-table-column label="Role Name" prop="roleName"></el-table-column>
          <el-table-column label="Role Description" prop="roleDesc"></el-table-column>
          <el-table-column label="Operation" width="300px">
            <template>
              <el-button size="mini" type="primary" icon="el-icon-edit">The editor</el-button>
              <el-button size="mini" type="danger" icon="el-icon-delete">delete</el-button>
              <el-button size="mini" type="warning" icon="el-icon-setting">Assign permissions</el-button>
            </template>
          </el-table-column>
        </el-table>
Copy the code

X. Rendering permissions

  • Get permission data for each row,
    
    

    Labels can make data formatted and beautiful, but permissions are hierarchical and need to be subdivided.

<! -- Expand column --><el-table-column type="expand">
          <template slot-scope="scope">
            <pre>
                {{ scope.row }}
              </pre>
          </template>
        </el-table-column>
Copy the code

1. Render level 1 permissions through the first level for loop

<! -- Expand column --><el-table-column type="expand">
          <template slot-scope="scope">
            <el-row v-for="(item1) in scope.row.children" :key="item1.id">
              <! Render level permissions -->
              <el-col :span="5">
                <el-tag>
                  {{ item1.authName }}
                </el-tag>
              </el-col>
              <! Render level 2 and Level 3 permissions -->
              <el-col :span="19"></el-col>
            </el-row>
            <pre>
                {{ scope.row }}
              </pre
            >
          </template>
        </el-table-column>
Copy the code

2. Layer 2 for loop, layer 3 for loop render level 2, level 3 permissions

<! Render level 2 and Level 3 permissions --><el-col :span="19">
                <! Nested render level 2 through the for loop -->
                <el-row
                  :class="[i2 === 0 ? '' : 'rolesTop','vcenter']"
                  v-for="(item2, i2) in item1.children"
                  :key="item2.id"
                >
                  <el-col :span="6">
                    <el-tag type="success">{{ item2.authName }}</el-tag>
                    <i class="el-icon-caret-right"></i>
                  </el-col>
                  <el-col :span="18">
                    <el-tag type="warning" v-for="item3 in item2.children" :key="item3.id">{{
                      item3.authName
                    }}</el-tag>
                  </el-col>
                </el-row>
              </el-col>
Copy the code

Complete the function of deleting specified permissions of roles based on their IDS

1. Add the Closable attribute to the EL-Tag component (display an x)

2. Add a close event to the el-Tag component (close: the event triggered when closing the tag)

<! <el-table-column type="expand"> <template slot-scope="scope"> <el-row :class="['rolesBottom', i1 === 0 ? 'rolesTop' : '', 'vcenter']" v-for="(item1, i1) in scope.row.children" :key="item1.id" > <! <el-col :span="5"> <el-tag closable @close="removeRightById(scope.row, item1.id)"> {{ item1.authName }} </el-tag> <i class="el-icon-caret-right"></i> </el-col> <! <el-col :span="19"> <! -- rendering by nested for loop secondary permissions - > < el - row: class = "[i2 = = = 0? ' ': 'rolesTop', 'vcenter']" v-for="(item2, i2) in item1.children" :key="item2.id" > <el-col :span="6"> <el-tag type="success" closable @close="removeRightById(scope.row, item2.id)" >{{ item2.authName }}</el-tag > <i class="el-icon-caret-right"></i> </el-col> <el-col :span="18"> <el-tag type="warning" v-for="item3 in item2.children" :key="item3.id" closable @close="removeRightById(scope.row, item3.id)" >{{ item3.authName }}</el-tag > </el-col> </el-row> </el-col> </el-row> <! -- <pre> {{ scope.row }} </pre> --> </template> </el-table-column>Copy the code
// Delete permissions based on id
    async removeRightById(role, rightId) {
      const confirmResult = await this.$confirm('This operation will permanently delete the file. Do you want to continue? '.'tip', {
        confirmButtonText: 'sure'.cancelButtonText: 'cancel'.type: 'warning'
      }).catch(err= > err)
      if(confirmResult ! = ='confirm') {
        return this.$message.info('Cancelled delete! ')}const { data: res } = await this.$http.delete(`roles/${role.id}/rights/${rightId}`)
      if(res.meta.status ! = =200) {
        return this.$message.error('Delete permission failed')
      }
      role.children = res.data
    }
Copy the code

Xii. The dialog box for assigning permissions is displayed, and the dialog box data is obtained

<el-button
              size="mini"
              type="warning"
              icon="el-icon-setting"
              @click="showSetRightDialog"</el-button > <! Assign Permissions dialog box --><el-dialog title="Assign permissions" :visible.sync="showSetRightDialogVisible">
      <el-table>
        <el-table-column
          property="date"
          label="Date"
          width="150"
        ></el-table-column>
        <el-table-column
          property="name"
          label="Name"
          width="200"
        ></el-table-column>
        <el-table-column property="address" label="Address"></el-table-column>
      </el-table>
    </el-dialog>
Copy the code
data: () = > ({
    // All role list data
    rolesList: [].// Assign permission dialog box properties
    showSetRightDialogVisible: false.// Data with all permissions
    rightsList: []}),// Assign permissions
    async showSetRightDialog() {
      const { data: res } = await this.$http.get('rights/tree')
      if(res.meta.status ! = =200) {
        return this.$message.error('Failed to get permission list tree! ')}this.rightsList = res.data
      console.log(this.rightsList)
      this.showSetRightDialogVisible = true
    }
Copy the code

13, the initial configuration and use of el-tree tree control

1. Introduce tree controls

<! Assign Permissions dialog box --><el-dialog title="Assign permissions" :visible.sync="showSetRightDialogVisible">
      <! -- Tree control -->
      <el-tree
        :data="rightsList"
        :props="treeProps"
      ></el-tree>
    </el-dialog>
Copy the code

2. Bind the data attribute in the el-tree to the permission data, and the props attribute defines the binding object in the data

data: () = > ({
    // All role list data
    rolesList: [].// Assign permission dialog box properties
    showSetRightDialogVisible: false.// Data with all permissions
    rightsList: [].// The tree control's property binding object
    treeProps: {
      label: 'authName'.children: 'children'}}),Copy the code

3. Optimize the display effect of the tree control

  • Show-checkbox: indicates the checkbox
  • Node-key =”id” : the attribute used by each tree node as a unique identifier. The entire tree should be unique
  • Default-expand-all: specifies whether to expand all nodes by default
<el-tree
        :data="rightsList"
        :props="treeProps"
        show-checkbox
        node-key="id"
        default-expand-all
      ></el-tree>
Copy the code

Load the permissions of the current role

1. Add default-checked-keys to el-tree

<el-tree
        :data="rightsList"
        :props="treeProps"
        show-checkbox
        node-key="id"
        default-expand-all
        default-checked-keys="defkeys"
      ></el-tree>
Copy the code
  data: () = > ({
    // All role list data
    rolesList: [].// Assign permission dialog box properties
    showSetRightDialogVisible: false.// Data with all permissions
    rightsList: [].// The tree control's property binding object
    treeProps: {
      label: 'authName'.children: 'children'
    },
    // An array of node IDS selected by default
    defkeys: []}),Copy the code

2. Obtain the IDS of all level 3 permissions of the role recursively and save them in the defKeys array

    // Assign permissions
    async showSetRightDialog(role) {
      const { data: res } = await this.$http.get('rights/tree')
      if(res.meta.status ! = =200) {
        return this.$message.error('Failed to get permission list tree! ')}this.rightsList = res.data
      // console.log(this.rightsList)
      // Recursively obtain the id of the level-3 node
      this.getLeafKeys(role, this.defkeys)
      this.showSetRightDialogVisible = true
    },




 // Get the ids of all level 3 privileges for the role recursively and save them in the defkeys array
    getLeafKeys(node, arr) {
      // If the current node does not contain the children attribute, it has the third level permission
      if(! node.children) {return arr.push(node.id)
      }
      // If not level 3, go to children
      node.children.forEach(item= > {
        this.getLeafKeys(item, arr)
      })
    },
Copy the code

Reset the defKeys array when closing the permissions dialog box, so that the following dialog box does not have the selected content of the previous dialog box

1. Add a close event to the dialog box

<! Assign Permissions dialog box --><el-dialog
      title="Assign permissions"
      :visible.sync="showSetRightDialogVisible"
      width="50%"
      @close="setRightDialogClose"
    >
Copy the code

2. Implement the shutdown event

    // Listen for the close event of the Assign Permissions dialog box
    setRightDialogClose() {
      this.defkeys = []
    }
Copy the code

16. Call API to complete the function of assigning permissions

1. Save the role ID in data when you click the Assign Permission button for later use

  data: () = > ({
    // All role list data
    rolesList: [].// Assign permission dialog box properties
    showSetRightDialogVisible: false.// Data with all permissions
    rightsList: [].// The tree control's property binding object
    treeProps: {
      label: 'authName'.children: 'children'
    },
    // An array of node IDS selected by default
    defkeys: [].// Click the Assign Permission button to obtain the role ID value
    roleId: ' '
  }),
Copy the code
// Assign permissions
    async showSetRightDialog(role) {
      / / character id
      this.roleId = role.id
      const { data: res } = await this.$http.get('rights/tree')
      if(res.meta.status ! = =200) {
        return this.$message.error('Failed to get permission list tree! ')}this.rightsList = res.data
      // console.log(this.rightsList)
      // Recursively obtain the id of the level-3 node
      this.getLeafKeys(role, this.defkeys)
      this.showSetRightDialogVisible = true
    },
Copy the code

2. When clicking the “OK” button, obtain the ID values of the half-selected and all-selected states in the whole tree structure, and merge them into a complete array

  • GetCheckedKeys: Returns the array of keys of the currently selected node if the node is selectable (that is, show-checkbox is true)
  • GetHalfCheckedKeys: If the node is selectable (that is, show-checkbox is true), returns an array of the keys of the currently half-selected node
  • 1. Add the click event to the OK button and the ref to the EL-tree component
<! Assign Permissions dialog box --><el-dialog
      title="Assign permissions"
      :visible.sync="showSetRightDialogVisible"
      width="50%"
      @close="setRightDialogClose"
    >
      <! -- Tree control -->
      <el-tree
        :data="rightsList"
        :props="treeProps"
        show-checkbox
        node-key="id"
        default-expand-all
        :default-checked-keys="defkeys"
        ref="treeRef"
      ></el-tree>
      <span slot="footer" class="dialog-footer">
        <el-button @click="showSetRightDialogVisible = false">Take away</el-button>
        <el-button type="primary" @click="allotRights">determine</el-button>
      </span>
    </el-dialog>
Copy the code
    1. Define permission assignment methods
    // Click assign permissions to roles
    async allotRights() {
    // Get full and half-selected ids
      const keys = [
        ...this.$refs.treeRef.getCheckedKeys(),
        ...this.$refs.treeRef.getHalfCheckedKeys()
      ]
    }
Copy the code

3. Concatenate the arrays using commas (,)

// Click assign permissions to roles
    async allotRights() {
      // Get full and half-selected ids
      const keys = [
        ...this.$refs.treeRef.getCheckedKeys(),
        ...this.$refs.treeRef.getHalfCheckedKeys()
      ]

      const idStr = keys.join(', ')}Copy the code

4. Initiate a request and send the role ID saved in 1 and the new string concatenated to the server

    // Click assign permissions to roles
    async allotRights() {
      // Get full and half-selected ids
      const keys = [
        ...this.$refs.treeRef.getCheckedKeys(),
        ...this.$refs.treeRef.getHalfCheckedKeys()
      ]

      // Concatenate the array with a comma
      const idStr = keys.join(', ')
    // Initiate a request
      const { data: res } = await this.$http.post(`roles/The ${this.roleId}/rights`, { rids: idStr })
      console.log(res)
      if(res.meta.status ! = =200) {
        return this.$message.error('Permission assignment failed! ')}this.$message.success('Permission assigned successfully! ')}Copy the code

5. Refresh the role list

    // Click assign permissions to roles
    async allotRights() {
      // Get full and half-selected ids
      const keys = [
        ...this.$refs.treeRef.getCheckedKeys(),
        ...this.$refs.treeRef.getHalfCheckedKeys()
      ]

      // Concatenate the array with a comma
      const idStr = keys.join(', ')
    // Initiate a request
      const { data: res } = await this.$http.post(`roles/The ${this.roleId}/rights`, { rids: idStr })
      console.log(res)
      if(res.meta.status ! = =200) {
        return this.$message.error('Permission assignment failed! ')}this.$message.success('Permission assigned successfully! ')
      // Refresh the role list
      this.getRolesList()
    }
Copy the code

6. Close the dialog box

    // Click assign permissions to roles
    async allotRights() {
      // Get full and half-selected ids
      const keys = [
        ...this.$refs.treeRef.getCheckedKeys(),
        ...this.$refs.treeRef.getHalfCheckedKeys()
      ]

      // Concatenate the array with a comma
      const idStr = keys.join(', ')
    // Initiate a request
      const { data: res } = await this.$http.post(`roles/The ${this.roleId}/rights`, { rids: idStr })
      console.log(res)
      if(res.meta.status ! = =200) {
        return this.$message.error('Permission assignment failed! ')}this.$message.success('Permission assigned successfully! ')
      // Refresh the role list
      this.getRolesList()
      // Close the dialog box
      this.showSetRightDialogVisible = false
    }
Copy the code

Complete the role assignment for the user (written in the implementation notes of the user list, but the actual code is in the rights branch, which is not described here)

18. Submit code

    1. View the current branch git Branch
    1. Git status
    1. git add .
    1. Git commit -m
    1. git status
    1. Git push commits the rights branch
    1. git checkout master
    1. Git merge Rights merges the rights branch in the master branch
    1. Git push updates the main branch