角色管理

角色管理屬于權(quán)限管理的一個(gè)部分缀壤,可以預(yù)設(shè)一些角色比如課程管理員病袄,廣告管理員,超級(jí)管理員歉甚,普通用戶等等万细,然后在實(shí)際使用時(shí)分配給不同不同的用戶不同的角色,便于操作(不需要給某個(gè)用戶進(jìn)行詳細(xì)的功能設(shè)置)
我們涉及到的功能有:

  • 制作添加角色铃芦,編輯角色雅镊,分配菜單
  • 布局,列表展示刃滓,刪除功能仁烹,分配資源
    基礎(chǔ)準(zhǔn)備工作:

views/role
.
├── components
│ └── list.vue 角色列表組件
└── index.vue 角色組件
角色頁(yè)面初始化代碼:

<template>
  <div class="role">
    <role-list></role-list>
  </div>
</template>

<script>
import RoleList from './components/list'
export default {
  name: 'RoleIndex',
  components: {
    RoleList
  }
}
</script>

<style lang="scss" scoped></style>

角色列表組件初始化代碼(實(shí)現(xiàn)展示和刪除功能)因?yàn)檎故竞蛣h除我們已經(jīng)做了很多次了這里就不再贅述

<template>
  <div class="role-list">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <el-form ref="form" :model="form">
          <el-form-item label="角色名稱">
            <el-input v-model="form.name"></el-input>
          </el-form-item>
        <el-form-item>
            <el-button
            type="primary"
            @click="onSubmit"
            v-loading:="isLoading"
            >查詢</el-button>
            <el-button @click="onReset">重置</el-button>
          </el-form-item>
        </el-form>
      </div>
      <el-button>添加角色</el-button>
      <el-table
      v-loading="isLoading"
      :data="roles"
      style="width: 100%">
      <el-table-column
        prop="id"
        label="編號(hào)"
        >
      </el-table-column>
      <el-table-column
        prop="name"
        label="角色名稱"
        />
      <el-table-column
        prop="description"
        label="描述"
        />
      <el-table-column
        prop="createdTime"
        label="添加時(shí)間"
        >
        <template slot-scope="scope">
              <span>{{ scope.row.createdTime | dateFormat }}</span>
          </template>
      </el-table-column>
      <el-table-column
        align="center"
        label="操作"
        width="150px"
        >
        <template slot-scope="scope">
            <div>
                <el-button
                type="text"
                >分配菜單</el-button>
                <el-button
                type="text"
                >分配資源</el-button>
            </div>
            <div>
                <el-button
                type="text"
                @click="handleEdit(scope.row)"
                >編輯</el-button>
                <el-button
                type="text"
                @click="handleDelete(scope.row)"
                >刪除</el-button>
            </div>
        </template>
        </el-table-column>
    </el-table>
    </el-card>
  </div>
</template>

<script>
// 引入請(qǐng)求方法
import { getRoles, deleteRole } from '@/services/role'
// 因?yàn)椴恢挂粋€(gè)地方使用了fliter時(shí)間日期過(guò)濾器了,所以我們封裝這個(gè)功能咧虎,再?gòu)墓ぞ哳愔幸?import dateFormat from '@/utils/dateformat'
export default {
  name: 'RoleList',
  data () {
    return {
      form: {
        name: ''
      },
      isLoading: false,
      roles: []
    }
  },
  created () {
    this.loadRoles()
  },
  methods: {
    onSubmit () {
    },
    onReset () {
    },
    handleEdit (role) {

    },
    handleDelete (role) {
      // 刪除角色
      this.$confirm(`確認(rèn)刪除角色:${role.name}卓缰?`, '刪除提示')
        .then(async () => {
          await deleteRole(role.id)
          this.$message.success('刪除成功')
          this.loadRoles()
        })
        .catch(err => {
          if (err && err.response) {
            this.$message.error('刪除失敗,請(qǐng)重試')
          } else {
            this.$message.info('取消刪除')
          }
        })
    },
    async loadRoles () {
      this.isLoading = true
      const { data } = await getRoles(this.form)
      this.roles = data.data.records
      this.isLoading = false
    }
  },
  filters: {
    dateFormat
  }
}
</script>

