vue-webtopo-svgeditor
基於vue3.2+ts實現的svg可視化web組態編輯器。可無需修改代碼動態添加組件、自定義拓展組件參數
當前主分支版本為3.0,該項目基於vue3.2+ts開發,ui使用了naiveui
本文圖片掛了請點此查看
預覽地址
http://svg.yaolm.top(請使用版本新一點的瀏覽器🤔)
git地址
https://github.com/yaolunmao/vue-webtopo-svgeditor
https://gitee.com/yaolunmao/vue-webtopo-svgeditor
這個項目都能干什么
目前我用來繪制物聯網監控系統圖
電力監控系統圖

水務系統圖

但不僅僅局限於這些,只要是svg矢量圖標都可以作為組件進行拖拽組態
優點
- 學習成本極低:核心代碼僅500多行
- 添加組件無需修改代碼:只要在json里新增一項就可
- 輕量:組件打包只有1MB
- 易拓展:按照我定義好的格式,只需要在json里面定義好屬性,便可以動態修改svg組件的任意節點
- 易於集成:組件已經發布到npm,只需要引用到現有項目將組件數據傳給組件即可使用
- 免費:MIT開源協議 可商用
如何引用
# 創建項目(已有項目跳過此步驟)
npm init vite@latest
# 進入項目目錄
cd projectname
# 安裝插件
npm install vue-webtopo-svgeditor
#引入插件
import {SvgEditor,SvgPrview} from 'vue-webtopo-svgeditor';
import 'vue-webtopo-svgeditor/dist/style.css'
# 修改vite.config.ts使之可以進行運行時創建組件
alias: {
'vue': 'vue/dist/vue.esm-bundler.js' // 定義vue的別名,如果使用其他的插件,可能會用到別名
},
# 如果需要使用圖表 修改main.ts 全局注冊一下圖表組件
import { VChart} from 'vue-webtopo-svgeditor';
const app=createApp(App)
app.component('v-chart',VChart)
app.mount('#app')
如何使用
使用編輯器需要將配置好的插件列表傳遞給組件,插件列表可通過調用后台接口的方式或者定義在項目里,推薦使用接口方式,可使項目更加靈活,舉例demo.json
[{
"type": "TestAddSvg",//組件類型 可理解為組件的唯一id
"title": "測試新增心形",//組件名稱
"panel_class": "common",//組件在左側工具欄的分類
"template": "<path :fill=\"prop_data.extend_attr.color.val\" :stroke=\"prop_data.extend_attr.color.val\" stroke-width=\"5\" style=\"pointer-events:inherit\" d=\"m143.72081869586242,163.35565803158485 c14.617751633754164,-41.93617271978648 71.89058180534832,0 0,53.91793635401125 c-71.89058180534832,-53.91793635401125 -14.617751633754164,-95.85410907379776 0,-53.91793635401125 z\" fill-opacity=\"1\" stroke-opacity=\"1\" transform=\"translate(-145,-180)\"></path> ",//svg元素
"props": [
"prop_data"
],
"extend_attr": {//拓展參數
"color": {
"title": "心形顏色",
"val": "#FF0000",
"type": "colorinputbox"
}
},
"create_type": "draggable",//創建方式 拖動還是繪制
"priview_img": "http://svg.yaolm.top/test.png"//左側工具欄的預覽圖像
}
]
更多組件請參考public\InterfaceReturn.json
在vue里引入編輯器組件,然后將demo.json傳遞給組件的component_infos
<svg-editor
:component_infos="demo.json"
@saveSvgInfo="saveSvgInfo"
:svgCanvas="{ width: 1920, height: 1080 }"
></svg-editor>
| 屬性名 | 說明 | 默認值 |
|---|---|---|
| component_infos | 預定義的組件列表 | |
| saveSvgInfo | 編輯器點擊保存的回調方法 | |
| svgCanvas | 畫板的大小 |
預覽組件同理
<svg-prview
:component_infos="demo.json"
:svg_data="prview_data"
:svgCanvas="{ width: 1920, height: 1080 }"
></svg-prview>
| 屬性名 | 說明 | 默認值 |
|---|---|---|
| component_infos | 預定義的組件列表 | |
| svg_data | 編輯器點擊保存的數據 | |
| svgCanvas | 畫板的大小 |
如何進行開發
# 克隆項目
git clone https://github.com/yaolunmao/vue-webtopo-svgeditor.git
# 進入項目目錄
cd vue-webtopo-svgeditor
# 安裝依賴
npm install
# 啟動服務
npm run dev
操作說明
- 常規組件和圖表組件用鼠標左鍵選中並按住可拖動至畫布
- 繪制組件需先選中 再將鼠標移至畫布中按住左鍵開始繪制 松開左鍵結束繪制
- 在畫布上單擊左鍵並按住可以拖動組件改變位置
- 當組件選中時會有選中效果 此時右側面板彈出 可使用快捷鍵和編輯右側面板屬性更改組件
- 鍵盤↑↓←→可移動選中組件 ctrl+c復制當前選中組件 deleted刪除當前選中組件
- 點擊畫布空白處可以取消選中組件 並關閉屬性面板
- 點擊《 符號可以顯示或隱藏左側面板
動態添加組件
可使用任意生成svg代碼的工具,我這里使用在線編譯器進行模擬
點擊這里進行svg圖像繪制,我這里以心形為例

