本系列教程是用Vue.js + Nuxt.js + Element + Vuex + 开源js绘图库,打造一个属于自己的在线绘图软件,最终效果:topology.le5le.com 。如果你觉得好,欢迎给文章和开源库点赞,让我们更有动力去做好!

本系列教程源码地址:Github

一、创建项目框架

1. 使用Nuxt.js向导创建项目

yarn create nuxt-app topology-vue
// 注意在后面提示中,上移下移,按空格选中 Element
复制代码

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

完成后,在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'
}
]
},
复制代码

2. 添加SCSS支持

2.1 安装scss的依赖包

yarn add node-sass sass-loader  -D
复制代码

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

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

3. 添加一个全局公用css

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

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

import '~/assets/css/base.scss'
复制代码

二、网页布局

1. 顶部导航栏

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

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

2. 修改首页为左中右三栏

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

三、创建画布

1. 下载topology依赖包

yarn add  topology-core topology-class-diagram topology-activity-diagram topology-flow-diagram topology-sequence-diagram -D
复制代码

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

2. 注册图形库

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

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

3. 加载图形库

3.1 准备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
}
}
}
复制代码

3.2 注册图形库

created() {
canvasRegister()
}
复制代码

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

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

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

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

<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…

3.5 右侧属性栏

  • 3.5.1 自定义属性栏组件 在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…

  • 3.5.2 引用右侧属性组件
<div class="props">
<CanvasProps :props.sync="props" @change="onUpdateProps"></CanvasProps>
</div>
复制代码

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

onUpdateProps(node) {
// 如果是node属性改变,需要传入node,重新计算node相关属性值
// 如果是line属性改变,无需传参
this.canvas.updateProps(node)
}
复制代码

其他

自此,一个简单的绘图项目就完成了,后续功能完善待续。

但,但,但...右侧属性栏,希望大家根据开发文档去参与完善,展示自己舞台的机会到了,可加入贡献者名单哦!不清楚的,欢迎联系管理员:(微信)alsmile123,或加群:

如何贡献

通过GitHub的pr方式: 0. 阅读开发文档,了解相关属性。

  1. fork仓库到自己名下
  2. 本地修改并提交到自己的git仓库
  3. 在自己的fork仓库找到 “Pull request” 按钮,提交

开源项目不易,欢迎大家一起参与,给【文章、GitHub开源库】点星点赞,或资助服务器:

【前端vue进阶实战】:从零打造一个流程图、拓扑图项目【Nuxt.js + Element + Vuex】 (一)的更多相关文章

  1. Vue+Koa+MongoDB从零打造一个任务管理系统

    大概是在18年的时候,当时还没有疫情.当时工作中同时负责多个项目,有 PC 端运营管理后台的,有移动端 M 站的,有微信小程序的,每天 git 分支切到头昏眼花,每个需求提测需要发送邮件,而且周五要写 ...

  2. 【前端新手也能做大项目】:跟我一起,从零打造一个属于自己的在线Visio项目实战【ReactJS + UmiJS + DvaJS】(二)

    本系列教程是教大家如何根据开源js绘图库,打造一个属于自己的在线绘图软件.当然,也可以看着是这个绘图库的开发教程.如果你觉得好,欢迎点个赞,让我们更有动力去做好! 本系列教程重点介绍如何开发自己的绘图 ...

  3. Vue + element从零打造一个H5页面可视化编辑器——pl-drag-template

    pl-drag-template Github地址:https://github.com/livelyPeng/pl-drag-template 前言 想必你一定使用过易企秀或百度H5等微场景生成工具 ...

  4. 从零打造一个Web地图引擎

    说到地图,大家一定很熟悉,平时应该都使用过百度地图.高德地图.腾讯地图等,如果涉及到地图相关的开发需求,也有很多选择,比如前面的几个地图都会提供一套js API,此外也有一些开源地图框架可以使用,比如 ...

  5. Netty+MUI从零打造一个仿微信的高性能聊天项目,兼容iPhone/iPad/安卓

    要说到微信,我相信是个人都应该知道,几乎人人都会安装这款社交APP吧,它已经成为了我们生活中不可缺少的一份子. 我记得我上大学那会刚接触Java,做的第一个小项目就是基于J2SE的聊天室,使用Java ...

  6. 使用Vue脚手架(vue-cli)从零搭建一个vue项目(包含vue项目结构展示)

    注:在搭建项目之前,请先安装一些全局的工具(如:node,vue-cli等) node安装:去node官网(https://nodejs.org/en/)下载并安装node即可,安装node以后就可以 ...

  7. ABP教程-打造一个《电话簿项目》-目录-MPA版本-基于ABP1.13版本

    此系列文章会进行不定期的更新,应该会有6章左右. 感兴趣的朋友可以跟着看看,本教程适合已经看过ABP的文档但是又无从下手的小伙伴们. 初衷: 发布系列教程的原因是发现ABP在园子火了很久,但是发现还是 ...

  8. Vue(三十二)SSR服务端渲染Nuxt.js

    初始化Nuxt.js项目步骤 1.使用脚手架工具 create-nuxt-app 创建Nuxt项目 使用yarn或者npm $ yarn create nuxt-app <项目名> 注:根 ...

  9. Vue 爬坑之路(十一)—— 基于 Nuxt.js 实现服务端渲染(SSR)

    直接使用 Vue 构建前端单页面应用,页面源码时只有简单的几行 html,这并不利于网站的 SEO,这时候就需要服务端渲染 2016 年 10 月 25 日,zeit.co 背后的团队对外发布了一个 ...

随机推荐

  1. 手动部署 Docker+Grafana+Prometheus系统监控之Redis

    监控规划图 使用Docker 创建两台Redis docker run -d --name redis1 redis docker run -d --name redis2 redis 查看redis ...

  2. 一文理解java对象初始化顺序

    例子 ​ Talk is cheap, Show you the code! public class ParentClass { static int parentStaticField = 1; ...

  3. C语言算法动态规划板子题汇总

    本篇博客仅为对动态规划基础问题的状态转移方程进行求解,然后给出对应的注释代码,有关题目的具体内容可在算法导论或网络上进行查看 目录 1.钢管切割(最小值) 2.两条流水线调度 3.多条流水线调度 4. ...

  4. python小例子(一)

    参考链接:https://zhuanlan.zhihu.com/p/83998758?utm_source=qq&utm_medium=social&utm_oi=7282008528 ...

  5. MongoDB系列---用户及权限管理02

    MongoDB-——Privilege 学习大纲: 1.用户权限管理 2.用户操作 知识回顾:  本系列上一篇博文我们讲述了如何搭建环境以及配置我们的MongoDB,通过搭建环境后我们又学习了如何通过 ...

  6. SpringBoot之响应式编程

    一 Spring WebFlux Framework说明 Spring WebFlux 是 Spring Framework 5.0 中引入的新 reactive web framework.与 Sp ...

  7. char 、signed char、unsigned char

    看如下代码: char c = -1; signed char sc = -1; unsigned char uc = -1; printf("c=%d, sc=%d, uc=%d, cx= ...

  8. quartus使用串口IP模块

    在quartus平台中使用串口模块的IP,需要使用到platform designer软件来实现. 1.在quartus界面调出IP Catalog界面. 2.在IP catalog中搜索UART,找 ...

  9. 【java基础之异常】死了都要try,不淋漓尽致地catch我不痛快!

    目录 1.异常 1.1 异常概念 1.2 异常体系 1.3 异常分类 1.4 异常的产生过程解析 2. 异常的处理 2.1 抛出异常throw 2.2 Objects非空判断 2.3 声明异常thro ...

  10. spring @Value("${name}")使用

    在springmvc.xml配置文件中加入 (注意是springmvc配置文件不是spring配置文件的xml)不然可能取不到值 <context:property-placeholder lo ...