<style lang="scss" scoped>
</style>

創(chuàng)建services/role.js角色接口操作模塊

import request from '@/utils/request'
// 獲取角色
export const getRoles = data => {
  return request({
    method: 'POST',
    url: '/boss/role/getRolePages',
    data
  })
}

// 刪除角色
export const deleteRole = id => {
  return request({
    method: 'DELETE',
    url: `/boss/role/${id}`
  })
}

再三強(qiáng)調(diào)砰诵,再三強(qiáng)調(diào)征唬,要核實(shí)英語(yǔ)單詞拼寫(本人這里又因?yàn)閱卧~問(wèn)題浪費(fèi)了很多時(shí)間來(lái)調(diào)試)
準(zhǔn)備工作到此結(jié)束

添加角色布局

使用Element的Dialog對(duì)話框組件

// Element 官方示例:Dialog 對(duì)話框組件
<el-dialog
  title="提示"
  :visible.sync="dialogVisible"
  width="30%"
  :before-close="handleClose">
  <span>這是一段信息</span>
  <span slot="footer" class="dialog-footer">
    <el-button @click="dialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="dialogVisible = false">確 定</el-button>
  </span>
</el-dialog>
<script>
  export default {
    data() {
      return {
        dialogVisible: false
      };
    },
    methods: {
      handleClose(done) {
        this.$confirm('確認(rèn)關(guān)閉?')
          .then(_ => {
            done();
          })
          .catch(_ => {});
      }
    }
  };
</script>

添加到頁(yè)面中最后位置茁彭,不需要關(guān)閉處理总寒,刪除就可以了

  • 點(diǎn)擊頂部添加按鈕時(shí),將dialogVisible設(shè)置為true理肺,讓對(duì)話框顯示
// role/components/list.vue
<template>
  <div class="role-list">
    <el-card class="box-card">
            ...
      <!-- 點(diǎn)擊添加按鈕摄闸,顯示對(duì)話框 -->
      <el-button @click="dialogVisible = true" >添加角色</el-button>
      ...
    </el-card>
    <!-- 對(duì)話框組件:刪除 :before-close="handleClose"  -->
    <el-dialog
      title="添加角色"
      :visible.sync="dialogVisible"
      width="30%"
    >
      <span>這是一段信息</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false">確 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        ...
        dialogVisible: false
      };
    }
  };
</script>

內(nèi)部的form表單結(jié)構(gòu)不建議直接書(shū)寫,因?yàn)椴恢挂粋€(gè)功能使用這個(gè)結(jié)構(gòu)妹萨,建議單獨(dú)封裝一個(gè)組件進(jìn)行處理

// role/components/create-or-edit.vue
<template>
  <div>
    <el-form>
      <el-form-item label="角色名稱">
        <el-input></el-input>
      </el-form-item>
      <el-form-item label="角色編碼">
        <el-input></el-input>
      </el-form-item>
      <el-form-item label="角色描述">
        <el-input type="textarea"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button>取消</el-button>
        <el-button type="primary">確認(rèn)</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  name: 'CreateOrEdit'
}
</script>

<style lang="scss" scoped></style>

引入到list組件中年枕,并將其注冊(cè)為子組件

// role/components/list.vue
<el-dialog
  title="添加角色"
  :visible.sync="dialogVisible"
  width="30%">
  <!-- 將對(duì)話框內(nèi)容更換為自定義組件 -->
  <create-or-edit></create-or-edit>
</el-dialog>
...
<script>
...
import CreateOrEdit from './create-or-edit'

export default {
  ...
  components: {
    CreateOrEdit
  },
    ...
}
</script>

結(jié)構(gòu)準(zhǔn)備完畢,設(shè)置請(qǐng)求乎完,提交表單用

// services/role.js
...
// 添加或編輯角色
export const createOrUpdate = data => {
  return request({
    method: 'POST',
    url: '/boss/role/saveOrUpdate',
    data
  })
}

引入文件熏兄,根據(jù)接口要求聲明綁定數(shù)據(jù),綁定給元素,瀏覽器可以查看效果

