美文网首页
从零开始打造流程图、拓扑图项目【Nuxt.js + Elemen

从零开始打造流程图、拓扑图项目【Nuxt.js + Elemen

作者: 萌褚 | 来源:发表于2022-05-25 14:28 被阅读0次

    一 、通过云开发平台快速创建初始化应用

    1.创建相关应用模版请参考链接:基于 vue.js 的 SSR 技术—Nuxt.js

    // 注意在后面提示中,上移下移,按空格选中 Element
    

    2.完成创建后就可以在github中查看到新增的Nuxt仓库

    file

    二 、 本地编写 流程图、拓扑图项目

    1.将应用模版克隆到本地

    ● 首先假定你已经安装了Git、node,没有安装请移步node官网进行安装。克隆项目:

    git clone + 项目地址
    

    ● 进入项目文件

    cd nuxtJs
    

    ● 切换到feature/1.0.0 分支上

    git checkout feature/1.0.0
    

    ● 安装依赖包

    npm install
    

    ● 启动服务

    npm run dev
    

    这里打开浏览器3000端口,并出现默认页面。

    2.项目框架

    选择Element后,在plugins文件夹下会自带添加Element的插件配置

    file

    完成后,在nuxt.config.js中配置head相关信息,主要有两个阿里字体文件: 左侧工具栏字体文件: //at.alicdn.com/t/font_1113798_0532l8oa6jqp.css

    右侧属性字体图标: //at.alicdn.com/t/font_1331132_5lvbai88wkb.css

    head: {
        title: '乐吾乐 Topology - 开源免费绘图工具',
        meta: [
          { charset: 'utf-8' },
          { name: 'viewport', content: 'width=device-width, initial-scale=1' },
          {
            hid: 'description',
            name: 'description',
            content:
              '一个基于typescript + canvas的好用开源绘图工具和绘图引擎。易集成到自己的前端项目、还可以方便自定义图形库,支持微服务架构图、流程图、时序图、活动图、类图等'
          }
        ],
        link: [
          { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
          {
            rel: 'stylesheet',
            href: '//at.alicdn.com/t/font_1113798_0532l8oa6jqp.css'
          },
          {
            rel: 'stylesheet',
            href: '//at.alicdn.com/t/font_1331132_5lvbai88wkb.css'
          }
        ]
      },
    

    3.添加SCSS支持

    ● 安装scss的依赖包

    yarn add node-sass sass-loader  -D 
    

    ● 给style标签加上lang="scss"标记

    <style lang="scss">
    .page {
      width: 100%;
      height: 100%;
    }
    </style>
    

    4.添加一个全局公用css

    ● 在asstes/css文件夹下新建一个base.scss公用全局样式文件

    file

    ● 导入 在layouts/default.vue的script脚本中导入:

    import '~/assets/css/base.scss'
    

    5.网页布局

    ● 顶部导航栏

    修改layouts/default.vue为导航栏 + body两部分

    file

    其中: 为Nuxt.js框架中对应页面路由的视图部分。

    ● 修改首页为左中右三栏

    修改pages/index.vue为左中右三栏布局

    file

    6.创建画布

    ● 下载topology依赖包

    // 先导入库
    import { Topology, Options, registerNode } from '@topology/core';
    import { register as registerFlow } from '@topology/flow-diagram';
    import { register as registerActivity } from '@topology/activity-diagram';
    import { register as registerClass } from '@topology/class-diagram';
    import { register as registerSequence } from '@topology/sequence-diagram';
    import { register as registerChart } from '@topology/chart-diagram';
    
    // 注册图形库
    canvasRegister() {
        registerFlow();
        registerActivity();
        registerClass();
        registerSequence();
        registerChart();
        // ...
    }
    

    其中,@topology/core为核心库引擎,其他的为图形库。具体参考:开发文档

    ● 注册图形库

    我们单独写个servers/canvas.js服务,用来提供topology相关服务

    file

    这里主要提供注册和左侧工具栏数据。

    7.加载图形库

    ● 准备canvas相关数据

    data() {
        return {
              // 左侧工具栏
          tools: Tools,
                // 图形库
          canvas: {},
                // 图形库选项:https://www.yuque.com/alsmile/topology/canvas#hOupV
          canvasOptions: {
            rotateCursor: '/img/rotate.cur'
          },
                // 右侧属性栏数据
          props: {
            node: null,
            line: null,
            multi: false
          }
        }
      }
    

    ● 注册图形库

    created() {
        canvasRegister()
    }
    

    ● 在父节点已经渲染后,new创建画布

    mounted() {
        this.canvasOptions.on = this.onMessage
        this.canvas = new Topology('topology-canvas', this.canvasOptions)
    }
    

    其中,onMessage 表示接受画布的消息回调函数

    ● 左侧工具栏支持鼠标拖放

    <a
                v-for="(btn, i) in item.children"
                :key="i"
                :title="btn.name"
                :draggable="btn.data"
                @dragstart="onDrag($event, btn)"
              >
                <i :class="`iconfont ${btn.icon}`"></i>
              </a>
    
    methods: {
        onDrag(event, node) {
          event.dataTransfer.setData('Text', JSON.stringify(node.data))
        }
      }
    

    只需要给拖放数据设置节点格式的字符串即可(画布自带支持拖放接收处理),节点数据格式文档:www.yuque.com/alsmile/top

    8.右侧属性栏

    ● 自定义属性栏组件

    在components下创建CanvasProps.vue

    <template>
      <div>
          <!-- 选中为空 -->
        <div v-if="!props.node && !props.line && !props.multi">
          <div class="title">欢迎使用le5le-topology!</div>
          <div class="group">
            <a class="star" href="https://github.com/le5le-com/topology" target="_blank">喜欢,点击这里打个star吧</a>
            <a href="https://www.yuque.com/alsmile/topology" target="_blank">使用教程</a>
            <br />
            <a
              href="http://topology.le5le.com/assets/img/topology_wechat.jpg?t=1"
              target="_blank"
            >微信交流群(大群)</a>
            <br />
            <a href="http://topology.le5le.com/assets/img/topology_wechat2.jpg" target="_blank">微信交流群2</a>
            <br />
            <a href="https://www.yuque.com/alsmile/topology/faq#EVbCgt" target="_blank">联系我们</a>
          </div>
          <div class="title">[Todo] 未来规划</div>
          <ul class="group">
            <li>Github issues</li>
            <li>React demo</li>
            <li>Vue3 demo</li>
            <li>系列教程</li>
          </ul>
          <div class="bottom">
            <div class="title">小提示</div>
            <ul class="group">
              <li>方向键:控制节点移动5个像素</li>
              <li>Ctrl + 方向键:控制节点移动1个像素</li>
              <li>Ctrl + 鼠标移动:移动整个画布</li>
              <li>Ctrl + 鼠标滚轮:缩放</li>
              <li>添加或选中节点,右侧属性支持上传各种图片哦</li>
            </ul>
          </div>
        </div>
            <!-- 选中节点 -->
        <div v-if="props.node">
          <div class="title">位置和大小</div>
          <div class="items">
            <div class="flex grid">
              <div>X(px)</div>
              <div class="ml5">Y(px)</div>
            </div>
            <div class="flex grid">
              <div>
                <el-input-number
                  v-model="props.node.rect.x"
                  controls-position="right"
                  @change="onChange"
                ></el-input-number>
              </div>
              <div class="ml5">
                <el-input-number
                  v-model="props.node.rect.y"
                  controls-position="right"
                  @change="onChange"
                ></el-input-number>
              </div>
            </div>
          </div>
          <div class="items">
            <div class="flex grid">
              <div>宽(px)</div>
              <div class="ml5">高(px)</div>
            </div>
            <div class="flex grid">
              <div>
                <el-input-number
                  v-model="props.node.rect.width"
                  controls-position="right"
                  @change="onChange"
                ></el-input-number>
              </div>
              <div class="ml5">
                <el-input-number
                  v-model="props.node.rect.height"
                  controls-position="right"
                  @change="onChange"
                ></el-input-number>
              </div>
            </div>
          </div>
        </div>
      </div>
    </template>
    
    <script >
    export default {
      data() {
        return {}
      },
      props: {
        props: {
          type: Object,
          require: true
        }
      },
      methods: {
        onChange(value) {
          this.$emit('change', this.props.node)
        }
      }
    }
    </script>
    

    其中,props.node、line、multi分别表示是否选中节点、连线、多个对象。 这里我们暂时没有用到vuex(后面教程介绍),直接使用原生的双向绑定更简单。用$emit通知父组件属性改变事件。

    相关属性值,参数API文档:www.yuque.com/alsmile/top

    ● 引用右侧属性组件

    <div class="props">
          <CanvasProps :props.sync="props" @change="onUpdateProps"></CanvasProps>
    </div>
    

    同样,我们利用.sync关键字使用双向绑定,并接收chang事件,反馈给画布组件:

    onUpdateProps(node) {
          // 如果是画布已选中的节点,无需传参数
          this.canvas.updateProps()
          
          // 如果画布没有选中节点,需要传相关参数,参考:https://www.yuque.com/alsmile/topology/canvas#v4OFi
          this.canvas.updateProps(true, [node])
    }
    

    自此,一个简单的绘图项目就完成了。

    三 、 云端一键部署上线应用

    1.上传代码

    git add . 
    git commit -m '添加你的注释'
    git push
    

    2.在日常环境部署

    一键进行应用部署。在应用详情页面点击日常环境的「部署」按钮进行一键部署,部署状态变成绿色已部署以后可以点击访问部署网站查看效果。

    file

    3.配置自定义域名在线上环境上线

    配置线上环境自定义域名。在功能开发验证完成后要在线上环境进行部署,在线上环境的「部署配置」-「自定义域名」中填写自己的域名。例如我们添加一个二级域名 company.workbench.fun 来绑定我们部署的前端应用。然后复制自定义域名下方的API网关地址对添加的二级域名进行CNAME配置。

    file

    配置CNAME地址。复制好 API网关域名地址后,来到你自己的域名管理平台(此示例中的域名管理是阿里云的域名管理控制台,请去自己的域名控制台操作)。添加记录的「记录类型」选择「CNAME」,在「主机记录」中输入你要创建的二级域名,这里我们输入「company」,在「记录值」中粘贴我们之前复制的 API网关域名地址,「TTL」保留默认值或者设置一个你认为合适的值即可。

    file

    在线上环境部署上线。回到云开发平台的应用详情页面,按照部署的操作,点击线上环境的「部署按钮」,部署完成以后就在你自定义的域名进行了上线。CNAME 生效之后,我们输入 company.workbench.fun(示例网址) 可以打开部署的页面。至此,如何部署一个应用到线上环境,如何绑定自己的域名来访问一个线上的应用就完成了,赶紧部署自己的应用到线上环境,用自己的域名玩起来吧 ;)

    file

    4.项目预览效果

    file

    一键创建NuxtJs应用模版链接 :https://workbench.aliyun.com/application/front/create?fromConfig=14&fromRepo=sol_github_14

    参考文献:https://juejin.cn/post/6844904002392424456

    相关文章

      网友评论

          本文标题:从零开始打造流程图、拓扑图项目【Nuxt.js + Elemen

          本文链接:https://www.haomeiwen.com/subject/ojbeprtx.html