mirror of
https://github.com/weibangtuo/vue-tree.git
synced 2025-12-08 19:46:25 +00:00
First commit
This commit is contained in:
parent
c84d5603d7
commit
3fb6c43e19
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2016 weibt
|
Copyright (c) 2016 weibangtuo
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
69
README.md
Normal file
69
README.md
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# Vue Tree View Component
|
||||||
|
|
||||||
|
Support `Vue.js` 1.0+
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Add the following required resources.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<link rel="stylesheet" href="[You Path]font-awesome/4.+/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="src/tree.vue.css">
|
||||||
|
|
||||||
|
<script src="[You Path]vue.js"></script>
|
||||||
|
<script src="src/tree.vue.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
Add the component in your vue view.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div id="app">
|
||||||
|
<vue-tree :option="option"></vue-tree>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
data: {
|
||||||
|
option: {
|
||||||
|
root: { //Root Node, see Node Options
|
||||||
|
name: 'Root Node',
|
||||||
|
isParent: true,
|
||||||
|
isOpen: true,
|
||||||
|
children: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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.
|
||||||
19
demo/demo-vue1.html
Normal file
19
demo/demo-vue1.html
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Vue Tree</title>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="../src/tree.vue.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="demo">
|
||||||
|
<h1>{{title}}</h1>
|
||||||
|
<vue-tree :option="option"></vue-tree>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.21/vue.js"></script>
|
||||||
|
<script src="../src/tree.vue.js"></script>
|
||||||
|
<script src="demo.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
19
demo/demo-vue2.html
Normal file
19
demo/demo-vue2.html
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Vue Tree</title>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="../src/tree.vue.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="demo">
|
||||||
|
<h1>{{title}}</h1>
|
||||||
|
<vue-tree :option="option"></vue-tree>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
|
||||||
|
<script src="../src/tree.vue.js"></script>
|
||||||
|
<script src="demo.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
125
demo/demo.js
Normal file
125
demo/demo.js
Normal file
@ -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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
78
src/tree.vue.css
Normal file
78
src/tree.vue.css
Normal file
@ -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
|
||||||
|
}
|
||||||
55
src/tree.vue.js
Normal file
55
src/tree.vue.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
var VueTreeItem = Vue.extend({
|
||||||
|
template: '<li :class="{parent_li: node.isParent}">' +
|
||||||
|
'<i v-if="node.isParent" v-on:click="click(node)" class="fa icon-open-state" :class=\'{"fa-plus-square-o": !node.isOpen, "fa-minus-square-o": node.isOpen}\'></i>' +
|
||||||
|
'<span :title="node.title">' +
|
||||||
|
'<i v-if="showIcon(node)" :class="nodeClass(node)"></i> {{node.name}}</span>' +
|
||||||
|
'<a v-for="btn in node.buttons" class="ml5" href="javascript:" :title="btn.title" v-on:click="btnClick(btn, node)"><i :class="btn.icon"></i></a>' +
|
||||||
|
'<ul v-if="node.children && node.children.length" v-show="node.isOpen">' +
|
||||||
|
'<vue-tree-item v-for="item in node.children" :node="item"></vue-tree-item>' +
|
||||||
|
'</ul>' +
|
||||||
|
'</li>',
|
||||||
|
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: '<div class="vue-tree"><ul>' +
|
||||||
|
'<tree-item :node.sync="option.root"></tree-item>' +
|
||||||
|
'</ul></div>',
|
||||||
|
props: {
|
||||||
|
option: {
|
||||||
|
type: Object
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'tree-item': VueTreeItem
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Vue.component('vue-tree', VueTree);
|
||||||
|
})();
|
||||||
Loading…
x
Reference in New Issue
Block a user