// create-or-edit.vue
<el-form>
  <el-form-item label="角色名稱">
    <el-input v-model="role.name"></el-input>
  </el-form-item>
  <el-form-item label="角色編碼">
    <el-input v-model="role.code"></el-input>
  </el-form-item>
  <el-form-item label="角色描述">
    <el-input v-model="role.description" type="textarea"></el-input>
  </el-form-item>
  <el-form-item>
    <el-button>取消</el-button>
    <el-button type="primary">確認(rèn)</el-button>
  </el-form-item>
</el-form>

<script>
import { createOrEdit } from "@/services/role"

export default {
  name: 'CreateOrEdit',
  data () {
    return {
      // 根據(jù)接口要求綁定數(shù)據(jù)
      role: {
        code: '',
        name: '',
        description: ''
      }
    }
  }
}
</script>

點(diǎn)擊確認(rèn)摩桶,提交表單

// create-or-edit.vue
<el-button type="primary" @click="onSubmit">確認(rèn)</el-button>
...
<script>
...
  methods: {
    async onSubmit () {
      // 省略驗(yàn)證步驟
      const { data } = await createOrEdit(this.role)
      if (data.code === '000000') {
      }
    }
  }
...
</script>

成功之后呢桥状,應(yīng)該關(guān)閉對(duì)話框并且刷新列表,這些都是list.vue的功能典格,這個(gè)需要用一個(gè)子傳父的通信功能了

  • 給子組件注冊(cè)自定義事件
  • 父組件監(jiān)聽(tīng)事件岛宦,觸發(fā)就說(shuō)明添加成功,就可以進(jìn)行下一步的處理了
// create-or-edit.vue
...
async onSubmit () {
  const { data } = await createOrEdit(this.role)
  if (data.code === '000000') {
    // 提示
    this.$message.success('添加成功')
    // 子組件觸發(fā)自定義事件
    this.$emit('success')
    // 清空內(nèi)容
    this.role = {}
  }
}
...
// list.vue
<create-or-edit
  @success="onSuccess"
></create-or-edit>
...
<script>
...
  // 添加成功的操作
  onSuccess () {
    // 關(guān)閉對(duì)話框
    this.dialogVisible = false
    // 刷新列表數(shù)據(jù)
    this.loadRoles()
  },
...
</script>

當(dāng)然了耍缴,取消按鈕也是需要設(shè)置的,點(diǎn)擊取消挽霉,關(guān)閉對(duì)話框防嗡,同樣的需要子傳父

// create-or-edit.vue
<el-button
  @click="onCancel"
>取消</el-button>
...
<script>
...
  onCancel () {
    this.$emit('cancel')
    this.role = {}
  }
...
</script>

由于取消無(wú)需刷新列表,可以直接在行內(nèi)標(biāo)簽寫入我們所需的關(guān)閉彈窗

// list.vue
<create-or-edit
  ...
  @cancel="dialogVisible = false"
></create-or-edit>

編輯角色

編輯功能和添加功能類似侠坎,采用同一組件蚁趁,操作時(shí)使用isEdit傳遞狀態(tài)

// list.vue
<script>
...
data () {
  return {
        ...
    // 添加或編輯
    isEdit: false,
    ...
  }
},
...
</script>
...
<el-dialog
  :title="isEdit ? '編輯角色' : '添加角色'"
  ...>
  <!-- 將對(duì)話框內(nèi)容更換為自定義組件 -->
  <create-or-edit
    :is-edit="isEdit"
    ...
  ></create-or-edit>
</el-dialog>

子組件接收狀態(tài)

// create-or-edit.vue
props: {
  isEdit: {
    type: Boolean,
    default: false
  }
},

點(diǎn)擊添加時(shí),設(shè)置isEdit為false

// list.vue
<el-button @click="handleAdd" >添加角色</el-button>
...
<script>
...
  handleAdd () {
    this.dialogVisible = true
    this.isEdit = false
  },
...
</script>

點(diǎn)擊編輯按鈕实胸,設(shè)置isEdit為true他嫡,同時(shí)彈出對(duì)話框

// list.vue
...
handleEdit (role) {
  // 顯示對(duì)話框
  this.dialogVisible = true
  // 設(shè)置編輯狀態(tài)
    this.isEdit = true
},