將svg代碼復制下來,雙引號進行轉義,刪除無用屬性(比如id),你也可以直接使用我下面的代碼
<path fill=\"#FF0000\" stroke=\"#000000\" stroke-width=\"5\" style=\"pointer-events:inherit\" d=\"m143.72081869586242,163.35565803158485 c14.617751633754164,-41.93617271978648 71.89058180534832,0 0,53.91793635401125 c-71.89058180534832,-53.91793635401125 -14.617751633754164,-95.85410907379776 0,-53.91793635401125 z\" fill-opacity=\"1\" stroke-opacity=\"1\"></path>
將拓展字段進行雙向綁定 我目前只做了顏色
<path :fill=\"prop_data.extend_attr.color.val\" :stroke=\"prop_data.extend_attr.color.val\" stroke-width=\"5\" style=\"pointer-events:inherit\" d=\"m143.72081869586242,163.35565803158485 c14.617751633754164,-41.93617271978648 71.89058180534832,0 0,53.91793635401125 c-71.89058180534832,-53.91793635401125 -14.617751633754164,-95.85410907379776 0,-53.91793635401125 z\" fill-opacity=\"1\" stroke-opacity=\"1\" transform=\"translate(-145,-180)\"></path>
修改項目文件夾pubilc下的模擬接口返回的json,新增一項:
{
"type": "TestAddSvg",
"title": "測試新增心形",
"panel_class": "common",
"template": "<path :fill=\"prop_data.extend_attr.color.val\" :stroke=\"prop_data.extend_attr.color.val\" stroke-width=\"5\" style=\"pointer-events:inherit\" d=\"m143.72081869586242,163.35565803158485 c14.617751633754164,-41.93617271978648 71.89058180534832,0 0,53.91793635401125 c-71.89058180534832,-53.91793635401125 -14.617751633754164,-95.85410907379776 0,-53.91793635401125 z\" fill-opacity=\"1\" stroke-opacity=\"1\" transform=\"translate(-145,-180)\"></path>",
"props": [
"prop_data"
],
"extend_attr": {
"color": {
"title": "心形顏色",
"val": "#FF0000",
"type": "colorinputbox"
}
},
"create_type": "draggable",
"priview_img": "http://svg.yaolm.top/test.png"
}
啟動項目,就可以看到剛才添加的組件了

也支持直接引入圖片,只不過放大有失真,將下面的代碼替換上面json文件的template值
<image x=\"-33\" y=\"-33\" width=\"66\" height=\"66\" xlink:href=\"http://svg.yaolm.top/test.png\" />
ps:目前中心輔助線的坐標取決於svg組件的中心坐標,請自行添加transform屬性調整svg組件中心坐標
右側屬性面板的自定義屬性說明
因為組件的多樣性,所以增加了自定義拓展屬性。例如文字組件可輸入文字內容、修改字體樣式等,開關組件則可以進行閉合,使用拓展屬性可以針對某個組件顯示不同的樣式。
目前只封裝了6種
- colorinputbox:顏色選擇器
- radiogroup:單選
- numberinputbox:數字輸入框
- textinputbox:文本輸入框
- textareainputbox:文本域
- select:下拉選擇器
具體配置可參考文件public\InterfaceReturn.json查看對象的extend_attr屬性
關於vue2的特別說明
vue2想使用動態組件可以使用Vue.component(),此處感謝大佬chj2020指導
vue2如何支持多節點
首先安裝vue-fragment
npm install vue-fragment
引用vue-fragment
//main.js
import Fragment from 'vue-fragment'
Vue.use(Fragment.Plugin)
然后在json文件的template屬性值里面最外層使用標簽
<fragment></fragment>
例如
<fragment><path :fill=\"prop_data.extend_attr.color.val\" :stroke=\"prop_data.extend_attr.color.val\" stroke-width=\"5\" style=\"pointer-events:inherit\" d=\"m143.72081869586242,163.35565803158485 c14.617751633754164,-41.93617271978648 71.89058180534832,0 0,53.91793635401125 c-71.89058180534832,-53.91793635401125 -14.617751633754164,-95.85410907379776 0,-53.91793635401125 z\" fill-opacity=\"1\" stroke-opacity=\"1\" transform=\"translate(-145,-180)\"></path></fragment>
截圖






