init project
This commit is contained in:
10
.babelrc
Normal file
10
.babelrc
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"presets": ["es2015", "stage-2"],
|
||||||
|
"plugins": ["transform-runtime"],
|
||||||
|
"comments": false,
|
||||||
|
"env": {
|
||||||
|
"test": {
|
||||||
|
"plugins": [ "istanbul" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
node_modules
|
||||||
|
npm-debug.log
|
||||||
|
.idea
|
||||||
|
coverage
|
BIN
dist/fonts/fontawesome-webfont.674f50d.eot
vendored
Normal file
BIN
dist/fonts/fontawesome-webfont.674f50d.eot
vendored
Normal file
Binary file not shown.
BIN
dist/fonts/fontawesome-webfont.af7ae50.woff2
vendored
Normal file
BIN
dist/fonts/fontawesome-webfont.af7ae50.woff2
vendored
Normal file
Binary file not shown.
BIN
dist/fonts/fontawesome-webfont.b06871f.ttf
vendored
Normal file
BIN
dist/fonts/fontawesome-webfont.b06871f.ttf
vendored
Normal file
Binary file not shown.
BIN
dist/fonts/fontawesome-webfont.fee66e7.woff
vendored
Normal file
BIN
dist/fonts/fontawesome-webfont.fee66e7.woff
vendored
Normal file
Binary file not shown.
2671
dist/img/fontawesome-webfont.912ec66.svg
vendored
Normal file
2671
dist/img/fontawesome-webfont.912ec66.svg
vendored
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 434 KiB |
26
dist/vue-tree.min.js
vendored
Normal file
26
dist/vue-tree.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
134
examples/demo1.html
Normal file
134
examples/demo1.html
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="with=device-width,initial-scale=1.0,
|
||||||
|
maximum-scale=1.0,minimum-scale=1.0,uses-scalable=no">
|
||||||
|
<title>vue-date-range</title>
|
||||||
|
<link href="https://cdn.bootcss.com/bulma/0.4.2/css/bulma.min.css" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
/*background: linear-gradient(to bottom right, #00ebcb, #dafffa)*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1024px !important;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
background-color: #fff;
|
||||||
|
margin-top: 1rem;
|
||||||
|
/*box-shadow: ;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.date-container, .selected-container {
|
||||||
|
margin: 1rem auto;
|
||||||
|
padding: 0 !important;
|
||||||
|
min-width: 300px;
|
||||||
|
max-width: 400px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column {
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
.control:not(:last-child) {
|
||||||
|
margin-bottom: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-full {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-horizontal {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.date-picker {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.calendar-wrapper {
|
||||||
|
border: 1px solid #bbbbbb;
|
||||||
|
position: absolute;
|
||||||
|
min-width: 300px;
|
||||||
|
max-width: 400px;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
@media all and (max-width: 375px) {
|
||||||
|
.calendar-wrapper {
|
||||||
|
width: 120%;
|
||||||
|
max-width: 120%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mask {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 998;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app" class="wrapper is-fullwidth">
|
||||||
|
<vue-tree :model="data"></vue-tree>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://unpkg.com/vue/dist/vue.js"></script>
|
||||||
|
<script src="../dist/vue-tree.min.js"></script>
|
||||||
|
<script>
|
||||||
|
new Vue({
|
||||||
|
el: '#app',
|
||||||
|
components: {
|
||||||
|
'VueTree': vuetree.VueTree
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
data: new vuetree.Tree([
|
||||||
|
{
|
||||||
|
name: 'Node 1-1',
|
||||||
|
id: 1,
|
||||||
|
pid: 0,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: 'Node 2-1',
|
||||||
|
id: 2,
|
||||||
|
pid: 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Node 1-2',
|
||||||
|
id: 3,
|
||||||
|
pid: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Node 1-3',
|
||||||
|
id: 4,
|
||||||
|
pid: 0
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
70
package.json
Normal file
70
package.json
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
{
|
||||||
|
"name": "vue-tree",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "A vue component for tree structure.",
|
||||||
|
"main": "dist/vue-tree.min.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "karma start --single-run",
|
||||||
|
"unit": "karma start --watch",
|
||||||
|
"coveralls": "npm run test -- --report lcovonly && cat ./coverage/lcov.info | coveralls",
|
||||||
|
"build": "webpack"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/ParadeTo/vue-date-range.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"vue",
|
||||||
|
"datepicker",
|
||||||
|
"date",
|
||||||
|
"range",
|
||||||
|
"moment"
|
||||||
|
],
|
||||||
|
"author": "ayou",
|
||||||
|
"license": "ISC",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/ParadeTo/vue-date-range/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/ParadeTo/vue-date-range#readme",
|
||||||
|
"dependencies": {
|
||||||
|
"font-awesome": "4.7.0",
|
||||||
|
"jquery": "^3.2.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"autoprefixer": "^6.4.0",
|
||||||
|
"babel-core": "^6.0.0",
|
||||||
|
"babel-eslint": "^7.0.0",
|
||||||
|
"babel-loader": "^6.0.0",
|
||||||
|
"babel-plugin-istanbul": "^3.0.0",
|
||||||
|
"babel-plugin-transform-runtime": "^6.0.0",
|
||||||
|
"babel-preset-es2015": "^6.0.0",
|
||||||
|
"babel-preset-stage-2": "^6.0.0",
|
||||||
|
"babel-register": "^6.0.0",
|
||||||
|
"chai": "^3.5.0",
|
||||||
|
"cross-env": "^5.0.1",
|
||||||
|
"css-loader": "^0.26.2",
|
||||||
|
"file-loader": "^0.10.1",
|
||||||
|
"isparta": "^4.0.0",
|
||||||
|
"isparta-loader": "^2.0.0",
|
||||||
|
"karma": "^1.7.0",
|
||||||
|
"karma-coverage": "^1.1.1",
|
||||||
|
"karma-coveralls": "^1.1.2",
|
||||||
|
"karma-mocha": "^1.3.0",
|
||||||
|
"karma-phantomjs-launcher": "^1.0.4",
|
||||||
|
"karma-sinon-chai": "^1.3.1",
|
||||||
|
"karma-webpack": "^2.0.3",
|
||||||
|
"less": "^2.7.2",
|
||||||
|
"less-loader": "^2.2.3",
|
||||||
|
"mocha": "^3.4.2",
|
||||||
|
"phantomjs-prebuilt": "^2.1.14",
|
||||||
|
"sinon": "^2.3.5",
|
||||||
|
"sinon-chai": "^2.11.0",
|
||||||
|
"sourcemap": "^0.1.0",
|
||||||
|
"url-loader": "^0.5.7",
|
||||||
|
"vue": "^2.3.4",
|
||||||
|
"vue-loader": "^11.1.3",
|
||||||
|
"vue-style-loader": "^2.0.3",
|
||||||
|
"vue-template-compiler": "^2.2.0",
|
||||||
|
"webpack": "^1.13.2"
|
||||||
|
}
|
||||||
|
}
|
195
src/Tree.js
Normal file
195
src/Tree.js
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
// used to record treenode's change
|
||||||
|
let Record = {}
|
||||||
|
// treenode's id
|
||||||
|
let nodeId = 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tree data struct
|
||||||
|
* Created by ayou on 2017/7/20.
|
||||||
|
* @param name: treenode's name
|
||||||
|
* @param isLeaf: treenode is leaf node or not
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
const TreeNode = function (name, isLeaf, id) {
|
||||||
|
this.name = name
|
||||||
|
this.id = (typeof id === 'undefined') ? ('new' + nodeId++) : id
|
||||||
|
this.parent = null
|
||||||
|
this.pid = null
|
||||||
|
this.children = null
|
||||||
|
this.isLeaf = !!isLeaf
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeNode.prototype.updateRecordProperty = function () {
|
||||||
|
if (!Record[this.id]) {
|
||||||
|
Record[this.id] = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Record[this.id].name = this.name
|
||||||
|
Record[this.id].id = this.id
|
||||||
|
Record[this.id].pid = this.pid
|
||||||
|
Record[this.id].isLeaf = this.isLeaf
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeNode.prototype.changeName = function (name) {
|
||||||
|
this.name = name
|
||||||
|
|
||||||
|
this.updateRecordProperty()
|
||||||
|
Record[this.id].modify = true
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeNode.prototype.addChildren = function (children, isNew) {
|
||||||
|
if (!this.children) {
|
||||||
|
this.children = []
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(children)) {
|
||||||
|
for (let i = 0, len = children.length; i < len; i++) {
|
||||||
|
const child = children[i]
|
||||||
|
child.parent = this
|
||||||
|
child.pid = this.id
|
||||||
|
|
||||||
|
if (isNew) {
|
||||||
|
child.updateRecordProperty()
|
||||||
|
Record[child.id].add = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.children.concat(children)
|
||||||
|
} else {
|
||||||
|
const child = children
|
||||||
|
child.parent = this
|
||||||
|
child.pid = this.id
|
||||||
|
this.children.push(child)
|
||||||
|
|
||||||
|
if (isNew) {
|
||||||
|
child.updateRecordProperty()
|
||||||
|
Record[child.id].add = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove self
|
||||||
|
TreeNode.prototype.remove = function () {
|
||||||
|
const parent = this.parent
|
||||||
|
const index = parent.findChildIndex(this)
|
||||||
|
parent.children.splice(index, 1)
|
||||||
|
|
||||||
|
this.updateRecordProperty()
|
||||||
|
Record[this.id].remove = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove child
|
||||||
|
TreeNode.prototype._removeChild = function (child) {
|
||||||
|
for (var i = 0, len = this.children.length; i < len; i++) {
|
||||||
|
if (this.children[i] === child) {
|
||||||
|
this.children.splice(i, 1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeNode.prototype.isTargetChild = function (target) {
|
||||||
|
let parent = target.parent
|
||||||
|
while (parent) {
|
||||||
|
if (parent === this) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
parent = parent.parent
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeNode.prototype.moveInto = function (target) {
|
||||||
|
if (this.name === 'root' || this === target) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// cannot move ancestor to child
|
||||||
|
if (this.isTargetChild(target)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.parent._removeChild(this)
|
||||||
|
this.parent = target
|
||||||
|
this.pid = target.id
|
||||||
|
if (!target.children) {
|
||||||
|
target.children = []
|
||||||
|
}
|
||||||
|
target.children.unshift(this)
|
||||||
|
|
||||||
|
this.updateRecordProperty()
|
||||||
|
Record[this.id].targetId = target.id
|
||||||
|
Record[this.id].move = true
|
||||||
|
Record[this.id].moveType = 'inside'
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeNode.prototype.findChildIndex = function (child) {
|
||||||
|
var index
|
||||||
|
for (let i = 0, len = this.children.length; i < len; i++) {
|
||||||
|
if (this.children[i] === child) {
|
||||||
|
index = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeNode.prototype._beforeInsert = function (target) {
|
||||||
|
if (this.name === 'root' || this === target) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// cannot move ancestor to child
|
||||||
|
if (this.isTargetChild(target)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.parent._removeChild(this)
|
||||||
|
this.parent = target.parent
|
||||||
|
this.pid = target.parent.id
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeNode.prototype.insertBefore = function (target) {
|
||||||
|
this._beforeInsert(target)
|
||||||
|
|
||||||
|
const pos = target.parent.findChildIndex(target)
|
||||||
|
target.parent.children.splice(pos, 0, this)
|
||||||
|
|
||||||
|
this.updateRecordProperty()
|
||||||
|
Record[this.id].targetId = target.id
|
||||||
|
Record[this.id].move = true
|
||||||
|
Record[this.id].moveType = 'before'
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeNode.prototype.insertAfter = function (target) {
|
||||||
|
this._beforeInsert(target)
|
||||||
|
|
||||||
|
const pos = target.parent.findChildIndex(target)
|
||||||
|
target.parent.children.splice(pos + 1, 0, this)
|
||||||
|
|
||||||
|
this.updateRecordProperty()
|
||||||
|
Record[this.id].targetId = target.id
|
||||||
|
Record[this.id].move = true
|
||||||
|
Record[this.id].moveType = 'after'
|
||||||
|
}
|
||||||
|
|
||||||
|
function Tree(data) {
|
||||||
|
this.root = new TreeNode('root', false, 0)
|
||||||
|
this.initNode(this.root, data)
|
||||||
|
return this.root
|
||||||
|
}
|
||||||
|
|
||||||
|
Tree.prototype.initNode = function (node, data) {
|
||||||
|
for (let i = 0, len = data.length; i < len; i++) {
|
||||||
|
var _data = data[i]
|
||||||
|
|
||||||
|
var child = new TreeNode(_data.name, _data.attrs, _data.id)
|
||||||
|
if (_data.children && _data.children.length > 0) {
|
||||||
|
this.initNode(child, _data.children)
|
||||||
|
}
|
||||||
|
node.addChildren(child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.Tree = Tree
|
||||||
|
exports.TreeNode = TreeNode
|
||||||
|
exports.Record = Record
|
311
src/VueTree.vue
Normal file
311
src/VueTree.vue
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div v-if="model.name !== 'root'">
|
||||||
|
<div class="border up" :class="{'active': isDragEnterUp}"
|
||||||
|
@drop="dropUp"
|
||||||
|
@dragenter="dragEnterUp"
|
||||||
|
@dragover='dragOverUp'
|
||||||
|
@dragleave="dragLeaveUp"></div>
|
||||||
|
<div class='tree-node' :id='model.id' :class="{'active': isDragEnterNode}"
|
||||||
|
draggable="true"
|
||||||
|
@click=""
|
||||||
|
@dragstart='dragStart'
|
||||||
|
@dragover='dragOver'
|
||||||
|
@dragenter='dragEnter'
|
||||||
|
@dragleave='dragLeave'
|
||||||
|
@drop='drop'
|
||||||
|
@dragend='dragEnd'
|
||||||
|
@mouseover='mouseOver'
|
||||||
|
@mouseout='mouseOut'>
|
||||||
|
<span class="caret icon is-small" v-if="model.children && model.children.length > 0">
|
||||||
|
<i class="vue-tree-icon" :class="caretClass" @click.prevent.stop="toggle"></i>
|
||||||
|
</span>
|
||||||
|
<div class="node-content" v-if="!editable">
|
||||||
|
{{model.name}}
|
||||||
|
</div>
|
||||||
|
<input v-else class="input" type="text" ref="nodeInput" :value="model.name" @input="updateName" @blur="setUnEditable">
|
||||||
|
<div class="operation" v-show="isHover">
|
||||||
|
<span title="add tree node" @click.stop.prevent="addChild(false)" v-if="!model.isLeaf">
|
||||||
|
<slot name="addTreeNode">
|
||||||
|
<i class="vue-tree-icon icon-folder-plus-e"></i>
|
||||||
|
</slot>
|
||||||
|
</span>
|
||||||
|
<span title="add tree node" @click.stop.prevent="addChild(true)" v-if="!model.isLeaf">
|
||||||
|
<slot name="addLeafNode">
|
||||||
|
<i class="vue-tree-icon icon-plus"></i>
|
||||||
|
</slot>
|
||||||
|
</span>
|
||||||
|
<span title="edit" @click.stop.prevent="setEditable">
|
||||||
|
<slot name="edit">
|
||||||
|
<i class="vue-tree-icon icon-edit"></i>
|
||||||
|
</slot>
|
||||||
|
</span>
|
||||||
|
<span title="delete" @click.stop.prevent="delNode">
|
||||||
|
<slot name="edit">
|
||||||
|
<i class="vue-tree-icon icon-trash"></i>
|
||||||
|
</slot>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="model.children && model.children.length > 0 && expanded"
|
||||||
|
class="border bottom"
|
||||||
|
:class="{'active': isDragEnterBottom}"
|
||||||
|
@drop="dropBottom"
|
||||||
|
@dragenter="dragEnterBottom"
|
||||||
|
@dragover='dragOverBottom'
|
||||||
|
@dragleave="dragLeaveBottom"></div>
|
||||||
|
</div>
|
||||||
|
<div :class="{'tree-margin': model.name !== 'root'}" v-show="expanded" v-if="isFolder">
|
||||||
|
<item v-for="model in model.children" :model="model" :key='model.id' :current-highlight='currentHighlight' :default-text='defaultText' :hover-color='hoverColor' :highlight-color='highlightColor'>
|
||||||
|
</item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Tree, TreeNode } from './Tree.js'
|
||||||
|
import $ from 'jquery'
|
||||||
|
|
||||||
|
let fromComp = ''
|
||||||
|
export default {
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
isHover: false,
|
||||||
|
editable: false,
|
||||||
|
isDragEnterUp: false,
|
||||||
|
isDragEnterBottom: false,
|
||||||
|
isDragEnterNode: false,
|
||||||
|
expanded: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
model: Object
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
caretClass () {
|
||||||
|
return this.expanded ? 'icon-caret-down' : 'icon-caret-right'
|
||||||
|
},
|
||||||
|
|
||||||
|
isFolder() {
|
||||||
|
return this.model.children &&
|
||||||
|
this.model.children.length
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
const vm = this
|
||||||
|
$(window).on('keyup', function (e) {
|
||||||
|
// click enter
|
||||||
|
if (e.keyCode === 13 && vm.editable) {
|
||||||
|
vm.editable = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
beforeDestroy () {
|
||||||
|
$(window).off('keyup')
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateName (e) {
|
||||||
|
this.model.changeName(e.target.value)
|
||||||
|
},
|
||||||
|
|
||||||
|
delNode () {
|
||||||
|
const vm = this
|
||||||
|
if (window.confirm('Are you sure?')) {
|
||||||
|
vm.model.remove()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setEditable () {
|
||||||
|
this.editable = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
$(this.$refs.nodeInput).trigger('focus')
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
setUnEditable () {
|
||||||
|
this.editable = false
|
||||||
|
},
|
||||||
|
|
||||||
|
toggle() {
|
||||||
|
if (this.isFolder) {
|
||||||
|
this.expanded = !this.expanded
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mouseOver(e) {
|
||||||
|
this.isHover = true
|
||||||
|
},
|
||||||
|
|
||||||
|
mouseOut(e) {
|
||||||
|
this.isHover = false
|
||||||
|
},
|
||||||
|
|
||||||
|
addChild(isLeaf) {
|
||||||
|
this.expanded = true
|
||||||
|
var node = new TreeNode(name, isLeaf)
|
||||||
|
this.model.addChildren(node, true)
|
||||||
|
},
|
||||||
|
|
||||||
|
dragStart(e) {
|
||||||
|
fromComp = this
|
||||||
|
|
||||||
|
e.dataTransfer.effectAllowed = 'move'
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
dragEnd(e) {
|
||||||
|
fromComp = null
|
||||||
|
},
|
||||||
|
dragOver(e) {
|
||||||
|
e.preventDefault()
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
dragEnter(e) {
|
||||||
|
this.isDragEnterNode = true
|
||||||
|
},
|
||||||
|
dragLeave(e) {
|
||||||
|
this.isDragEnterNode = false
|
||||||
|
},
|
||||||
|
drop(e) {
|
||||||
|
fromComp.model.moveInto(this.model)
|
||||||
|
this.isDragEnterNode = false
|
||||||
|
},
|
||||||
|
|
||||||
|
dragEnterUp () {
|
||||||
|
this.isDragEnterUp = true
|
||||||
|
},
|
||||||
|
dragOverUp (e) {
|
||||||
|
e.preventDefault()
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
dragLeaveUp () {
|
||||||
|
this.isDragEnterUp = false
|
||||||
|
},
|
||||||
|
dropUp () {
|
||||||
|
fromComp.model.insertBefore(this.model)
|
||||||
|
this.isDragEnterUp = false
|
||||||
|
},
|
||||||
|
|
||||||
|
dragEnterBottom () {
|
||||||
|
this.isDragEnterBottom = true
|
||||||
|
},
|
||||||
|
dragOverBottom (e) {
|
||||||
|
e.preventDefault()
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
dragLeaveBottom () {
|
||||||
|
this.isDragEnterBottom = false
|
||||||
|
},
|
||||||
|
dropBottom () {
|
||||||
|
fromComp.model.insertAfter(this.model)
|
||||||
|
this.isDragEnterBottom = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeCreate () {
|
||||||
|
this.$options.components.item = require('./VueTree.vue')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" rel="stylesheet/less" scoped>
|
||||||
|
@font-face {
|
||||||
|
font-family: 'icomoon';
|
||||||
|
src: url('fonts/icomoon.eot?ui1hbx');
|
||||||
|
src: url('fonts/icomoon.eot?ui1hbx#iefix') format('embedded-opentype'),
|
||||||
|
url('fonts/icomoon.ttf?ui1hbx') format('truetype'),
|
||||||
|
url('fonts/icomoon.woff?ui1hbx') format('woff'),
|
||||||
|
url('fonts/icomoon.svg?ui1hbx#icomoon') format('svg');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vue-tree-icon {
|
||||||
|
/* use !important to prevent issues with browser extensions that change fonts */
|
||||||
|
font-family: 'icomoon' !important;
|
||||||
|
speak: none;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
text-transform: none;
|
||||||
|
line-height: 1;
|
||||||
|
|
||||||
|
/* Better Font Rendering =========== */
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
&:hover {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-caret-down:before {
|
||||||
|
content: "\e900";
|
||||||
|
}
|
||||||
|
.icon-caret-right:before {
|
||||||
|
content: "\e901";
|
||||||
|
}
|
||||||
|
.icon-edit:before {
|
||||||
|
content: "\e902";
|
||||||
|
}
|
||||||
|
.icon-folder-plus-e:before {
|
||||||
|
content: "\e903";
|
||||||
|
}
|
||||||
|
.icon-plus:before {
|
||||||
|
content: "\e904";
|
||||||
|
}
|
||||||
|
.icon-trash:before {
|
||||||
|
content: "\e905";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.border {
|
||||||
|
height: 5px;
|
||||||
|
&.up {
|
||||||
|
margin-top: -5px;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
&.bottom {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
border-bottom: 3px dashed blue;
|
||||||
|
/*background-color: blue;*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-node {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 5px 0 5px 1rem;
|
||||||
|
.input {
|
||||||
|
border: none;
|
||||||
|
max-width: 150px;
|
||||||
|
border-bottom: 1px solid blue;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
outline: 2px dashed pink;
|
||||||
|
}
|
||||||
|
.caret {
|
||||||
|
margin-left: -1rem;
|
||||||
|
}
|
||||||
|
/*.fa {*/
|
||||||
|
/*color: #ddd;*/
|
||||||
|
/*&:hover {*/
|
||||||
|
/*color: blue;*/
|
||||||
|
/*}*/
|
||||||
|
/*}*/
|
||||||
|
.operation {
|
||||||
|
margin-left: 2rem;
|
||||||
|
letter-spacing: 1.2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.item {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.tree-margin {
|
||||||
|
margin-left: 2em;
|
||||||
|
}
|
||||||
|
</style>
|
BIN
src/fonts/icomoon.eot
Executable file
BIN
src/fonts/icomoon.eot
Executable file
Binary file not shown.
16
src/fonts/icomoon.svg
Executable file
16
src/fonts/icomoon.svg
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<metadata>Generated by IcoMoon</metadata>
|
||||||
|
<defs>
|
||||||
|
<font id="icomoon" horiz-adv-x="1024">
|
||||||
|
<font-face units-per-em="1024" ascent="960" descent="-64" />
|
||||||
|
<missing-glyph horiz-adv-x="1024" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="512" d="" />
|
||||||
|
<glyph unicode="" glyph-name="caret-down" d="M635.311 448q0-14.848-10.848-25.728l-256-256q-10.848-10.848-25.728-10.848t-25.728 10.848-10.848 25.728v512q0 14.848 10.848 25.728t25.728 10.848 25.728-10.848l256-256q10.848-10.848 10.848-25.728z" />
|
||||||
|
<glyph unicode="" glyph-name="caret-right" d="M512 301.714q-14.848 0-25.746 10.825l-256 256q-10.825 10.825-10.825 25.746t10.825 25.746 25.746 10.825h512q14.848 0 25.746-10.825t10.825-25.746-10.825-25.746l-256-256q-10.825-10.825-25.746-10.825z" />
|
||||||
|
<glyph unicode="" glyph-name="edit" d="M816.001 594.256c-11.151 0-20.203-9.053-20.203-20.201v-363.665c0-22.31-18.089-40.402-40.401-40.402h-505.083c-22.318 0-40.405 18.093-40.405 40.402v505.086c0 22.317 18.094 40.401 40.405 40.401h343.46c11.168 0 20.2 9.038 20.2 20.204 0 11.161-9.036 20.201-20.2 20.201h-363.675c-33.483 0-60.612-27.136-60.612-60.61v-545.494c0-33.481 27.13-60.612 60.612-60.612h545.494c33.482 0 60.613 27.133 60.613 60.612v383.877c-0.004 11.148-9.040 20.201-20.205 20.201zM417.158 397.194c7.893-7.868 20.674-7.868 28.572 0l363.068 365.049c7.889 7.894 7.889 20.689 0 28.572-7.89 7.893-20.678 7.893-28.563 0l-363.077-365.035c-7.897-7.891-7.897-20.692 0-28.586z" />
|
||||||
|
<glyph unicode="" glyph-name="folder-plus-e" d="M946.471 884.169h-548.426l-42.856 51.918c-17.498 21.394-39.525 25.1-46.676 23.629h-230.922c-42.788 0-77.591-34.803-77.591-77.525v-688.284l6.327-39.784h19.857c10.467-7.603 23.121-11.751 36.469-11.751h509.37v65.392h-494.433l-12.194-1.020v675.448c0 6.704 5.486 12.133 12.194 12.133l227.025 0.256 43.551-52.108c6.96-11.43 22.799-23.693 46.424-23.693h551.88c6.709 0 12.133-5.49 12.133-12.198v-202.19h65.397v202.189c0 42.787-34.803 77.589-77.529 77.589zM988.451 391.215h-142.197v142.197c0 19.65-15.9 35.549-35.549 35.549s-35.549-15.9-35.549-35.549v-142.197h-142.197c-19.65 0-35.549-15.9-35.549-35.549s15.9-35.549 35.549-35.549h142.197v-142.197c0-19.65 15.9-35.549 35.549-35.549s35.549 15.9 35.549 35.549v142.197h142.197c19.65 0 35.549 15.9 35.549 35.549s-15.9 35.549-35.549 35.549z" />
|
||||||
|
<glyph unicode="" glyph-name="plus" d="M863.328 478.66l-317.344-0.1v318.622c0 17.665-14.336 32.001-32 32.001s-32-14.336-32-32v-318.401l-322.465 0.177c-17.632 0-31.935-14.24-32-31.904-0.097-17.665 14.208-32.032 31.871-32.096l322.593-0.177v-319.167c0-17.696 14.336-32.001 31.999-32.001s32 14.303 32 32v318.946l317.216 0.1c17.632 0 31.935 14.24 32 31.905s-14.238 32.031-31.87 32.095z" />
|
||||||
|
<glyph unicode="" glyph-name="trash" d="M607.904 191.952c-17.712 0-32 14.288-32 32v352.112c0 17.712 14.288 32 32 32s31.984-14.288 31.984-32v-351.936c0-0.033 0-0.073 0-0.112 0-17.68-14.31-32.019-31.98-32.064h-0.004zM415.936 191.952c-17.712 0-32 14.288-32 32v352.112c0 17.712 14.272 32 32 32s32-14.288 32-32v-351.936c0-0.024 0-0.052 0-0.080 0-17.692-14.315-32.041-31.995-32.096h-0.005zM928.016 736.032h-159.968v63.984c0 52.992-42.672 95.984-95.296 95.984h-320.816c-52.999-0.027-95.957-42.984-95.984-95.981v-63.987h-159.968c-17.712 0-32-14.288-32-32s14.272-32 32-32h832.032c0.014 0 0.031 0 0.048 0 17.638 0 31.936 14.298 31.936 31.936 0 0.023 0 0.045 0 0.068v-0.004c0 17.728-14.272 32-31.984 32zM319.952 800.016c0 17.552 14.448 32 32 32h320.816c17.536 0 31.312-14.112 31.312-32v-63.984h-384.128v63.984zM736.048 0h-447.92c-53.001 0.009-95.966 42.968-95.984 95.966v480.434c0 17.712 14.272 32 32 32s32-14.288 32-32v-480.432c0-17.712 14.448-32 32-32h448.096c17.712 0 32 14.288 32 32v479.232c0 17.712 14.288 32 32 32s31.984-14.288 31.984-32v-479.232c-0.192-52.816-43.2-95.968-96.176-95.968z" />
|
||||||
|
</font></defs></svg>
|
After Width: | Height: | Size: 3.9 KiB |
BIN
src/fonts/icomoon.ttf
Executable file
BIN
src/fonts/icomoon.ttf
Executable file
Binary file not shown.
BIN
src/fonts/icomoon.woff
Executable file
BIN
src/fonts/icomoon.woff
Executable file
Binary file not shown.
7
src/index.js
Normal file
7
src/index.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* Created by ayou on 17/7/21.
|
||||||
|
*/
|
||||||
|
exports.VueTree = require('./VueTree.vue')
|
||||||
|
exports.TreeNode = require('./Tree.js').TreeNode
|
||||||
|
exports.Tree = require('./Tree.js').Tree
|
||||||
|
exports.Record = require('./Tree.js').Record
|
51
webpack.config.js
Normal file
51
webpack.config.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
var webpack = require('webpack');
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: './src/index.js',
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, 'dist'),
|
||||||
|
filename: 'vue-tree.min.js',
|
||||||
|
library: 'vuetree',
|
||||||
|
libraryTarget: 'umd'
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
loaders: [
|
||||||
|
{
|
||||||
|
test: /\.vue$/,
|
||||||
|
loader: 'vue'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
loader: 'babel',
|
||||||
|
include: [path.join(__dirname, 'src')],
|
||||||
|
exclude: /node_modules/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(woff2?|eot|ttf|otf|svg)(\?.*)?$/,
|
||||||
|
loader: 'url-loader',
|
||||||
|
query: {
|
||||||
|
limit: 10000,
|
||||||
|
name: 'fonts/[name].[hash:7].[ext]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
vue: {
|
||||||
|
loaders: {
|
||||||
|
less: 'vue-style!css!less'
|
||||||
|
},
|
||||||
|
postcss: [
|
||||||
|
require('autoprefixer')({
|
||||||
|
browsers: ['iOS >= 7', 'Android >= 4.1']
|
||||||
|
})
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.optimize.UglifyJsPlugin({
|
||||||
|
compress: {
|
||||||
|
warnings: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}
|
Reference in New Issue
Block a user