點(diǎn)擊編輯時(shí)將數(shù)據(jù)綁定給表單,需要父?jìng)髯訉⒕庉嫷慕巧玦d傳入

  • 傳入id由子組件重新查詢庐完,可以確保數(shù)據(jù)為最新的數(shù)據(jù)钢属,避免數(shù)據(jù)不齊全的情況
// list.vue
<script>
...
  data () {
      ...
      // 正在編輯的角色I(xiàn)D
      roleId: null
    }
  },
  handleEdit (role) {
    this.dialogVisible = true
    this.isEdit = true
    // 將要編輯的角色 ID 傳遞給表單展示
    this.roleId = role.id
  },
...
</script>
...
<create-or-edit
  :is-edit="isEdit"
  :role-id="roleId"
    @success="onSuccess"
    @cancel="dialogVisible = false"
></create-or-edit>

子組件接收,并且在created鉤子函數(shù)下展示

// create-or-list.vue
props: {
  ...
  roleId: {
    type: Object
  }
},
created () {
  if (this.isEdit) {
    console.log(roleId)
  }
},

封裝請(qǐng)求功能

// services/role.js
...
// 獲取角色
export const getRoleById = id => {
  return request({
    method: 'GET',
    url: `/boss/role/${id}`,
  })
}

引入請(qǐng)求角色數(shù)據(jù)

// create-or-edit.vue
created () {
  if (this.isEdit) {
    // 加載用戶數(shù)據(jù)
    this.loadRole()
  }
},
...
async loadRole () {
  const { data } = await getRoleById(this.roleId)
  if (data.code === '000000') {
    // 將角色數(shù)據(jù)更新給 role 即可
    this.role = data.data
  }
},

提交功能因?yàn)槲覀兊慕涌谑切略龊途庉嫷膮^(qū)別在于id门躯,role中自動(dòng)包含了參數(shù)id淆党,所以無(wú)需修改直接提交
優(yōu)化:role數(shù)據(jù)渲染問(wèn)題

使用監(jiān)聽(tīng)器監(jiān)聽(tīng)id變化,一旦變化之后讶凉,比如我先點(diǎn)擊了添加按鈕染乌,那么edit界面就不會(huì)再有渲染數(shù)據(jù),需要再次進(jìn)行加載

通過(guò)子傳父的自定義事件懂讯,當(dāng)我們點(diǎn)擊了取消按鈕荷憋,isEdit,roleId都會(huì)重置褐望,這樣以來(lái)數(shù)據(jù)就便于控制勒庄,表單可以正常執(zhí)行功能

以上的方法是本人自行解決的辦法,但是有更好的做法:

由于當(dāng)前組件只是顯示和隱藏譬挚,組件沒(méi)有銷毀和創(chuàng)建锅铅,所以我們通過(guò)v-if來(lái)控制對(duì)話框,達(dá)到生命周期函數(shù)created重新運(yùn)行的目的,可以避免數(shù)據(jù)只會(huì)渲染一次的錯(cuò)誤

// list.vue
<create-or-edit
  v-if="dialogVisible"
  ...
></create-or-edit>

完成

分配菜單

分配菜單用于設(shè)置角色可以訪問(wèn)哪些菜單功能

布局與路由處理

創(chuàng)建文件

// role/alloc-menu.vue
<template>
  <div class="alloc-menu"></div>
</template>

<script>
export default {
  name: 'AllocMenu'
}
</script>

<style lang="scss" scoped></style>

添加路由减宣,設(shè)置動(dòng)態(tài)參數(shù)

// router/index.js
...
  {
    path: '/role/:roleId/alloc-menu',
    name: 'alloc-menu',
    component: () => import(/* webpackChunkName: 'alloc-menu' */'@/views/role/alloc-menu')
  }
]
...

點(diǎn)擊分配菜單按鈕盐须,進(jìn)行導(dǎo)航跳轉(zhuǎn)

  • 跳轉(zhuǎn)后,可以通過(guò)$route來(lái)獲取要分配菜單的用戶id
