feat: 更改文件目录,编写部分文档

Re-1.0
咬轮猫 3 years ago
parent feb6f31d69
commit 1a3529e354

@ -1,16 +1,139 @@
# vue-webtopo-svgeditor
> 基于vue3.2+ts实现的svg可视化web组态编辑器。可直接把svg文件作为组件使用、自定义拓展组件参数
> 基于vue3.2+ts实现的svg可视化web组态编辑器。可直接把svg文件和vue组件作为编辑器图形库使用赋予其缩放和旋转等功能并支持自定义拓展参数实时控制组件状态等
当前分支为重制版本,正在开发中。。。
qq交流群209048413
# 声明
## 项目优点
### 组态软件核心功能都具备
没有特殊需求,只需要配置好图形库,即可开始您的组态世界
### 优越的性能
使用了svg的symbol技术use方式加载svg图形同样的svg图形不管数量多少只会渲染一次
### 学习成本极低
svg文件即组件引入之后无需进行额外配置编辑器会自适应解析加载组件添加自定义组件和传统html无差前端er零学习成本上手
### 易拓展
配置文件采用开放式结构属性支持自定义拓展。图形库支持添加svg文件或者vue组件定制开发将变得容易
### 易于集成
项目已经编写好了库模式脚本组件已经发布到npm支持外部传入自定义组件支持组件事件订阅等
### 免费开源
MIT开源协议 可商用
## 项目说明
### 组件库
编写中,敬请期待
### 工具栏
编写中,敬请期待
### 画布
编写中,敬请期待
### 属性面板
编写中,敬请期待
## 图形库说明
### 有状态组件
编写中,敬请期待
### 无状态组件
编写中,敬请期待
### 自带动画组件
编写中,敬请期待
### 自定义svg
编写中,敬请期待
### vue组件
编写中,敬请期待
## 集成到已有项目
```
# 创建项目(已有项目跳过此步骤)
npm init vite@latest
# 进入项目目录
cd projectname
# 安装插件
pnpm i webtopo-svg-edit
# 安装pinia
pnpm i pinia
# 修改main.ts 注册pinia
import { createPinia } from 'pinia';
const app = createApp(App);
app.use(createPinia());
app.mount('#app')
#引入插件
import { WebtopoSvgEdit,WebtopoSvgPreview } from 'webtopo-svg-edit';
import 'webtopo-svg-edit/dist/style.css'
```
如果集成有问题请参考示例项目[vue-webtopo-svgeditor-example](https://github.com/yaolunmao/vue-webtopo-svgeditor-example)
**请注意插件方式引入会导致左侧工具栏的icon图标无法正确显示请自行寻找您项目构建工具的svg加载器将icon图标转换成symbol并将名字命名为svg-xxx即可正常显示**
## 贡献代码
1. Fork 本项目
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
**只接受github的prgitee为github镜像库**
## 声明
**本项目组件库来源均为网络,仅供学习交流使用,请勿将本项目里面的组件用于商业用途**
# 常见问题
## 君子协议
开源版使用时请保留底部的版权声明,感谢支持
![](./readme-imgs/版权声明.png)
## 常见问题
行尾序列问题error Delete `␍` prettier/prettier
git config --global core.autocrlf false
git config --global core.autocrlf false
## 捐助
如果这个项目对您有所帮助,请扫下方二维码打赏一杯咖啡。
![](./readme-imgs/捐赠.jpg)
## 感谢以下小伙伴为此项目做出的贡献
<a href="https://github.com/yaolunmao/vue-webtopo-svgeditor/graphs/contributors"><img src="https://contrib.rocks/image?repo=yaolunmao/vue-webtopo-svgeditor" /></a>

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
<title>webtopo-svg-editor</title>
</head>
<body>
<div id="app"></div>

@ -1,13 +1,31 @@
{
"name": "vue-webtopo-svgeditor",
"version": "1.0.0",
"name": "webtopo-svg-edit",
"version": "0.0.2",
"description": "基于vue3.2+ts实现的svg可视化web组态编辑器。",
"author": "咬轮猫 <10928033@qq.com>",
"files": [
"dist"
],
"module": "./dist/webtopo-svg-edit.es.ts",
"main": "./dist/webtopo-svg-edit.umd.ts",
"exports": {
".": {
"import": "./dist/webtopo-svg-edit.es.ts",
"require": "./dist/webtopo-svg-edit.umd.ts"
},
"./dist/style.css": {
"import": "./dist/style.css",
"require": "./dist/style.css"
}
},
"scripts": {
"dev": "vite --port 3001",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview",
"lint:eslint": "eslint --fix --ext .js,.ts,.vue,.tsx ./src",
"preinstall": "npx only-allow pnpm",
"postinstall": "husky install"
"postinstall": "husky install",
"lib": "vue-tsc --noEmit --skipLibCheck && vite build --mode lib"
},
"dependencies": {
"ace-builds": "^1.14.0",

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<g stroke="#ffffff" stroke-width="4">
<path d="M39.3 6.00012H8.7C7.20883 6.00012 6 7.20895 6 8.70012V39.3001C6 40.7913 7.20883 42.0001 8.7 42.0001H39.3C40.7912 42.0001 42 40.7913 42 39.3001V8.70012C42 7.20895 40.7912 6.00012 39.3 6.00012Z" fill="none" stroke-linejoin="round" />
<path d="M32 6V24H15V6H32Z" fill="none" stroke-linejoin="round" />
<path d="M26 13.0001V17.0001" stroke-linecap="round" />
<path d="M10.9969 6.00012H35.9985" stroke-linecap="round" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 653 B

@ -172,7 +172,7 @@
</div>
</template>
<script setup lang="ts">
import { computed, getCurrentInstance, onMounted, reactive, ref } from 'vue';
import { computed, getCurrentInstance, reactive, ref } from 'vue';
import { useConfigStore } from '@/store/config';
import { useGlobalStore } from '@/store/global';
import {
@ -200,10 +200,10 @@
calculateRightTop,
calculateTop
} from '@/utils/scale-core';
import HandlePanel from '@/components/webtopo-svgedit/components/handle-panel/index.vue';
import ConnectionPanel from '@/components/webtopo-svgedit/components/connection-panel/index.vue';
import HandlePanel from '@/components/webtopo-svg-edit/components/handle-panel/index.vue';
import ConnectionPanel from '@/components/webtopo-svg-edit/components/connection-panel/index.vue';
import { EDoneJsonType, IConfigItem } from '@/config-center/types';
import ConnectionLine from '@/components/webtopo-svgedit/components/connection-line/index.vue';
import ConnectionLine from '@/components/webtopo-svg-edit/components/connection-line/index.vue';
import { IVisiableInfo } from './types';
import { ComponentImport } from '@/config-center';
import { useContextMenuStore } from '@/store/system';
@ -720,10 +720,6 @@
height: actual_bound.height * scale_y
};
};
onMounted(() => {
globalStore.setDoneJson([]);
});
</script>
<style lang="less" scoped>
.canvas {

@ -0,0 +1,32 @@
<script setup lang="ts">
import { ref } from 'vue';
import { VAceEditor } from 'vue3-ace-editor';
import '@/config-center/ace-edit';
import { useImportDataModel } from '@/hooks';
import { ElMessage } from 'element-plus';
const content = ref<string>('');
const onImportJson = () => {
useImportDataModel(content.value);
ElMessage.success('导入成功');
};
defineExpose({
onImportJson
});
</script>
<template>
<v-ace-editor
v-model:value="content"
lang="json"
theme="monokai"
style="height: 400px"
:options="{
useWorker: true,
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true
}"
/>
</template>

@ -5,7 +5,7 @@
<div class="source-repo">组件库 :</div>
<el-select v-model="select_lib" placeholder="请选择组件库" @change="libChange">
<el-option
v-for="(item, key) in globalStore.config_center"
v-for="(item, key) in left_tool_bar"
:key="key"
:label="key"
:value="item"
@ -41,16 +41,30 @@
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { PropType, ref } from 'vue';
import { ElSelect, ElOption, ElCollapse, ElCollapseItem, ElIcon, ElMessage } from 'element-plus';
import { IConfigComponentGroup, IConfigItem } from '@/config-center/types';
import { IConfigCenter, IConfigComponentGroup, IConfigItem } from '@/config-center/types';
import { useGlobalStore } from '@/store/global';
import SvgAnalysis from '@/components/svg-analysis/index.vue';
import { EGlobalStoreIntention } from '@/store/global/types';
import { prosToVBind } from '@/utils';
const globalStore = useGlobalStore();
const select_lib = ref('svg文件');
const config_center = ref<IConfigComponentGroup[]>(globalStore.config_center.svg文件);
const props = defineProps({
customToolBar: {
type: Object as PropType<IConfigCenter>,
default: () => {}
}
});
const left_tool_bar = ref(
props.customToolBar
? Object.keys(props.customToolBar).length > 0
? props.customToolBar
: globalStore.config_center
: globalStore.config_center
);
const first_key = Object.keys(left_tool_bar.value)[0];
const select_lib = ref(first_key);
const config_center = ref<IConfigComponentGroup[]>(left_tool_bar.value[first_key]);
const activeNames = ref([
'stateful',
'stateless',

@ -59,7 +59,7 @@
ElSwitch
} from 'element-plus';
import { PropType } from 'vue';
import JsonEdit from '@/components/webtopo-svgedit/components/right-panel/json-edit.vue';
import JsonEdit from '@/components/webtopo-svg-edit/components/right-panel/json-edit.vue';
const props = defineProps({
objInfo: {
type: Object as PropType<IConfigItemProps>,

@ -1,7 +1,11 @@
<!-- eslint-disable vue/html-indent -->
<template>
<div class="flex justify-between" style="width: 100%">
<div class="flex items-center justify-between" style="width: 220px">
<div class="flex items-center"> </div>
<div class="flex items-center">
<!-- <img title="咬轮猫" class="logoimg" src="../../../../assets/logo.png" /> -->
<span class="logo-title">vue-webtopo-svgeditor</span></div
>
<el-icon
size="22"
style="cursor: pointer"
@ -84,6 +88,10 @@
<svg-analysis name="return"></svg-analysis>
</el-icon>
<el-divider direction="vertical"></el-divider>
<el-icon title="保存" class="icon-normal" :size="20" @click="onSaveClick">
<svg-analysis name="save"></svg-analysis>
</el-icon>
<el-divider direction="vertical"></el-divider>
<el-icon title="预览" class="icon-normal" :size="20" @click="onPreviewClick">
<svg-analysis name="preview"></svg-analysis>
</el-icon>
@ -106,16 +114,14 @@
import { useGlobalStore } from '@/store/global';
import { useEditPrivateStore } from '@/store/system';
import { ElIcon, ElDivider } from 'element-plus';
import { useRouter } from 'vue-router';
import SvgAnalysis from '../../../../components/svg-analysis/index.vue';
import { useSvgEditLayoutStore } from '../../../../store/svgedit-layout';
import { EVisibleConfKey, IDataModel } from '../../types';
const router = useRouter();
const svgEditLayoutStore = useSvgEditLayoutStore();
const globalStore = useGlobalStore();
const editPrivateStore = useEditPrivateStore();
const configStore = useConfigStore();
const emits = defineEmits(['changeVisible', 'onReturn']);
const emits = defineEmits(['changeVisible', 'onReturn', 'onPreview', 'onSave']);
const onDeleteBtnClick = () => {
globalStore.done_json.length <= 0 || globalStore.setDoneJson([]);
};
@ -125,16 +131,21 @@
config: configStore.svg,
done_json: globalStore.done_json
};
router.push({
name: 'preview',
params: { data_model: JSON.stringify(data_model) }
});
emits('onPreview', data_model);
};
const onSaveClick = () => {
const data_model: IDataModel = {
layout_center: svgEditLayoutStore.center_offset,
config: configStore.svg,
done_json: globalStore.done_json
};
emits('onSave', data_model);
};
</script>
<style scoped lang="less">
.logoimg {
height: 40px;
width: 160px;
width: 40px;
}
.logo-title {

@ -2,12 +2,17 @@
<div>
<el-container>
<el-header class="top-el-header">
<top-panel @change-visible="changeVisible" @on-return="emits('onReturn')"></top-panel>
<top-panel
@change-visible="changeVisible"
@on-return="emits('onReturn')"
@on-preview="(val) => emits('onPreview', val)"
@on-save="(val) => emits('onSave', val)"
></top-panel>
</el-header>
<el-container class="middle">
<el-aside class="side-nav" :class="svgEditLayoutStore.left_nav ? 'show-nav' : 'hide-nav'">
<el-scrollbar class="elscrooll-pc">
<left-panel class="content-left"></left-panel>
<left-panel class="content-left" :custom-tool-bar="props.customToolBar"></left-panel>
</el-scrollbar>
</el-aside>
<el-main class="middle main">
@ -72,12 +77,25 @@
import RightPanel from './components/right-panel/index.vue';
import BottomPanel from './components/bottom-panel/index.vue';
import { useSvgEditLayoutStore } from '../../store/svgedit-layout';
import { reactive, ref } from 'vue';
import ExportJson from '@/components/webtopo-svgedit/components/export-json/index.vue';
import ImportJson from '@/components/webtopo-svgedit/components/import-json/index.vue';
import ComponentTree from '@/components/webtopo-svgedit/components/component-tree/index.vue';
import { onMounted, PropType, reactive, ref } from 'vue';
import ExportJson from '@/components/webtopo-svg-edit/components/export-json/index.vue';
import ImportJson from '@/components/webtopo-svg-edit/components/import-json/index.vue';
import ComponentTree from '@/components/webtopo-svg-edit/components/component-tree/index.vue';
import { IVisibleConf, EVisibleConfKey } from './types';
import { IConfigCenter } from '@/config-center/types';
import { useImportDataModel } from '@/hooks';
import { useGlobalStore } from '@/store/global';
const props = defineProps({
customToolBar: {
type: Object as PropType<IConfigCenter>,
default: () => {}
},
dataModel: {
type: String,
default: ''
}
});
const globalStore = useGlobalStore();
const svgEditLayoutStore = useSvgEditLayoutStore();
const importJsonRef = ref<InstanceType<typeof ImportJson>>();
const visible_conf: IVisibleConf = reactive({
@ -85,7 +103,7 @@
[EVisibleConfKey.ImportJson]: false,
[EVisibleConfKey.ComponentTree]: false
});
const emits = defineEmits(['onReturn']);
const emits = defineEmits(['onReturn', 'onPreview', 'onSave']);
const changeVisible = (key: EVisibleConfKey, val: boolean) => {
visible_conf[key] = val;
};
@ -93,6 +111,13 @@
importJsonRef.value?.onImportJson();
changeVisible(EVisibleConfKey.ImportJson, false);
};
onMounted(() => {
if (props.dataModel != '') {
useImportDataModel(props.dataModel);
} else {
globalStore.setDoneJson([]);
}
});
</script>
<style scoped lang="less">
@headerHeight: 60px;

@ -96,10 +96,10 @@
import { prosToVBind } from '@/utils';
import { EDoneJsonType } from '@/config-center/types';
import ConnectionLine from '@/components/webtopo-svgedit/components/connection-line/index.vue';
import ConnectionLine from '@/components/webtopo-svg-edit/components/connection-line/index.vue';
import { ComponentImport } from '@/config-center';
import { IDataModel } from '../webtopo-svgedit/types';
import { IDataModel } from '../webtopo-svg-edit/types';
import 'element-plus/dist/index.css';
// import HandlePanel from '../handle-panel/index.vue';
//

@ -1,50 +0,0 @@
<script setup lang="ts">
import { ref } from 'vue';
import { VAceEditor } from 'vue3-ace-editor';
import '@/config-center/ace-edit';
import { useGlobalStore } from '@/store/global';
import { useSvgEditLayoutStore } from '@/store/svgedit-layout';
import { useConfigStore } from '@/store/config';
import { IDataModel } from '../../types';
import { ElMessage } from 'element-plus';
const content = ref<string>('');
const globalStore = useGlobalStore();
const svgEditLayoutStore = useSvgEditLayoutStore();
const configStore = useConfigStore();
const onImportJson = () => {
try {
const json: IDataModel = JSON.parse(content.value);
console.log(json, json.layout_center, configStore, 15);
if (!json.config || !json.layout_center || !json.done_json) {
ElMessage.error('请导入正确的数据模型!');
return;
}
configStore.svg = json.config;
svgEditLayoutStore.center_offset = json.layout_center;
globalStore.setDoneJson(json.done_json);
ElMessage.success('导入成功');
} catch (error) {
ElMessage.error('请导入正确的数据模型!');
console.error(error);
return;
}
};
defineExpose({
onImportJson
});
</script>
<template>
<v-ace-editor
v-model:value="content"
lang="json"
theme="monokai"
style="height: 400px"
:options="{
useWorker: true,
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true
}"
/>
</template>

@ -1,10 +1,10 @@
import { svgfile_config_center } from './svg-file';
import { IComponentImport, IConfigCenter } from './types';
import customSvgText from '@/components/webtopo-svgedit/components/custom-svg/custom-svg-text/index.vue';
import customSvgText from '@/components/webtopo-svg-edit/components/custom-svg/custom-svg-text/index.vue';
import { vue_config_center } from './vue';
import { ElButton, ElTag } from 'element-plus';
import CommonTable from '@/components/webtopo-svgedit/components/custom-vue/common-table/index.vue';
import PieCharts from '@/components/webtopo-svgedit/components/echarts/pie-charts/index.vue';
import CommonTable from '@/components/webtopo-svg-edit/components/custom-vue/common-table/index.vue';
import PieCharts from '@/components/webtopo-svg-edit/components/echarts/pie-charts/index.vue';
export const configCenter: IConfigCenter = {
svg: svgfile_config_center,
vue: vue_config_center

@ -0,0 +1,5 @@
import WebtopoSvgEdit from '@/components/webtopo-svg-edit/index.vue';
import WebtopoSvgPreview from '@/components/webtopo-svg-preview/index.vue';
import 'virtual:windi.css';
import 'virtual:svg-icons-register';
export { WebtopoSvgEdit, WebtopoSvgPreview };

@ -1,5 +1,10 @@
import { IDataModel } from '@/components/webtopo-svg-edit/types';
import { useConfigStore } from '@/store/config';
import { useGlobalStore } from '@/store/global';
import { IDoneJson } from '@/store/global/types';
import { useSvgEditLayoutStore } from '@/store/svgedit-layout';
import { useEditPrivateStore } from '@/store/system';
import { ElMessage } from 'element-plus';
export const useHistoryRecord = (done_json: IDoneJson[]) => {
const edit_private_store = useEditPrivateStore();
@ -16,3 +21,22 @@ export const useHistoryRecord = (done_json: IDoneJson[]) => {
}
edit_private_store.is_record_history = true;
};
export const useImportDataModel = (model_str: string) => {
try {
const globalStore = useGlobalStore();
const svgEditLayoutStore = useSvgEditLayoutStore();
const configStore = useConfigStore();
const json: IDataModel = JSON.parse(model_str);
if (!json.config || !json.layout_center || !json.done_json) {
ElMessage.error('请导入正确的数据模型!');
return;
}
configStore.svg = json.config;
svgEditLayoutStore.center_offset = json.layout_center;
globalStore.setDoneJson(json.done_json);
} catch (error) {
ElMessage.error('请导入正确的数据模型!');
console.error(error);
return;
}
};

@ -1,9 +1,396 @@
<template>
<webtopo-svgedit @on-return="onReturn"></webtopo-svgedit>
<webtopo-svg-edit
@on-return="onReturn"
@on-preview="onPreview"
@on-save="onSave"
></webtopo-svg-edit>
</template>
<script setup lang="ts">
import WebtopoSvgedit from '../../components/webtopo-svgedit/index.vue';
// import { ref } from 'vue';
import { IDataModel } from '@/components/webtopo-svg-edit/types';
// import { ref } from 'vue';
import { useRouter } from 'vue-router';
import WebtopoSvgEdit from '../../components/webtopo-svg-edit/index.vue';
// const setCustomToolBar = ref({
// : [
// {
// groupType: 'element-ui',
// title: 'element-ui',
// list: [
// {
// name: 'el-button',
// tag: 'el-button',
// title: '',
// type: 'Vue',
// config: {
// can_zoom: true,
// have_anchor: true,
// actual_rect: true
// },
// display: true,
// props: {
// size: {
// title: '',
// type: 'Select',
// val: 'default',
// options: [
// {
// label: '',
// value: 'large'
// },
// {
// label: '',
// value: 'default'
// },
// {
// label: '',
// value: 'small'
// }
// ]
// },
// type: {
// title: '',
// type: 'Select',
// val: 'primary',
// options: [
// {
// label: '',
// value: 'primary'
// },
// {
// label: '',
// value: 'success'
// },
// {
// label: '',
// value: 'warning'
// },
// {
// label: '',
// value: 'danger'
// },
// {
// label: '',
// value: 'info'
// }
// ]
// },
// plain: {
// title: '',
// type: 'Switch',
// val: false
// },
// text: {
// title: '',
// type: 'Switch',
// val: false
// }
// },
// tag_slot: ''
// }
// ]
// },
// {
// groupType: 'custom-vue',
// title: '',
// list: [
// {
// name: 'custom-vue-common-table',
// title: '',
// tag: 'custom-vue-common-table',
// type: 'Vue',
// config: {
// can_zoom: true,
// have_anchor: true,
// actual_rect: true
// },
// display: true,
// props: {
// 'col-config': {
// title: '',
// type: 'JsonEdit',
// val: [
// {
// prop: 'date',
// label: '',
// width: '120px',
// fixed: false,
// sortable: false,
// 'show-overflow-tooltip': false
// },
// {
// prop: 'name',
// label: '',
// width: '120px',
// fixed: false,
// sortable: false,
// 'show-overflow-tooltip': false
// },
// {
// prop: 'address',
// label: '',
// width: '280px',
// fixed: false,
// sortable: false,
// 'show-overflow-tooltip': false
// }
// ]
// },
// data: {
// title: '',
// type: 'JsonEdit',
// val: [
// {
// date: '2016-05-03',
// name: 'Tom',
// address: 'No. 189, Grove St, Los Angeles'
// },
// {
// date: '2016-05-02',
// name: 'Tom',
// address: 'No. 189, Grove St, Los Angeles'
// },
// {
// date: '2016-05-04',
// name: 'Tom',
// address: 'No. 189, Grove St, Los Angeles'
// },
// {
// date: '2016-05-01',
// name: 'Tom',
// address: 'No. 189, Grove St, Los Angeles'
// }
// ]
// },
// height: {
// title: '',
// type: 'InputNumber',
// val: null
// },
// 'max-height': {
// title: '',
// type: 'InputNumber',
// val: null
// },
// stripe: {
// title: '',
// type: 'Switch',
// val: false
// },
// border: {
// title: '',
// type: 'Switch',
// val: false
// },
// size: {
// title: '',
// type: 'Select',
// val: 'default',
// options: [
// {
// label: '',
// value: 'large'
// },
// {
// label: '',
// value: 'default'
// },
// {
// label: '',
// value: 'small'
// }
// ]
// },
// fit: {
// title: '',
// type: 'Switch',
// val: false
// }
// }
// }
// ]
// }
// ]
// });
// const import_model = ref(
// JSON.stringify({
// layout_center: {
// x: 0,
// y: 0
// },
// config: {
// background_color: '#fff',
// scale: 1,
// position_center: {
// x: -295,
// y: -95
// },
// svg_position_center: {
// x: 50,
// y: 50
// }
// },
// done_json: [
// {
// id: 'circuit-breakerCuFTG7Iy6F',
// x: 474,
// y: 226,
// client: {
// x: 474,
// y: 226
// },
// scale_x: 1,
// scale_y: 1,
// rotate: 0,
// actual_bound: {
// x: 23.1640625,
// y: 19.375,
// width: 61.201171875,
// height: 64.033203125
// },
// point_coordinate: {
// tl: {
// x: 443.3994140625,
// y: 193.9833984375
// },
// tc: {
// x: 474,
// y: 193.9833984375
// },
// tr: {
// x: 504.6005859375,
// y: 193.9833984375
// },
// l: {
// x: 443.3994140625,
// y: 226
// },
// r: {
// x: 504.6005859375,
// y: 226
// },
// bl: {
// x: 443.3994140625,
// y: 258.0166015625
// },
// bc: {
// x: 474,
// y: 258.0166015625
// },
// br: {
// x: 504.6005859375,
// y: 258.0166015625
// }
// },
// name: 'circuit-breaker',
// title: '',
// type: 'File',
// config: {
// can_zoom: true,
// have_anchor: true,
// actual_rect: true
// },
// display: true,
// props: {},
// state: {
// OnOff: {
// title: '',
// default: false,
// props: {
// fill: {
// openVal: '#00ff00',
// closeVal: '#ff0000'
// },
// 'fill-opacity': {
// openVal: '0',
// closeVal: '1'
// }
// }
// }
// }
// },
// {
// id: 'traction-transformer9nzBE9dPxm',
// x: 666,
// y: 170,
// client: {
// x: 666,
// y: 170
// },
// scale_x: 1,
// scale_y: 1,
// rotate: 0,
// actual_bound: {
// x: 35.416664123535156,
// y: 22.916667938232422,
// width: 26.858333587646484,
// height: 54.16874313354492
// },
// point_coordinate: {
// tl: {
// x: 652.5708332061768,
// y: 142.91562843322754
// },
// tc: {
// x: 666,
// y: 142.91562843322754
// },
// tr: {
// x: 679.4291667938232,
// y: 142.91562843322754
// },
// l: {
// x: 652.5708332061768,
// y: 170
// },
// r: {
// x: 679.4291667938232,
// y: 170
// },
// bl: {
// x: 652.5708332061768,
// y: 197.08437156677246
// },
// bc: {
// x: 666,
// y: 197.08437156677246
// },
// br: {
// x: 679.4291667938232,
// y: 197.08437156677246
// }
// },
// name: 'traction-transformer',
// title: '',
// type: 'File',
// config: {
// can_zoom: true,
// have_anchor: true,
// actual_rect: true
// },
// display: true,
// props: {
// fill: {
// title: '',
// type: 'Color',
// val: '#ff0000'
// }
// }
// }
// ]
// })
// );
const router = useRouter();
const onReturn = () => {
console.log('点击了返回按钮');
};
const onPreview = (data_model: IDataModel) => {
router.push({
name: 'preview',
params: { data_model: JSON.stringify(data_model) }
});
};
const onSave = (data_model: IDataModel) => {
console.log('点击了保存按钮,可以在此处将图存到数据库', data_model);
};
</script>

@ -3,7 +3,7 @@
</template>
<script setup lang="ts">
import WebtopoSvgPreview from '@/components/webtopo-svg-preview/index.vue';
import { IDataModel } from '@/components/webtopo-svgedit/types';
import { IDataModel } from '@/components/webtopo-svg-edit/types';
import { ref } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();

@ -1,33 +1,62 @@
import { defineConfig } from 'vite';
import { defineConfig, UserConfigExport } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
import eslintPlugin from 'vite-plugin-eslint';
import WindiCSS from 'vite-plugin-windicss';
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
eslintPlugin({
cache: false,
include: ['src/**/*.vue', 'src/**/*.ts', 'src/**/*.tsx'] // 检查的文件
}),
WindiCSS(),
createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [
resolve(process.cwd(), 'src/assets/svgs'),
resolve(process.cwd(), 'src/assets/icons')
],
// 指定symbolId格式
symbolId: 'svg-[name]',
// 禁用压缩 否则想要修改无状态组件的stroke或者fill会影响到预设样式 例如stroke-width
svgoOptions: false
})
],
resolve: {
alias: {
'@': resolve(__dirname, 'src')
export default defineConfig(({ mode }) => {
let config: UserConfigExport = {
plugins: [
vue(),
eslintPlugin({
cache: false,
include: ['src/**/*.vue', 'src/**/*.ts', 'src/**/*.tsx'] // 检查的文件
}),
WindiCSS(),
createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [
resolve(process.cwd(), 'src/assets/svgs'),
resolve(process.cwd(), 'src/assets/icons')
],
// 指定symbolId格式
symbolId: 'svg-[name]',
// 禁用压缩 否则想要修改无状态组件的stroke或者fill会影响到预设样式 例如stroke-width
svgoOptions: false
})
],
resolve: {
alias: {
'@': resolve(__dirname, 'src')
}
}
};
if (mode === 'lib') {
config = {
...config,
...{
build: {
lib: {
entry: resolve(__dirname, 'src/export.ts'),
name: 'webtopo-svg-edit',
fileName: (format) => `webtopo-svg-edit.${format}.ts`
},
rollupOptions: {
// 确保外部化处理那些你不想打包进库的依赖
external: ['vue', 'pinia'],
output: {
// 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
globals: {
vue: 'Vue',
pinia: 'Pinia'
},
inlineDynamicImports: true
}
}
}
}
};
}
return config;
});

Loading…
Cancel
Save