| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- <template>
- <div class="tree-node-container" :style="containerStyle" ref="node">
- <div class="tree-node" :style="cardStyle" @click="nodeClick(id)">
- <ElCard class="tree-node-card" shadow="hover">
- <template #header>
- <div class="card-header">
- <span class="node-title">{{title}}</span>
- <ElTag class="node-state" :type="getTagTypeFromState(state)">{{state}}</ElTag>
- </div>
- </template>
- <div class="card-body">
- <PriorityTag :size="'mini'" :priority="priority"></PriorityTag>
- <ElTag size="mini" >{{processor}}</ElTag>
- </div>
- </ElCard>
- </div>
- <div class="node-postfix">
- <template v-if="depth!==1">
- <div class="icon" target="delete" @click="deleteNode(id)"></div>
- </template>
- <template v-if="depth!==4">
- <div class="icon" target="add" @click="addChild(id)"></div>
- </template>
- </div>
- </div>
- </template>
- <script>
- import PriorityTag from '@/components/PriorityTag.vue';
- const getTagTypeFromState = (state) => {
- if (state === '已创建') {
- return '';
- } if (state === '进行中') {
- return 'success';
- } if (state === '已完成' || state === '已结束') {
- return 'info';
- }
- return 'danger';
- };
- export default {
- name: 'TreeNode',
- components: { PriorityTag },
- props: {
- id: Number,
- state: String,
- title: String,
- positionY: Number,
- positionX: Number,
- nodeStyle: Object,
- depth: Number,
- processor: String,
- priority: String,
- },
- computed: {
- containerStyle() {
- return {
- top: `${this.positionY * 180}px`,
- left: `${280 * this.positionX - 100}px`,
- width: `${this.nodeStyle.width + this.nodeStyle.padding * 2}px`,
- height: `${this.nodeStyle.height + this.nodeStyle.padding * 2}px`,
- };
- },
- cardStyle() {
- return {
- width: `${this.nodeStyle.width}px`,
- height: `${this.nodeStyle.height}px`,
- };
- },
- },
- methods: {
- getTagTypeFromState,
- getTreeNodeSizeAndPosition() {
- return {
- top: this.$refs.node.offsetTop + this.nodeStyle.padding,
- left: this.$refs.node.offsetLeft + this.nodeStyle.padding,
- height: this.nodeStyle.height,
- width: this.nodeStyle.width,
- };
- },
- addChild(id) {
- this.$emit('add-child', id);
- },
- deleteNode(id) {
- this.$emit('delete-node', id);
- },
- nodeClick(id) {
- this.$emit('node-click', id);
- },
- },
- };
- </script>
- <style lang="scss" scoped>
- .tree-node-container {
- position: absolute;
- box-sizing: border-box;
- display: flex;
- justify-content: center;
- align-items: center;
- user-select: none;
- & .node-postfix {
- position: absolute;
- bottom: 10px;
- right: 25px;
- width: 100%;
- display: none;
- }
- &:hover .node-postfix {
- display: block;
- }
- }
- .tree-node {
- box-sizing: border-box;
- }
- .card-header {
- display: flex;
- justify-content: space-between;
- }
- .card-body{
- display: flex;
- justify-content: space-between;
- }
- .icon {
- width: 14px;
- height: 14px;
- float: right;
- background-position: center;
- background-repeat: no-repeat;
- background-size: 100% 100%;
- margin-top: 10px;
- margin-right: 10px;
- transition: all .2s linear;
- }
- .icon:hover{
- cursor: pointer;
- transition-duration: 0.2s;
- transform: scale(1.1);
- transition-timing-function:ease-in-out;
- }
- .icon[target=add]{
- background-image: url("../assets/icon/add.svg");
- }
- .icon[target=delete]{
- background-image: url("../assets/icon/delete.svg");
- }
- </style>
|