// list.vue
<!-- scope.row 為作用域插槽提供的當(dāng)前行數(shù)據(jù) -->
<el-button
  type="text"
  @click="$router.push({
    name: 'alloc-menu',
    params: {
      roleId: scope.row.id
    }
  })"
>分配菜單</el-button>

使用這種方式非常簡(jiǎn)單漆腌,但是會(huì)讓組件與路由耦合(組件無(wú)法獨(dú)立于路由使用)

  • 如果希望組件與路由解耦贼邓,可以將動(dòng)態(tài)路由參數(shù)替換為props(這個(gè)方法可以詳細(xì)參考一下Vue Router階段->路由傳參處理
// router/index.js
//  - 設(shè)置 props: true阶冈,讓路徑參數(shù)通過(guò) props 方式傳遞給組件
{
  path: '/role/:roleId/alloc-menu',
  name: 'alloc-menu',
  component: () => import(/* webpackChunkName: 'alloc-menu' */'@/views/role/alloc-menu'),
  props: true
},
// alloc-menu.vue
props: {
  // 組件內(nèi)需要通過(guò) props 接收路徑傳遞的參數(shù),實(shí)現(xiàn)解耦
  //   - 注意塑径,$route 里的數(shù)據(jù)雖然還能訪問(wèn)女坑,但不要用,否則組件與路由還是耦合统舀,解耦就白寫了
  roleId: {
    type: [String, Number],
    required: true
  }
}

菜單列表展示

這里使用Element的Tree樹(shù)形控件組件

// Element 官方示例:Tree 樹(shù)形控件基礎(chǔ)用法
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>

<script>
  export default {
    data() {
      return {
        data: [{
          label: '一級(jí) 1',
          children: [{
            label: '二級(jí) 1-1',
            children: [{
              label: '三級(jí) 1-1-1'
            }]
          }]
        }, {
          label: '一級(jí) 2',
          children: [{
            label: '二級(jí) 2-1',
            children: [{
              label: '三級(jí) 2-1-1'
            }]
          }, {
            label: '二級(jí) 2-2',
            children: [{
              label: '三級(jí) 2-2-1'
            }]
          }]
        }, {
          label: '一級(jí) 3',
          children: [{
            label: '二級(jí) 3-1',
            children: [{
              label: '三級(jí) 3-1-1'
            }]
          }, {
            label: '二級(jí) 3-2',
            children: [{
              label: '三級(jí) 3-2-1'
            }]
          }]
        }],
        defaultProps: {
          children: 'children',
          label: 'label'
        }
      };
    },
    methods: {
      handleNodeClick(data) {
        console.log(data);
      }
    }
  };
</script>

引入到頁(yè)面中匆骗,去除事件

  • 設(shè)置一個(gè)Card作為容器
  • 設(shè)置默認(rèn)全部展開(kāi),使用<el-tree>組件的
    dafault-expand-all屬性
  • 設(shè)置復(fù)選框提示誉简,使用show-checkbox屬性
  • data代表的是樹(shù)形圖數(shù)據(jù)碉就,更改為menus避免混淆
  • defaultProps代表讀取數(shù)據(jù)時(shí),屬性對(duì)應(yīng)的功能闷串,因?yàn)檎?qǐng)求接口時(shí)瓮钥,不是所有的接口都用label作為標(biāo)題,具體根據(jù)接口返回的數(shù)據(jù)為標(biāo)準(zhǔn)
  • 請(qǐng)求數(shù)據(jù)接口:接口地址
  • 將其封裝到services/menu.js中
// services/menu.js
...
// 獲取所有菜單并按層級(jí)展示(注意烹吵,這是菜單功能碉熄,保存到 menu.js 中)
export const getMenuNodeList = () => {
  return request({
    method: 'GET',
    url: '/boss/menu/getMenuNodeList'
  })
}
  • 引入請(qǐng)求數(shù)據(jù),由于對(duì)應(yīng)標(biāo)題和層級(jí)的屬性與默認(rèn)名稱不同肋拔,需要進(jìn)行設(shè)置锈津,menus中的默認(rèn)數(shù)據(jù)也可以刪掉
