Vue2.0 permission tree component implementation code, vue2.0 permission tree component

Source: Internet
Author: User
Tags allkeys

Vue2.0 permission tree component implementation code, vue2.0 permission tree component

The Element-Ui of ELE. Me used by the project. The permission tree uses its tree control:

<el-tree :data="data" ></el-tree> 

At the beginning, there were no special requirements. The third-level branch was quite good. However, the new requirement is as follows: the page OPERATION button permission is added, that is, the level-4 branch is reached, and the level-4 permission Layout mode is required to be horizontal. the operation button permission is not fixed to the level-4 tree, but the style requirements are consistent. In this way, it is very difficult to operate. If only four trees are horizontal, you can also adjust the style. I originally wanted to modify the tree control source code of the element to implement it. I checked some information on the Internet and there is no good way to generate the compilation file. The final decision is to write the component to complete the above requirements.

First:

It can basically meet the requirements. The style is slightly worse than that of the element and will be optimized later.

The component code is as follows:

<Template> <li: class = "[isButton, hasBorder]" style = "list-style: none; "> <span @ click =" toggle "v-show =" model. menuLevel! = 1 "> <I v-if =" isFolder "class =" icon ": class =" [open? 'Folder-open': 'folder'] "style =" margin-bottom: 3px; "> </I> <I v-if = "! IsFolder "class =" icon file-text "> </I> <input type =" checkbox "class =" checkCls "@ click. stop = "selTree (model)": id = "'menu '+ model. id ": class =" 'group' + label "> {model. menuName }}</span> <ul v-show = "open" v-if = "isFolder"> <tree-menu v-for = "(item, index) in model. childNode ": model =" item ": key =" index ": menuList =" menuList ": label =" label ": selectKeys = "selectKeys"> </tree-menu> </ul> </li> </template> <scrip T type = "text/ecmascript-6"> import $ from 'jquery 'export default {name: 'treemenu', props: ['model', 'menulist', 'label ', 'selectkeys '], data () {return {open: true, // selAllkeys: [] }}, computed: {isFolder: function () is enabled by default () {return this. model. childNode & this. model. childNode. length}, isButton: function () {if (this. model. buttonControl = '1') {return 'btncls'} else {return 'menu Cls '}}, hasBorder: function () {if (this. model. menuLevel === 1) {return 'blk _ border' }}, methods: {getAllKeys () {var keys = [] var objs = $ ('. group '+ this. label + ': checked') for (let I = 0; I <objs. length; I ++) {let id = objs [I]. id = id. substring (4) keys. push (id-0) // Save the selected menu id} return keys}, toggle: function () {if (this. isFolder) {this. open =! This. open }}, // obtain the menu object getMeunById (id, allMenuList) {var menu ={} if (allMenuList. id = id) {// level-1 menu = allMenuList} else if (allMenuList. childNode & allMenuList. childNode. length) {// list menu for (let I = 0; I <allMenuList. childNode. length; I ++) {if (allMenuList. childNode [I]. id = id) {menu = allMenuList. childNode [I] break} else if (allMenuList. childNode [I]. childNode & allMen UList. childNode [I]. childNode. length) {// Level 3 for (let j = 0; j <allMenuList. childNode [I]. childNode. length; j ++) {if (allMenuList. childNode [I]. childNode [j]. id = id) {menu = allMenuList. childNode [I]. childNode [j] break }}} return menu}, // checkbox Click Event selTree (model) {var obj = $ ('# menu' + model. id) [0] // checkbox DOM object if (obj. checked) {// select // if a sublevel exists, select if (model. childNode & mod El. childNode. length) {this. subMenusOp (model. childNode, 1)} // if a superior exists, check whether the superior CheckBox if (model. supMenuID! = 0 & model. menuLevel> 2) {this. supMenusOp (model. supMenuID, 1) }}else {// cancel // if a sublevel exists, all sublevels cancel if (model. childNode & model. childNode. length) {this. subMenusOp (model. childNode, 0)} // if there is a parent, confirm whether to cancel the parent CheckBox if (model. supMenuID! = 0 & model. menuLevel> 2) {this. supMenusOp (model. supMenuID, 0)} this. getAllKeys ()}, // the flag of the sub-menu operation is selected, and flag = 0 is used to cancel subMenusOp (childNodes, flag) {for (let I = 0; I <childNodes. length; I ++) {var menu = childNodes [I] var id = menu. id if (flag = 1) {// select $ ('# menu' + id) [0]. checked = true} else {// cancel $ ('# menu' + id) [0]. checked = false} if (menu. childNode & menu. childNode. length) {th Is. subMenusOp (menu. childNode, flag) }}, // upper-level menu operation (select: flag = 1, cancel: flag = 0) supMenusOp (id, flag) {var menu = this. getMeunById (id, this. menuList) if (menu. childNode & menu. childNode. length) {var childLength = menu. childNode. length // number of direct sub-levels var selectCount = 0 for (let I = 0; I <childLength; I ++) {let id1 = menu. childNode [I]. id if ($ ('# menu' + id1) [0]. checked) {selectCount ++} if (flag = 1) {// Select if (childLength === selectCount) {$ ('# menu' + id) [0]. checked = true if (menu. supMenuID! = 0 & menu. menuLevel> 2) {this. supMenusOp (menu. supMenuID, flag) }}else if (flag = 0) {if (childLength! = SelectCount) {$ ('# menu' + id) [0]. checked = false if (menu. supMenuID! = 0 & menu. menuLevel> 2) {this. supMenusOp (menu. supMenuID, flag) }}}, // calculates whether all lower-level nodes are selected. true is returned; false isAllSel (childNodes, selectKeys) is returned) {var nodeKeys = [] // selected id set this. addKeys (childNodes, selectKeys, nodeKeys) var allKeys = [] this. getNodesCount (childNodes, allKeys) if (nodeKeys. length = allKeys. length) {return true} else {return false}, // calculate the id set addKeys (chil DNodes, selectKeys, Arrs) {for (let I = 0; I <childNodes. length; I ++) {if (selectKeys. indexOf (childNodes [I]. id)> = 0) {Arrs. push (childNodes [I]. id)} if (childNodes [I]. childNode & childNodes [I]. childNode. length) {this. addKeys (childNodes [I]. childNode, selectKeys, Arrs) }}, // calculate the sublevel getNodesCount (childNodes, allKeys) {for (let I = 0; I <childNodes. length; I ++) {allKeys. push (ch IldNodes [I]. id) if (childNodes [I]. childNode & childNodes [I]. childNode. length) {this. getNodesCount (childNodes [I]. childNode, allKeys) }}}, mounted () {// disable the check box's bubble event $ ("input [type = 'checkbox']"). click (function (e) {e. stopPropagation ()}) // select the menu to enable if (this. selectKeys instanceof Array & this. selectKeys. length> 0 & this. selectKeys. indexOf (this. model. id)> = 0) {if (this. model. childNode & thi S. model. childNode. length & this. model. menuLevel! = 1) {// contains sub-level, except for the first-level menu // calculates whether all sub-nodes are selected if (this. isAllSel (this. model. childNode, this. selectKeys) {$ ('# menu' + this. model. id) [0]. checked = true} else {$ ('# menu' + this. model. id) [0]. checked = true }}</script> <style>. blk_border {border: 1px solid # d1dbe5; padding-bottom: 15px ;}. blk_border ul {padding-left: 15px;} ul {list-style: none;} I. icon {display: inline-block; width: 15px; hei Ght: 15px; background-repeat: no-repeat; vertical-align: middle ;}. icon. folder {background-image: url (.. /.. /images/close.png );}. icon. folder-open {background-image: url (.. /.. /images/open.png );}. tree-menu li {line-height: 1.5;} li. btnCls {float: left; margin-right: 10px;} li. menuCls {clear: both; line-height: 30px ;}. checkCls {vertical-align: middle ;}. el-tabs _ content {color: # 48576A;} </Style> the data structure of the permission tree has certain requirements. It is slightly more attribute than the data structure of the tree control of element, otherwise the implementation will not be so simple, the optimized permission tree data structure simplifies the return of the selected menu and does not use vuex. Permission tree data structure: {'childnode': [{'childnode': [{'icon ': '', 'id': 242, 'menulevel': 3, 'menuname': 'travel order', 'menutop ': 1, 'menuurl':'/', 'buttoncontrol': '0', 'supmenuid': 241 }, {'icon ': '', 'id': 243, 'menulevel': 3, 'menuname': 'visa order', 'menutop': 2, 'menuurl ': '/', 'buttoncontrol': '0', 'supmenuid': 241}, {'icon ': '', 'id': 244, 'menulevel': 3, 'menuname': 'Notice of departure ', 'menutop': 3, 'menuurl': '/', 'buttoncontrol': '0', 'supmenuid': 241}], 'icon ': '', 'id': 241, 'menulevel': 2, 'menuname': 'order management', 'menutop': 1, 'menuurl ': '/', 'buttoncontrol': '0', 'supmenuid': 240}, {'childnode': [{'icon ': '', 'id': 246, 'menulevel': 3, 'menuname': 'travel product', 'menutop ': 1, 'menuurl':'/tourproduct', 'buttoncontrol': '0 ', 'supmenuid': 245}, {'icon ': '', 'id': 247, 'menulevel': 3, 'menuname': 'gallery', 'menutop ': 2, 'menurl': '/basepicstore', 'buttoncontrol': '0', 'supmenuid': 245}, {'icon': '', 'id': 248, 'menulevel': 3, 'menuname': 'visa product', 'menutop ': 3, 'menuurl':'/', 'buttoncontrol': '0 ', 'supmenuid': 245}], 'icon ': '', 'id': 245, 'menulevel': 2, 'menuname': 'product management', 'menutop ': 2, 'menurl': '/', 'buttoncontrol': '0', 'supmenuid': 240}, {'childnode': [{'icon ':'', 'id': 250, 'menulevel': 3, 'menuname': 'travel ads', 'menutop ': 1, 'menuurl':'/', 'buttoncontrol ': '0', 'supmenuid': 249}], 'icon ': '', 'id': 249, 'menulevel': 2, 'menuname': 'advertising management ', 'menutop ': 3, 'menuurl':'/', 'buttoncontrol': '0', 'supmenuid': 240}], 'icon ':'', 'id': 240, 'menulevel': 1, 'menuname': 'Business Center', 'menutop ': 1, 'menuurl':'/', 'buttoncontrol ': '0', 'supmenuid': 0}

The actual data is an array of the above objects.

Here we mainly addbuttonControlAndsupMenuIdTo easily determine the style of Button permissions and to select or cancel checkbox cascade operations.

Reference component code:

<el-tab-pane v-for="(menu, index) in theModel" :key="index" :label="menu.menuName">  <my-tree :model="menu" ref="tree" :menuList="menu" :label="index" :selectKeys="selectKeys"></my-tree> </el-tab-pane>

TheModel is the permission tree array, and selectKeys is the selected permission array, that is, the id set.

Mounted () implements initialization: disables the Bubble Time of checkbox and the value assignment of selectKeys.

In fact, the key points of the permission tree or menu tree are recursive algorithms. to select or cancel a button, recursive operations must be performed. Here, jQuery is used to assist in operations, which simplifies many things. It should be the spirit of data binding. GetAllKeys () returns the permission id for obtaining a checkbox value of true.
The actual data obtained from the selected permission menu is as follows:

Summary

The above is the Vue2.0 permission tree component implementation Code introduced by xiaobian. I hope it will help you. If you have any questions, please leave a message and I will reply to you in a timely manner. Thank you very much for your support for the help House website!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.