mirror of
https://github.com/weibangtuo/vue-tree.git
synced 2025-12-08 19:46:25 +00:00
Support asynchronous loading tree data
This commit is contained in:
parent
3fb6c43e19
commit
26e0197365
25
README.md
25
README.md
@ -38,26 +38,31 @@ Add the component in your vue view.
|
|||||||
|
|
||||||
## Node Options
|
## Node Options
|
||||||
|
|
||||||
|
`[opt]` means optional property.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
{
|
{
|
||||||
name: 'Node Name',
|
name: 'Node Name',
|
||||||
title: 'Node Tag title attr',
|
title: 'Node Tag title attr',
|
||||||
isParent: true, //
|
isParent: true, // Requested for parent node
|
||||||
isOpen: true, // Control node to fold or unfold
|
isOpen: false, // [opt] Control node to fold or unfold
|
||||||
icon: 'fa fa-folder', // Or other custom icons call by class name
|
icon: 'fa fa-folder', //[opt] Icon class name
|
||||||
openedIcon: 'fa fa-folder-open', // [option] For parent. Show when isOpen == true, show icon if it's null or empty
|
openedIcon: 'fa fa-folder-open', // [opt] 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
|
closedIcon: 'fa fa-folder', // [opt] For parent. Show when isOpen != true, show icon if it's null or empty
|
||||||
children: [], // for parent node only
|
children: [], // Requested for parent node
|
||||||
buttons: [ // []
|
buttons: [ // [opt]
|
||||||
{
|
{
|
||||||
title: 'icon button tag title attr', //[option]
|
title: 'icon button tag title attr', //[opt]
|
||||||
icon: 'fa fa-edit',
|
icon: 'fa fa-edit',
|
||||||
click: function (node) { //[option]
|
click: function (node) { //[opt]
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//...
|
//...
|
||||||
]
|
],
|
||||||
|
showLoading: false, // [opt] For parent, when `node.showLoading && node._loading` and node is opened then show loading icon
|
||||||
|
onOpened: function (node) {}, // [opt]
|
||||||
|
onClosed: function (node) {} // [opt]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
28
demo/demo.js
28
demo/demo.js
@ -5,7 +5,6 @@
|
|||||||
node.children.push({
|
node.children.push({
|
||||||
name: 'child node',
|
name: 'child node',
|
||||||
parent: node,
|
parent: node,
|
||||||
isOpen: true,
|
|
||||||
isParent: true,
|
isParent: true,
|
||||||
children: [],
|
children: [],
|
||||||
buttons: [
|
buttons: [
|
||||||
@ -78,7 +77,6 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Level1 add node',
|
name: 'Level1 add node',
|
||||||
isOpen: true,
|
|
||||||
isParent: true,
|
isParent: true,
|
||||||
children: [],
|
children: [],
|
||||||
buttons: [
|
buttons: [
|
||||||
@ -88,7 +86,7 @@
|
|||||||
click: function (node) {
|
click: function (node) {
|
||||||
node.isOpen = true;
|
node.isOpen = true;
|
||||||
node.children.push({
|
node.children.push({
|
||||||
name: 'level2 node',
|
name: 'Level2 node',
|
||||||
parent: node,
|
parent: node,
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
@ -105,8 +103,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'level1-addNode',
|
name: 'Level1-addNode',
|
||||||
isOpen: true,
|
|
||||||
isParent: true,
|
isParent: true,
|
||||||
children: [],
|
children: [],
|
||||||
buttons: [
|
buttons: [
|
||||||
@ -116,6 +113,27 @@
|
|||||||
click: addNode
|
click: addNode
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Level1 Ajax',
|
||||||
|
isParent: true,
|
||||||
|
children: [],
|
||||||
|
showLoading: true, // if (node.showLoading && node._loading) then show loading icon
|
||||||
|
onOpened: function (node) {
|
||||||
|
if (!node._loading) {
|
||||||
|
Vue.set(node, 'children', []); // Clean old data
|
||||||
|
node._loading = true; // Start Ajax
|
||||||
|
setTimeout(function () { //
|
||||||
|
node._loading = false; //Finish Ajax
|
||||||
|
for (var i = 1; i < 6; i++) {
|
||||||
|
node.children.push({name: 'Ajax Node ' + i});
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onClosed: function () {
|
||||||
|
// NOOP
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,11 +2,12 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
var VueTreeItem = Vue.extend({
|
var VueTreeItem = Vue.extend({
|
||||||
template: '<li :class="{parent_li: node.isParent}">' +
|
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>' +
|
'<i v-if="node.isParent" v-on:click="toggle(node)" class="fa icon-open-state" :class=\'{"fa-plus-square-o": !node.isOpen, "fa-minus-square-o": node.isOpen}\'></i>' +
|
||||||
'<span :title="node.title">' +
|
'<span :title="node.title">' +
|
||||||
'<i v-if="showIcon(node)" :class="nodeClass(node)"></i> {{node.name}}</span>' +
|
'<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>' +
|
'<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">' +
|
'<ul v-show="node.isOpen">' +
|
||||||
|
'<li v-show="node.showLoading && node._loading"><i class="fa fa-spinner fa-pulse"></i></li>' +
|
||||||
'<vue-tree-item v-for="item in node.children" :node="item"></vue-tree-item>' +
|
'<vue-tree-item v-for="item in node.children" :node="item"></vue-tree-item>' +
|
||||||
'</ul>' +
|
'</ul>' +
|
||||||
'</li>',
|
'</li>',
|
||||||
@ -26,14 +27,34 @@
|
|||||||
return node.closedIcon || node.icon;
|
return node.closedIcon || node.icon;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
click: function (node) {
|
toggle: function (node) {
|
||||||
|
if (node.hasOwnProperty('isOpen')) {
|
||||||
node.isOpen = !node.isOpen;
|
node.isOpen = !node.isOpen;
|
||||||
|
} else {
|
||||||
|
Vue.set(node, 'isOpen', true);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
btnClick: function (btn, node) {
|
btnClick: function (btn, node) {
|
||||||
if (typeof btn.click === 'function') {
|
if (typeof btn.click === 'function') {
|
||||||
btn.click(node);
|
btn.click(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'node.isOpen': function (val) {
|
||||||
|
if (!this.node.hasOwnProperty('_loading')) {
|
||||||
|
Vue.set(this.node, '_loading', false);
|
||||||
|
}
|
||||||
|
if (val) {
|
||||||
|
if (typeof this.node.onOpened === 'function') {
|
||||||
|
this.node.onOpened(this.node);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (typeof this.node.onClosed === 'function') {
|
||||||
|
this.node.onClosed(this.node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Vue.component('vue-tree-item', VueTreeItem);
|
Vue.component('vue-tree-item', VueTreeItem);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user