<template>
  <div class="alloc-menu">
    <el-card>
      <el-tree
        :data="menus"
        :props="defaultProps"
        show-checkbox
        default-expand-all
        >
      </el-tree>
    </el-card>
  </div>
</template>

<script>
import { getMenuNodeList } from '@/services/menu'
export default {
  name: 'AllocMenu',
  props: {
    roleId: {
      type: [Number, String],
      required: true
    }
  },
  created () {
    this.loadMenus()
  },
  data () {
    return {
      menus: [],
      defaultProps: {
        children: 'subMenuList',
        label: 'name'
      }
    }
  },
  methods: {
    async loadMenus () {
      const { data } = await getMenuNodeList()
      if (data.code === '000000') {
        this.menus = data.data
      }
    }
  }
}
</script>

<style lang="scss" scoped>

</style>

保存與清空

設(shè)置按鈕結(jié)構(gòu)

// alloc-menu.vue
<el-card>
  <el-tree
    ...
  ></el-tree>
  <div style="margin: 20px;">
    <el-button>清空</el-button>
    <el-button type="primary">保存</el-button>
  </div>
</el-card>

保存

  • 觀察接口,需要用戶id與菜單列表(參數(shù)有點(diǎn)復(fù)雜)
// services/menu.js
...
// 給角色分配菜單
export const allocateRoleMenus = data => {
  return request({
    method: 'POST',
    url: '/boss/menu/allocateRoleMenus',
    data
  })
}

引入并且在調(diào)用保存按鈕時(shí)調(diào)用

  • 請(qǐng)求參數(shù)需要分配的菜單列表(由勾選選項(xiàng)組成)只损,可以通過(guò)tree組件的getCheckedKeys方法來(lái)獲取
  • 首先要給tree組件設(shè)置一個(gè)ref一姿,才能找到指定的tree組件
  • 如果通過(guò)getCheckedKeys方法獲取,需要給tree組件設(shè)置一個(gè)node-key來(lái)設(shè)置通過(guò)哪個(gè)屬性作為唯一標(biāo)識(shí)(比如id)
  • 提交成功跃惫,跳轉(zhuǎn)加提示信息
// alloc-menu.vue
...
 <el-tree
   ref="menu-tree"
   node-key="id"
   ...
 ></el-tree>
...
<el-button type="primary" @click="onSave">保存</el-button>
...
<script>
import { getMenuNodeList, allocateRoleMenus } from '@/services/menu'
...
async onSave () {
  // 傳入通過(guò)路徑參數(shù)接收的角色I(xiàn)D
  const { data } = await allocateRoleMenus({
    roleId: this.roleId,
    menuIdList: this.$refs['menu-tree'].getCheckedKeys()
  })
  if (data.code === '000000') {
    // 提示
    this.$message.success('分配菜單成功')
    // 返回角色列表頁(yè)即可
    this.$router.push('/role')
  }
}

改進(jìn)(勾選已分配選項(xiàng))

Tree組件具有default-checked-keys屬性叮叹,值為數(shù)組,當(dāng)node-key為id時(shí)爆存,數(shù)組內(nèi)存放的id對(duì)應(yīng)的選項(xiàng)會(huì)被選擇
通過(guò)接口來(lái)請(qǐng)求當(dāng)前角色擁有的菜單列表蛉顽,接口地址

// services/menu.js
...
// 獲取角色擁有的菜單列表
export const getRoleMenus = roleId => {
  return request({
    method: 'GET',
    // 下面兩種方式均可
    // url: `/boss/menu/getRoleMenus?roleId=${roleId}`,
    url: '/boss/menu/getRoleMenus',
    params: { // axios 會(huì)把 params 轉(zhuǎn)換為 urlencoded 并以 ? 連接到 url 后
      roleId
    }
  })
}

引入并調(diào)用

// alloc-menu.vue
..
import { getMenuNodeList, allocateRoleMenus, getRoleMenus } from '@/services/menu'
...
created () {
  ...
  // 加載角色擁有的菜單列表
  this.loadRoleMenus()
},
...
async loadRoleMenus () {
  // 請(qǐng)求角色擁有的菜單列表
  const { data } = await getRoleMenus(this.roleId)
  if (data.code === '000000') {
    console.log(data)
  }
},

