diff --git a/LICENSE b/LICENSE index 70baf45..aa88d8a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2016 weibt +Copyright (c) 2016 weibangtuo Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md new file mode 100644 index 0000000..0589be3 --- /dev/null +++ b/README.md @@ -0,0 +1,69 @@ +# Vue Tree View Component + + Support `Vue.js` 1.0+ + +## Usage + +Add the following required resources. + +```html + + + + + +``` + +Add the component in your vue view. + +```html +
+ +
+ +``` + +## Node Options + +```javascript +{ + name: 'Node Name', + title: 'Node Tag title attr', + isParent: true, // + isOpen: true, // Control node to fold or unfold + icon: 'fa fa-folder', // Or other custom icons call by class name + openedIcon: 'fa fa-folder-open', // [option] For parent. Show when isOpen == true, show icon if it's null or empty + closedIcon: 'fa fa-folder', // [option] For parent. Show when isOpen != true, show icon if it's null or empty + children: [], // for parent node only + buttons: [ // [] + { + title: 'icon button tag title attr', //[option] + icon: 'fa fa-edit', + click: function (node) { //[option] + // + } + } + //... + ] +} +``` + + + + +## License + +Copyright (c) 2016 weibangtuo. Under MIT License. diff --git a/demo/demo-vue1.html b/demo/demo-vue1.html new file mode 100644 index 0000000..c15181a --- /dev/null +++ b/demo/demo-vue1.html @@ -0,0 +1,19 @@ + + + + + Vue Tree + + + + +
+

{{title}}

+ +
+ + + + + + \ No newline at end of file diff --git a/demo/demo-vue2.html b/demo/demo-vue2.html new file mode 100644 index 0000000..54e802b --- /dev/null +++ b/demo/demo-vue2.html @@ -0,0 +1,19 @@ + + + + + Vue Tree + + + + +
+

{{title}}

+ +
+ + + + + + \ No newline at end of file diff --git a/demo/demo.js b/demo/demo.js new file mode 100644 index 0000000..3fb5eb7 --- /dev/null +++ b/demo/demo.js @@ -0,0 +1,125 @@ +(function () { + 'use strict'; + var addNode = function (node) { + node.isOpen = true; + node.children.push({ + name: 'child node', + parent: node, + isOpen: true, + isParent: true, + children: [], + buttons: [ + { + title: 'Add', + icon: 'fa fa-plus', + click: addNode + }, { + title: 'Delete', + icon: 'fa fa-trash', + click: function (node) { + node.parent && node.parent.children.$remove(node); + } + } + ] + }); + }; + new Vue({ + el: '#demo', + data: { + title: 'Vue Tree Demo', + option: { + root: { + name: 'Root Node', + isParent: true, + isOpen: true, + openedIcon: 'fa fa-folder-open-o', + closedIcon: 'fa fa-folder-o', + children: [ + { + name: 'Level1' + }, + { + name: 'Level1 with icon', + icon: 'fa fa-cube', + title: '192.168.89.0' + }, + { + name: 'Edit node', + buttons: [ + { + title: 'Edit', + icon: 'fa fa-edit', + click: function (node) { + node.name = prompt('Editing node name, require string', node.name) || node.name; + } + } + ] + }, + { + name: 'Level1 has children', + icon: 'fa fa-folder', + openedIcon: 'fa fa-folder-open', + isOpen: false, + isParent: true, + children: [ + { + name: 'level2 - 1', + icon: 'fa fa-file' + }, + { + name: 'level2 - 2', + icon: 'fa fa-file' + }, + { + name: 'level2 - 3', + icon: 'fa fa-file' + } + ] + }, + { + name: 'Level1 add node', + isOpen: true, + isParent: true, + children: [], + buttons: [ + { + title: 'Add', + icon: 'fa fa-plus', + click: function (node) { + node.isOpen = true; + node.children.push({ + name: 'level2 node', + parent: node, + buttons: [ + { + title: 'Delete', + icon: 'fa fa-trash', + click: function (node) { + node.parent.children.$remove(node); + } + } + ] + }); + } + } + ] + }, + { + name: 'level1-addNode', + isOpen: true, + isParent: true, + children: [], + buttons: [ + { + title: 'Add', + icon: 'fa fa-plus', + click: addNode + } + ] + } + ] + } + } + } + }); +})(); \ No newline at end of file diff --git a/src/tree.vue.css b/src/tree.vue.css new file mode 100644 index 0000000..0dd3ced --- /dev/null +++ b/src/tree.vue.css @@ -0,0 +1,78 @@ +.vue-tree { + font-size: 14px; + min-height: 20px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.vue-tree li { + margin: 0; + padding: 5px; + position: relative; + list-style: none; +} + +.vue-tree li > span, +.vue-tree li > i, +.vue-tree li > a { + line-height: 20px; + vertical-align: middle; +} + +.vue-tree li > a + a { + margin-left: 5px; +} + +.vue-tree li i.icon-open-state { + font-size: 16px; +} + +.vue-tree ul ul li:hover { + background: rgba(0, 0, 0, .015) +} + +.vue-tree li:after, .vue-tree li:before { + content: ''; + left: -18px; + position: absolute; + right: auto +} + +.vue-tree li:before { + border-left: 1px solid #999; + bottom: 50px; + height: 100%; + top: -16px; + width: 1px; +} + +.vue-tree li:after { + border-top: 1px solid #999; + height: 20px; + top: 17px; + width: 22px +} + +.vue-tree li span { + display: inline-block; + padding: 3px 5px; + text-decoration: none; +} + +.vue-tree > ul > li::after, .vue-tree > ul > li:before { + border: 0 +} + +.vue-tree li:last-child::before { + height: 34px +} + +.vue-tree > ul { + padding-left: 0 +} + +.vue-tree ul ul { + padding-left: 24px; + padding-top: 10px +} \ No newline at end of file diff --git a/src/tree.vue.js b/src/tree.vue.js new file mode 100644 index 0000000..abb7b14 --- /dev/null +++ b/src/tree.vue.js @@ -0,0 +1,55 @@ +(function () { + 'use strict'; + var VueTreeItem = Vue.extend({ + template: '
  • ' + + '' + + '' + + ' {{node.name}}' + + '' + + '' + + '
  • ', + props: { + node: { + type: Object + } + }, + methods: { + showIcon: function (node) { + return node.icon || node.openedIcon || node.closedIcon; + }, + nodeClass: function (node) { + if (node.isOpen) { + return node.openedIcon || node.icon; + } else { + return node.closedIcon || node.icon; + } + }, + click: function (node) { + node.isOpen = !node.isOpen; + }, + btnClick: function (btn, node) { + if (typeof btn.click === 'function') { + btn.click(node); + } + } + } + }); + Vue.component('vue-tree-item', VueTreeItem); + + var VueTree = Vue.extend({ + template: '
    ', + props: { + option: { + type: Object + } + }, + components: { + 'tree-item': VueTreeItem + } + }); + Vue.component('vue-tree', VueTree); +})(); \ No newline at end of file