Tree.jsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import { Menu, Icon, Input } from 'ant-design-vue'
  2. const { Item, ItemGroup, SubMenu } = Menu
  3. const { Search } = Input
  4. export default {
  5. name: 'Tree',
  6. props: {
  7. dataSource: {
  8. type: Array,
  9. required: true
  10. },
  11. openKeys: {
  12. type: Array,
  13. default: () => []
  14. },
  15. search: {
  16. type: Boolean,
  17. default: false
  18. }
  19. },
  20. created () {
  21. this.localOpenKeys = this.openKeys.slice(0)
  22. },
  23. data () {
  24. return {
  25. localOpenKeys: []
  26. }
  27. },
  28. methods: {
  29. handlePlus (item) {
  30. this.$emit('add', item)
  31. },
  32. handleTitleClick (...args) {
  33. this.$emit('titleClick', { args })
  34. },
  35. renderSearch () {
  36. return (
  37. <Search
  38. placeholder="input search text"
  39. style="width: 100%; margin-bottom: 1rem"
  40. />
  41. )
  42. },
  43. renderIcon (icon) {
  44. return icon && (<Icon type={icon} />) || null
  45. },
  46. renderMenuItem (item) {
  47. return (
  48. <Item key={item.key}>
  49. { this.renderIcon(item.icon) }
  50. { item.title }
  51. <a class="btn" style="width: 20px;z-index:1300" {...{ on: { click: () => this.handlePlus(item) } }}><a-icon type="plus"/></a>
  52. </Item>
  53. )
  54. },
  55. renderItem (item) {
  56. return item.children ? this.renderSubItem(item, item.key) : this.renderMenuItem(item, item.key)
  57. },
  58. renderItemGroup (item) {
  59. const childrenItems = item.children.map(o => {
  60. return this.renderItem(o, o.key)
  61. })
  62. return (
  63. <ItemGroup key={item.key}>
  64. <template slot="title">
  65. <span>{ item.title }</span>
  66. <a-dropdown>
  67. <a class="btn"><a-icon type="ellipsis" /></a>
  68. <a-menu slot="overlay">
  69. <a-menu-item key="1">新增</a-menu-item>
  70. <a-menu-item key="2">合并</a-menu-item>
  71. <a-menu-item key="3">移除</a-menu-item>
  72. </a-menu>
  73. </a-dropdown>
  74. </template>
  75. { childrenItems }
  76. </ItemGroup>
  77. )
  78. },
  79. renderSubItem (item, key) {
  80. const childrenItems = item.children && item.children.map(o => {
  81. return this.renderItem(o, o.key)
  82. })
  83. const title = (
  84. <span slot="title">
  85. { this.renderIcon(item.icon) }
  86. <span>{ item.title }</span>
  87. </span>
  88. )
  89. if (item.group) {
  90. return this.renderItemGroup(item)
  91. }
  92. // titleClick={this.handleTitleClick(item)}
  93. return (
  94. <SubMenu key={key}>
  95. { title }
  96. { childrenItems }
  97. </SubMenu>
  98. )
  99. }
  100. },
  101. render () {
  102. const { dataSource, search } = this.$props
  103. // this.localOpenKeys = openKeys.slice(0)
  104. const list = dataSource.map(item => {
  105. return this.renderItem(item)
  106. })
  107. return (
  108. <div class="tree-wrapper">
  109. { search ? this.renderSearch() : null }
  110. <Menu mode="inline" class="custom-tree" {...{ on: { click: item => this.$emit('click', item), 'update:openKeys': val => { this.localOpenKeys = val } } }} openKeys={this.localOpenKeys}>
  111. { list }
  112. </Menu>
  113. </div>
  114. )
  115. }
  116. }