觀察響應(yīng)數(shù)據(jù)可以發(fā)現(xiàn)一點(diǎn):每一個(gè)菜單項(xiàng)都有selected屬性,以此來(lái)判斷是否選中了數(shù)據(jù)先较,拿到了這些數(shù)據(jù)的id之后携冤,設(shè)置給default-checked-keys就可以了

data () {
    return {
     checkedKeys: []
  }
}
...
methods: {
// 封裝的用于數(shù)據(jù)篩選的方法(篩選出被選中選項(xiàng)的菜單項(xiàng)的id)
    getCheckedKeys (menus) {
      // 遍歷數(shù)據(jù)(將所有存在子節(jié)點(diǎn)的node排除,對(duì)子節(jié)點(diǎn)列表進(jìn)行遍歷)
      menus.forEach(menu => {
        // 未選中闲勺,結(jié)束
        if (!menu.selected) {
          return
        }
        // 是否存在子節(jié)點(diǎn)
        if (menu.subMenuList) {
          return this.getCheckedKeys(menu.subMenuList)
        }
        // 選中的葉子節(jié)點(diǎn)曾棕,沒(méi)有子節(jié)點(diǎn)的節(jié)點(diǎn),存儲(chǔ)Id即可
        // this.checkedKeys.push(menu.id)菜循,采用賦值的方法可以避免因?yàn)轭l繁的異步操作導(dǎo)致視圖不更新的問(wèn)題
        this.checkedKeys = [...this.checkedKeys, menu.id]
      })
    },
    async loadRoleMenus () {
      const { data } = await getRoleMenus(this.roleId)
      if (data.code === '000000') {
        this.getCheckedKeys(data.data)
      }
    },
...
}

清空

Element-Tree-樹(shù)型節(jié)點(diǎn)的選擇實(shí)例演示了如何進(jìn)行清空

  • 通過(guò)this.$refs.tree.setCheckedKeys([])即可清空
// alloc-menu.vue
<el-button @click="resetChecked">清空</el-button>
...
// 設(shè)置清空方法
 resetChecked () {
   this.$refs['menu-tree'].setCheckedKeys([])
 }

完成翘地,旁邊的按鈕,分配資源以及查詢重置都是重復(fù)的內(nèi)容,可以快速完成

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末衙耕,一起剝皮案震驚了整個(gè)濱河市昧穿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌橙喘,老刑警劉巖时鸵,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異厅瞎,居然都是意外死亡饰潜,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門磁奖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)囊拜,“玉大人,你說(shuō)我怎么就攤上這事比搭。” “怎么了南誊?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵身诺,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我抄囚,道長(zhǎng)霉赡,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任幔托,我火速辦了婚禮穴亏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘重挑。我一直安慰自己嗓化,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布谬哀。 她就那樣靜靜地躺著刺覆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪史煎。 梳的紋絲不亂的頭發(fā)上谦屑,一...
    開(kāi)封第一講書(shū)人閱讀 51,590評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音篇梭,去河邊找鬼氢橙。 笑死,一個(gè)胖子當(dāng)著我的面吹牛恬偷,可吹牛的內(nèi)容都是我干的悍手。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼谓苟!你這毒婦竟也來(lái)了官脓?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤涝焙,失蹤者是張志新(化名)和其女友劉穎卑笨,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體仑撞,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赤兴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了隧哮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桶良。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖沮翔,靈堂內(nèi)的尸體忽然破棺而出陨帆,到底是詐尸還是另有隱情,我是刑警寧澤采蚀,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布疲牵,位于F島的核電站,受9級(jí)特大地震影響榆鼠,放射性物質(zhì)發(fā)生泄漏纲爸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一妆够、第九天 我趴在偏房一處隱蔽的房頂上張望识啦。 院中可真熱鬧,春花似錦神妹、人聲如沸颓哮。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)题翻。三九已至,卻和暖如春腰鬼,著一層夾襖步出監(jiān)牢的瞬間嵌赠,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工熄赡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留姜挺,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓彼硫,卻偏偏與公主長(zhǎng)得像炊豪,于是被迫代替她去往敵國(guó)和親凌箕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容