Compare commits
11 Commits
feature-co
...
dependabot
Author | SHA1 | Date | |
---|---|---|---|
![]() |
821851e1ed | ||
![]() |
5500a36492 | ||
![]() |
66bc19baaa | ||
![]() |
97daf67f9a | ||
![]() |
d1e12aad85 | ||
![]() |
d5dd9b88c9 | ||
![]() |
ccb1067713 | ||
![]() |
d5705f92e8 | ||
![]() |
ae494ce25f | ||
![]() |
c59015fdf7 | ||
![]() |
5f94ebf51b |
32
dev/App.vue
32
dev/App.vue
@@ -14,6 +14,11 @@
|
||||
default-leaf-node-name="new leaf"
|
||||
v-bind:default-expanded="false"
|
||||
>
|
||||
<template v-slot:leafNameDisplay="slotProps">
|
||||
<span>
|
||||
{{ slotProps.model.name }} <span class="muted">#{{ slotProps.model.id }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<template v-slot:addTreeNodeIcon="slotProps">
|
||||
<span class="icon">📂</span>
|
||||
</template>
|
||||
@@ -31,18 +36,22 @@
|
||||
</template>
|
||||
<template v-slot:treeNodeIcon="slotProps">
|
||||
<span class="icon">
|
||||
{{ (slotProps.model.children && slotProps.model.children.length > 0 && !slotProps.expanded) ? '🌲' : '' }}</span>
|
||||
{{
|
||||
slotProps.model.children && slotProps.model.children.length > 0 && !slotProps.expanded
|
||||
? '🌲'
|
||||
: ''
|
||||
}}</span
|
||||
>
|
||||
</template>
|
||||
</vue-tree-list>
|
||||
<button @click="getNewTree">Get new tree</button>
|
||||
<pre>
|
||||
{{ newTree }}
|
||||
</pre
|
||||
>
|
||||
{{ newTree }}
|
||||
</pre>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {VueTreeList, Tree, TreeNode} from '../src'
|
||||
import { VueTreeList, Tree, TreeNode } from '../src'
|
||||
export default {
|
||||
components: {
|
||||
VueTreeList
|
||||
@@ -105,23 +114,23 @@ export default {
|
||||
console.log(params)
|
||||
},
|
||||
|
||||
drop: function({node, src, target}) {
|
||||
drop: function({ node, src, target }) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('drop', node, src, target)
|
||||
},
|
||||
|
||||
dropBefore: function({node, src, target}) {
|
||||
dropBefore: function({ node, src, target }) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('drop-before', node, src, target)
|
||||
},
|
||||
|
||||
dropAfter: function({node, src, target}) {
|
||||
dropAfter: function({ node, src, target }) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('drop-after', node, src, target)
|
||||
},
|
||||
|
||||
addNode() {
|
||||
var node = new TreeNode({name: 'new node', isLeaf: false})
|
||||
var node = new TreeNode({ name: 'new node', isLeaf: false })
|
||||
if (!this.data.children) this.data.children = []
|
||||
this.data.addChildren(node)
|
||||
},
|
||||
@@ -171,4 +180,9 @@ export default {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.muted {
|
||||
color: gray;
|
||||
font-size: 80%;
|
||||
}
|
||||
</style>
|
||||
|
14
package-lock.json
generated
14
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vue-tree-list",
|
||||
"version": "1.4.3",
|
||||
"version": "1.4.6",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -893,9 +893,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@hapi/hoek": {
|
||||
"version": "8.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.0.tgz",
|
||||
"integrity": "sha512-7XYT10CZfPsH7j9F1Jmg1+d0ezOux2oM2GfArAzLwWe4mE2Dr3hVjsAL6+TFY49RRJlCdJDMw3nJsLFroTc8Kw==",
|
||||
"version": "8.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz",
|
||||
"integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==",
|
||||
"dev": true
|
||||
},
|
||||
"@hapi/joi": {
|
||||
@@ -2405,7 +2405,7 @@
|
||||
},
|
||||
"util": {
|
||||
"version": "0.10.3",
|
||||
"resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
|
||||
"integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -3340,7 +3340,7 @@
|
||||
"dependencies": {
|
||||
"callsites": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "http://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
|
||||
"integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
|
||||
"dev": true
|
||||
}
|
||||
@@ -12326,7 +12326,7 @@
|
||||
"dependencies": {
|
||||
"jsesc": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
|
||||
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
|
||||
"dev": true
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vue-tree-list",
|
||||
"version": "1.4.3",
|
||||
"version": "1.4.6",
|
||||
"description": "A vue component for tree structure. Support adding treenode/leafnode, editing node's name and dragging.",
|
||||
"author": "ayou",
|
||||
"scripts": {
|
||||
|
118
readme.md
118
readme.md
@@ -1,6 +1,7 @@
|
||||
[](https://github.com/ParadeTo/vue-tree-list/actions)
|
||||
|
||||
# vue-tree-list
|
||||
|
||||
A vue component for tree structure. Support adding treenode/leafnode, editing node's name and dragging.
|
||||
|
||||

|
||||
@@ -21,7 +22,8 @@ Vue.use(VueTreeList)
|
||||
Or just register locally like the example below.
|
||||
|
||||
# use
|
||||
``npm install vue-tree-list``
|
||||
|
||||
`npm install vue-tree-list`
|
||||
|
||||
```html
|
||||
<template>
|
||||
@@ -35,7 +37,13 @@ Or just register locally like the example below.
|
||||
:model="data"
|
||||
default-tree-node-name="new node"
|
||||
default-leaf-node-name="new leaf"
|
||||
v-bind:default-expanded="false">
|
||||
v-bind:default-expanded="false"
|
||||
>
|
||||
<template v-slot:leafNameDisplay="slotProps">
|
||||
<span>
|
||||
{{ slotProps.model.name }} <span class="muted">#{{ slotProps.model.id }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<span class="icon" slot="addTreeNodeIcon">📂</span>
|
||||
<span class="icon" slot="addLeafNodeIcon">+</span>
|
||||
<span class="icon" slot="editNodeIcon">📃</span>
|
||||
@@ -56,7 +64,7 @@ Or just register locally like the example below.
|
||||
components: {
|
||||
VueTreeList
|
||||
},
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
newTree: {},
|
||||
data: new Tree([
|
||||
@@ -93,32 +101,32 @@ Or just register locally like the example below.
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onDel (node) {
|
||||
onDel(node) {
|
||||
console.log(node)
|
||||
node.remove()
|
||||
},
|
||||
|
||||
onChangeName (params) {
|
||||
onChangeName(params) {
|
||||
console.log(params)
|
||||
},
|
||||
|
||||
onAddNode (params) {
|
||||
onAddNode(params) {
|
||||
console.log(params)
|
||||
},
|
||||
|
||||
onClick (params) {
|
||||
onClick(params) {
|
||||
console.log(params)
|
||||
},
|
||||
|
||||
addNode () {
|
||||
addNode() {
|
||||
var node = new TreeNode({ name: 'new node', isLeaf: false })
|
||||
if (!this.data.children) this.data.children = []
|
||||
this.data.addChildren(node)
|
||||
},
|
||||
|
||||
getNewTree () {
|
||||
getNewTree() {
|
||||
var vm = this
|
||||
function _dfs (oldNode) {
|
||||
function _dfs(oldNode) {
|
||||
var newNode = {}
|
||||
|
||||
for (var k in oldNode) {
|
||||
@@ -137,8 +145,7 @@ Or just register locally like the example below.
|
||||
}
|
||||
|
||||
vm.newTree = _dfs(vm.data)
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -163,58 +170,71 @@ Or just register locally like the example below.
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
.muted {
|
||||
color: gray;
|
||||
font-size: 80%;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
# props
|
||||
## props of vue-tree-list
|
||||
| name | type | default | description |
|
||||
|:-----:|:-------:|:------------:|:----:|
|
||||
model | TreeNode | - | You can use `const head = new Tree([])` to generate a tree with the head of `TreeNode` type
|
||||
default-tree-node-name | string | New node node | Default name for new treenode
|
||||
default-leaf-node-name | string | New leaf node | Default name for new leafnode
|
||||
default-expanded | boolean | true | Tree is expanded or not
|
||||
|
||||
## props of vue-tree-list
|
||||
|
||||
| name | type | default | description |
|
||||
| :--------------------: | :------: | :-----------: | :-----------------------------------------------------------------------------------------: |
|
||||
| model | TreeNode | - | You can use `const head = new Tree([])` to generate a tree with the head of `TreeNode` type |
|
||||
| default-tree-node-name | string | New node node | Default name for new treenode |
|
||||
| default-leaf-node-name | string | New leaf node | Default name for new leafnode |
|
||||
| default-expanded | boolean | true | Tree is expanded or not |
|
||||
|
||||
## props of TreeNode
|
||||
|
||||
### attributes
|
||||
| name | type | default | description |
|
||||
|:-----:|:-------:|:------------:|:----:|
|
||||
id | string, number | current timestamp | The node's id
|
||||
isLeaf | boolean | false | The node is leaf or not
|
||||
dragDisabled | boolean | false | Forbid dragging tree node
|
||||
addTreeNodeDisabled | boolean | false | Show `addTreeNode` button or not
|
||||
addLeafNodeDisabled | boolean | false | Show `addLeafNode` button or not
|
||||
editNodeDisabled | boolean | false | Show `editNode` button or not
|
||||
delNodeDisabled | boolean | false | Show `delNode` button or not
|
||||
children | array | null | The children of node
|
||||
|
||||
| name | type | default | description |
|
||||
| :-----------------: | :------------: | :---------------: | :------------------------------: |
|
||||
| id | string, number | current timestamp | The node's id |
|
||||
| isLeaf | boolean | false | The node is leaf or not |
|
||||
| dragDisabled | boolean | false | Forbid dragging tree node |
|
||||
| addTreeNodeDisabled | boolean | false | Show `addTreeNode` button or not |
|
||||
| addLeafNodeDisabled | boolean | false | Show `addLeafNode` button or not |
|
||||
| editNodeDisabled | boolean | false | Show `editNode` button or not |
|
||||
| delNodeDisabled | boolean | false | Show `delNode` button or not |
|
||||
| children | array | null | The children of node |
|
||||
|
||||
### methods
|
||||
| name | params | description |
|
||||
|:-----:|:-------:|:----:|
|
||||
changeName | name | Change node's name
|
||||
addChildren | children: object, array | Add children to node
|
||||
remove | - | Remove node from the tree
|
||||
moveInto | target: TreeNode | Move node into another node
|
||||
insertBefore | target: TreeNode | Move node before another node
|
||||
insertAfter | target: TreeNode | Move node after another node
|
||||
|
||||
| name | params | description |
|
||||
| :----------: | :---------------------: | :---------------------------: |
|
||||
| changeName | name | Change node's name |
|
||||
| addChildren | children: object, array | Add children to node |
|
||||
| remove | - | Remove node from the tree |
|
||||
| moveInto | target: TreeNode | Move node into another node |
|
||||
| insertBefore | target: TreeNode | Move node before another node |
|
||||
| insertAfter | target: TreeNode | Move node after another node |
|
||||
|
||||
# events
|
||||
| name | params | description |
|
||||
|:-----:|:-------:|:----:|
|
||||
click | TreeNode | Trigger when clicking a tree node
|
||||
change-name | {'id', 'oldName', 'newName'} | Trigger after changing a node's name
|
||||
delete-node | TreeNode | Trigger when clicking `delNode` button. You can call `remove` of `TreeNode` to remove the node.
|
||||
add-node | TreeNode | Trigger after adding a new node
|
||||
drop | {node, src, target} | Trigger after dropping a node into another. node: the draggable node, src: the draggable node's parent, target: the node that draggable node will drop into
|
||||
drop-before | {node, src, target} | Trigger after dropping a node before another. node: the draggable node, src: the draggable node's parent, target: the node that draggable node will drop before
|
||||
drop-after | {node, src, target} | Trigger after dropping a node after another. node: the draggable node, src: the draggable node's parent, target: the node that draggable node will drop after
|
||||
|
||||
| name | params | description |
|
||||
| :---------: | :--------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------: |
|
||||
| click | TreeNode | Trigger when clicking a tree node |
|
||||
| change-name | {'id', 'oldName', 'newName'} | Trigger after changing a node's name |
|
||||
| delete-node | TreeNode | Trigger when clicking `delNode` button. You can call `remove` of `TreeNode` to remove the node. |
|
||||
| add-node | TreeNode | Trigger after adding a new node |
|
||||
| drop | {node, src, target} | Trigger after dropping a node into another. node: the draggable node, src: the draggable node's parent, target: the node that draggable node will drop into |
|
||||
| drop-before | {node, src, target} | Trigger after dropping a node before another. node: the draggable node, src: the draggable node's parent, target: the node that draggable node will drop before |
|
||||
| drop-after | {node, src, target} | Trigger after dropping a node after another. node: the draggable node, src: the draggable node's parent, target: the node that draggable node will drop after |
|
||||
|
||||
# customize operation icons
|
||||
|
||||
The component has default icons for `addTreeNodeIcon`, `addLeafNodeIcon`, `editNodeIcon`, `delNodeIcon`, `leafNodeIcon`, `treeNodeIcon` button, but you can also customize them and can access `model`, `root`, `expanded` as below:
|
||||
|
||||
```html
|
||||
<template v-slot:leafNameDisplay="slotProps">
|
||||
<span>{{ slotProps.model.name }} #{{ slotProps.model.id }}</span>
|
||||
</template>
|
||||
<template v-slot:addTreeNodeIcon="slotProps">
|
||||
<span class="icon">📂</span>
|
||||
</template>
|
||||
@@ -232,6 +252,8 @@ The component has default icons for `addTreeNodeIcon`, `addLeafNodeIcon`, `editN
|
||||
</template>
|
||||
<template v-slot:treeNodeIcon="slotProps">
|
||||
<span class="icon">
|
||||
{{ (slotProps.model.children && slotProps.model.children.length > 0 && !slotProps.expanded) ? '🌲' : '' }}</span>
|
||||
{{ (slotProps.model.children && slotProps.model.children.length > 0 && !slotProps.expanded) ?
|
||||
'🌲' : '' }}</span
|
||||
>
|
||||
</template>
|
||||
```
|
||||
|
@@ -43,7 +43,9 @@
|
||||
</span>
|
||||
|
||||
<div class="vtl-node-content" v-if="!editable">
|
||||
{{ model.name }}
|
||||
<slot name="leafNameDisplay" :expanded="expanded" :model="model" :root="rootNode">
|
||||
{{ model.name }}
|
||||
</slot>
|
||||
</div>
|
||||
<input
|
||||
v-else
|
||||
@@ -110,6 +112,9 @@
|
||||
:model="model"
|
||||
:key="model.id"
|
||||
>
|
||||
<template v-slot:leafNameDisplay="slotProps">
|
||||
<slot name="leafNameDisplay" v-bind="slotProps" />
|
||||
</template>
|
||||
<template v-slot:addTreeNodeIcon="slotProps">
|
||||
<slot name="addTreeNodeIcon" v-bind="slotProps" />
|
||||
</template>
|
||||
@@ -221,7 +226,8 @@ export default {
|
||||
this.rootNode.$emit('change-name', {
|
||||
id: this.model.id,
|
||||
oldName: oldName,
|
||||
newName: e.target.value
|
||||
newName: e.target.value,
|
||||
node: this.model
|
||||
})
|
||||
},
|
||||
|
||||
@@ -238,8 +244,16 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
setUnEditable() {
|
||||
setUnEditable(e) {
|
||||
this.editable = false
|
||||
var oldName = this.model.name
|
||||
this.model.changeName(e.target.value)
|
||||
this.rootNode.$emit('change-name', {
|
||||
id: this.model.id,
|
||||
oldName: oldName,
|
||||
newName: e.target.value,
|
||||
eventType: 'blur'
|
||||
})
|
||||
},
|
||||
|
||||
toggle() {
|
||||
@@ -287,6 +301,7 @@ export default {
|
||||
return true
|
||||
},
|
||||
dragEnter() {
|
||||
if (!compInOperation) return
|
||||
if (compInOperation.model.id === this.model.id || !compInOperation || this.model.isLeaf)
|
||||
return
|
||||
this.isDragEnterNode = true
|
||||
|
Reference in New Issue
Block a user