awesome-minder

1.1.2 • Public • Published

基于 vue2 制作的脑图组件

安装

npm install awesome-minder

使用

import Vue from 'vue';
import AwesomeMinder from 'awesome-minder';
Vue.use(AwesomeMinder);
<template>
  <div style="width: 98vw; height: 96vh" ref="demoWrapper">
    <awesome-minder
      :sourceData="sourceData"
      :renderContent="renderContent"
      ref="minderRef"
      @contextmenu="handleMenu"
      @node:select="handleNodeSelect"
    >
      <template #navbar>
        <div class="navbar">
          <div class="iconfont-wrapper" :class="[{ active: expandAll }]" @click="toggleExpandAll">
            <i class="iconfont icon-a-icon-quanbuzhankaizhedie"></i>
          </div>
          <div
            class="iconfont-wrapper"
            :class="[{ active: nodeExpanded, disabled: nodeExpandDisabled }]"
            @click="toggleNodeExpand"
          >
            <i class="iconfont icon-a-icon-tongjizhankaizhedie"></i>
          </div>
          <div class="iconfont-wrapper" @click="centerContent">
            <i class="iconfont icon-icon-dingweijuzhong"></i>
          </div>
          <div class="iconfont-wrapper" @click="zoomIn">
            <i class="iconfont icon-icon-fangda"></i>
          </div>
          <div class="iconfont-wrapper" @click="zoomOut">
            <i class="iconfont icon-icon-suoxiao"></i>
          </div>
          <div class="iconfont-wrapper" @click="downloadImage">
            <i class="iconfont icon-download"></i>
          </div>
          <div style="flex: 1"></div>
          <el-select
            v-model="searchVal"
            placeholder="搜索结构"
            @focus="initSearchOptions"
            @change="handleSearch"
            size="mini"
            clearable
            filterable
          >
            <el-option
              v-for="item in searchOptions"
              :key="item.id"
              :label="item.text"
              :value="item.id"
            >
            </el-option>
          </el-select>
        </div>
      </template>
    </awesome-minder>
    <awesome-context-menu ref="menuRef">
      <awesome-context-menu-item @click="handleAppend">
        <span>添加下级</span>
      </awesome-context-menu-item>
      <awesome-context-menu-item @click="handleUpdate">
        <span>编辑</span>
      </awesome-context-menu-item>
      <awesome-context-menu-item @click="handleDelete" v-if="!isRootNode">
        <span style="color: #e63c28">删除</span>
      </awesome-context-menu-item>
    </awesome-context-menu>
  </div>
</template>
<script lang="jsx">
export default {
  name: 'Demo',
  data() {
    return {
      sourceData: [
        {
          id: 1,
          parentId: null,
          text: '根节点'
        }
      ],
      selectedNode: null,
      expandAll: false,
      searchVal: '',
      searchOptions: []
    };
  },
  computed: {
    nodeExpanded() {
      return (
        !!this.selectedNode &&
        !!this.selectedNode.rightRelations.length &&
        !!this.selectedNode.rightExpanded
      );
    },
    nodeExpandDisabled() {
      return !this.selectedNode || !this.selectedNode.rightRelations?.length;
    },
    isRootNode() {
      return this.selectedNode && !this.selectedNode.parentId;
    }
  },
  methods: {
    renderContent(node) {
      return <node-render text={node.text} />;
    },
    handleNodeSelect(node) {
      this.selectedNode = node;
    },
    handleMenu({ e }) {
      const wrapperPos = this.$refs.demoWrapper.getBoundingClientRect();
      const clientX = e.clientX - wrapperPos.x;
      const clientY = e.clientY - wrapperPos.y;
      this.$refs.menuRef.openMenu({
        clientX,
        clientY
      });
    },
    toggleExpandAll() {
      this.expandAll = !this.expandAll;
      this.$refs.minderRef.toggleExpandAll(this.expandAll);
    },
    toggleNodeExpand() {
      this.$refs.minderRef.toggleExpandNode(this.selectedNode);
    },
    centerContent() {
      this.$refs.minderRef.centerContent(false);
    },
    initSearchOptions() {
      const options = this.$refs.minderRef.exportFlattenedDatasource();
      this.searchOptions = options;
    },
    handleSearch() {
      if (this.searchVal) {
        this.$refs.minderRef.highlightNodeById(this.searchVal);
      }
    },
    zoomIn() {
      this.$refs.minderRef.zoomIn();
    },
    zoomOut() {
      this.$refs.minderRef.zoomOut();
    },
    downloadImage() {
      this.$refs.minderRef.exportImage('导出图片');
    },
    handleAppend() {
      if (!this.selectedNode) return;
      const id = new Date().getTime();
      this.$refs.minderRef.appendNode(this.selectedNode.id, {
        id,
        parentId: this.selectedNode.id,
        text: '测试' + id
      });
    },
    handleUpdate() {
      if (!this.selectedNode) return;
      const id = new Date().getTime();
      this.$refs.minderRef.editNode(this.selectedNode.id, {
        text: '测试-更新' + id
      });
    },
    handleDelete() {
      if (!this.selectedNode) return;
      this.$refs.minderRef.removeNode(this.selectedNode.id);
    }
  }
};
</script>
<style lang="scss" scoped>
.navbar {
  position: absolute;
  top: 20px;
  left: 20px;
  right: 20px;
  padding: 8px;
  background: #fff;
  box-shadow: 0 1px 1px 1px rgba(170, 170, 170, 0.18);
  overflow: hidden;
  word-break: keep-all;
  display: flex;
  align-items: center;
  gap: 8px;
  .iconfont-wrapper {
    align-items: center;
    border-radius: 2px;
    cursor: pointer;
    display: flex;
    height: 24px;
    justify-content: center;
    padding: 6px;
    transition: all 0.1s ease;
    width: 24px;

    &:not(.disabled):hover {
      background-color: #f2f3f4;
    }

    &.disabled {
      color: #ccc;
      cursor: not-allowed;
    }

    &.active {
      background-color: #e7eefb;
      color: #265cdd;
    }
  }
}
.demo-node {
  user-select: none;
}
</style>

Readme

Keywords

none

Package Sidebar

Install

npm i awesome-minder

Weekly Downloads

0

Version

1.1.2

License

MIT

Unpacked Size

139 kB

Total Files

7

Last publish

Collaborators

  • danx123