update
This commit is contained in:
parent
0c21631357
commit
b120bc39b7
941
package-lock.json
generated
941
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -9,9 +9,11 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.8.3",
|
||||||
|
"element-plus": "^2.5.6",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"stream": "^0.0.2",
|
"stream": "^0.0.2",
|
||||||
"vue": "^3.2.13"
|
"vue": "^3.2.13",
|
||||||
|
"vue-i18n": "^9.9.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.12.16",
|
"@babel/core": "^7.12.16",
|
||||||
@ -20,7 +22,9 @@
|
|||||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||||
"@vue/cli-service": "~5.0.0",
|
"@vue/cli-service": "~5.0.0",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-plugin-vue": "^8.0.3"
|
"eslint-plugin-vue": "^8.0.3",
|
||||||
|
"unplugin-auto-import": "^0.17.5",
|
||||||
|
"unplugin-vue-components": "^0.26.0"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"root": true,
|
"root": true,
|
||||||
|
@ -53,3 +53,26 @@ html, body {
|
|||||||
background: none;
|
background: none;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-select__wrapper {
|
||||||
|
background-color: transparent !important;
|
||||||
|
width: 50% !important;
|
||||||
|
min-width: 200px !important;
|
||||||
|
padding: 13px !important;
|
||||||
|
font-size: 16px !important;
|
||||||
|
color: var(--sidebar-item-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-select__placeholder {
|
||||||
|
color: var(--sidebar-item-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-select-dropdown {
|
||||||
|
min-width: 300px !important;
|
||||||
|
background-color: var(--sidebar);
|
||||||
|
border: 1px solid var(--main-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-checkbox-button__inner {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
25
src/App.vue
25
src/App.vue
@ -24,7 +24,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMounted, reactive } from 'vue';
|
import { onMounted, reactive } from 'vue';
|
||||||
import { getVcdStream, readVcdFile } from '@/hook/utils';
|
import { getVcdStream, readVcdFile } from '@/hook/utils';
|
||||||
import { emitter } from '@/hook/global';
|
import { emitter, globalLookup } from '@/hook/global';
|
||||||
|
|
||||||
import RightNav from '@/components/right-nav.vue';
|
import RightNav from '@/components/right-nav.vue';
|
||||||
|
|
||||||
@ -40,6 +40,18 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
// 改变默认颜色
|
||||||
|
document.body.style.setProperty('--el-color-primary', 'var(--main-color)');
|
||||||
|
document.body.style.setProperty('--el-color-primary-light-9', 'var(--main-color)');
|
||||||
|
document.body.style.setProperty('--el-color-primary-light-3', 'var(--main-color)');
|
||||||
|
document.body.style.setProperty('--el-text-color-secondary', 'var(--foreground)');
|
||||||
|
document.body.style.setProperty('--el-text-color-regular', 'var(--foreground)');
|
||||||
|
document.body.style.setProperty('--el-border-color', 'var(--vscode-focusBorder)');
|
||||||
|
document.body.style.setProperty('--el-fill-color-blank', 'var(--sidebar)');
|
||||||
|
document.body.style.setProperty('--el-fill-color-light', 'var(--vscode-button-hoverBackground)');
|
||||||
|
document.body.style.setProperty('--el-switch-on-color', 'var(--main-color)');
|
||||||
|
|
||||||
|
|
||||||
const uint8array = await readVcdFile();
|
const uint8array = await readVcdFile();
|
||||||
const vcdstream = await getVcdStream();
|
const vcdstream = await getVcdStream();
|
||||||
const maxChunkLength = 1 << 17;
|
const maxChunkLength = 1 << 17;
|
||||||
@ -51,16 +63,17 @@ export default {
|
|||||||
VcdInfo.topModules.push(topModule);
|
VcdInfo.topModules.push(topModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
// timestamp when vcd is loaded
|
// 这一步时,已经加载完成
|
||||||
// send wires of first module
|
// 默认第一个模块被选中
|
||||||
if (VcdInfo.topModules.length > 0) {
|
if (VcdInfo.topModules.length > 0) {
|
||||||
const defaultMod = VcdInfo.topModules[0];
|
const defaultMod = VcdInfo.topModules[0];
|
||||||
const wires = defaultMod.body.filter(mod => mod.link);
|
const wires = defaultMod.body.filter(mod => mod.link);
|
||||||
emitter.emit('tree-view', wires);
|
emitter.emit('tree-view', wires);
|
||||||
|
// 将顶层模块存储进全局对象,以便后续的搜索服务
|
||||||
|
for (const mod of VcdInfo.topModules) {
|
||||||
|
globalLookup.topModules.push(mod);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -4,19 +4,18 @@
|
|||||||
<img src="../../assets/icon.png" height="200px" alt="">
|
<img src="../../assets/icon.png" height="200px" alt="">
|
||||||
</div>
|
</div>
|
||||||
<div class="version-caption">
|
<div class="version-caption">
|
||||||
<span>当前版本   <span class="version-wrapper">0.3.3</span></span>
|
<span>{{ t('current-version') }}   <span class="version-wrapper">0.3.3</span></span>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div style="display: flex;justify-content: space-around;">
|
<div style="display: flex;justify-content: space-around;">
|
||||||
<div class="copyright-caption">本软件版权归
|
<div class="copyright-caption" v-html="t('copyright')"></div>
|
||||||
<a href="https://github.com/Digital-EDA" target="_blank">Digital-IDE</a> 项目组所有,欢迎 <a href="https://github.com/Digital-EDA/Digital-IDE">Star</a>。</div>
|
|
||||||
<div class="copyright-caption">The copyright of this software belongs to
|
|
||||||
<a href="https://github.com/Digital-EDA" target="_blank">Digital-IDE</a> project team. Welcome to <a href="https://github.com/Digital-EDA/Digital-IDE">Star</a>.</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'dide-about',
|
name: 'dide-about',
|
||||||
setup() {
|
setup() {
|
||||||
@ -24,8 +23,11 @@ export default {
|
|||||||
window.open(url, '_blank');
|
window.open(url, '_blank');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
goto
|
goto,
|
||||||
|
t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,75 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="setting-wrapper">
|
<div class="setting-wrapper">
|
||||||
<div class="section">
|
<div class="setting-section">
|
||||||
|
<h2>{{ t('search-setting') }}</h2>
|
||||||
|
<div class="setting-option">
|
||||||
|
<span class="option-title">{{ t('case-sensitivity') }}</span>
|
||||||
|
<el-switch v-model="globalSetting.caseSensitivity" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div class="setting-option">
|
||||||
|
<span class="option-title">{{ t('search-scope') }}</span>
|
||||||
|
<el-checkbox-group v-model="globalSetting.searchScope" size="default">
|
||||||
|
<el-checkbox-button label="wire" border>wire </el-checkbox-button>
|
||||||
|
<el-checkbox-button label="reg" border>reg </el-checkbox-button>
|
||||||
|
<el-checkbox-button label="module" border>module</el-checkbox-button>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="section">
|
|
||||||
|
<div class="setting-section">
|
||||||
|
<h2>{{ t('general-setting') }}</h2>
|
||||||
|
<div class="setting-option" style="width: 300px;">
|
||||||
|
<span class="option-title">{{ t('language-setting') }}</span>
|
||||||
|
|
||||||
|
<el-select name="language-setting" class="language-setting" v-model="locale">
|
||||||
|
<el-option
|
||||||
|
v-for="option in languageSetting.options"
|
||||||
|
:value="option.value"
|
||||||
|
:label="option.text"
|
||||||
|
:key="option.value">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { reactive } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { globalSetting } from '@/hook/global';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'dide-setting',
|
name: 'dide-setting',
|
||||||
setup() {
|
setup() {
|
||||||
|
const { t, locale } = useI18n();
|
||||||
|
|
||||||
|
const languageSetting = reactive({
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: 'en',
|
||||||
|
text: 'English'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'zh',
|
||||||
|
text: '中文'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
t,
|
||||||
|
languageSetting,
|
||||||
|
globalSetting,
|
||||||
|
locale
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -22,12 +77,30 @@ export default {
|
|||||||
<style>
|
<style>
|
||||||
.setting-wrapper {
|
.setting-wrapper {
|
||||||
width: 600px;
|
width: 600px;
|
||||||
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.setting-wrapper section {
|
.setting-section {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
border-radius: .3em;
|
border-radius: .3em;
|
||||||
min-height: 50px;
|
min-height: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.setting-option {
|
||||||
|
margin: 5px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
height: 40px;
|
||||||
|
width: fit-content;
|
||||||
|
border-radius: .5em;
|
||||||
|
background-color: var(--background);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-title {
|
||||||
|
min-width: 80px;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -3,17 +3,17 @@
|
|||||||
<div class="vcd-treeview">
|
<div class="vcd-treeview">
|
||||||
<TreeViewSearch></TreeViewSearch>
|
<TreeViewSearch></TreeViewSearch>
|
||||||
<br>
|
<br>
|
||||||
<div style="display: flex;">
|
<div class="vcd-module-wrapper">
|
||||||
<div class="vcd-signal-info">
|
<div class="vcd-module-info">
|
||||||
<div>Modules</div>
|
<div>{{ t('module') }}</div>
|
||||||
<hr>
|
<hr>
|
||||||
<Signals v-for="mod of props.topModules"
|
<Modules v-for="mod of props.topModules"
|
||||||
:key="mod.name"
|
:key="mod.name"
|
||||||
:signal="mod"
|
:module="mod"
|
||||||
></Signals>
|
></Modules>
|
||||||
</div>
|
</div>
|
||||||
<div class="vcd-signal-wires">
|
<div class="vcd-module-wires">
|
||||||
<Wires></Wires>
|
<Signals></Signals>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -21,46 +21,44 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { onMounted } from 'vue';
|
import { onMounted } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import TreeViewSearch from '@/components/treeview/search.vue';
|
import TreeViewSearch from '@/components/treeview/search.vue';
|
||||||
|
import Modules from '@/components/treeview/modules.vue';
|
||||||
import Signals from '@/components/treeview/signals.vue';
|
import Signals from '@/components/treeview/signals.vue';
|
||||||
import Wires from '@/components/treeview/wires.vue';
|
|
||||||
|
|
||||||
import { emitter } from '@/hook/global';
|
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'tree-view',
|
name: 'tree-view',
|
||||||
components: {
|
components: {
|
||||||
|
Modules,
|
||||||
Signals,
|
Signals,
|
||||||
Wires,
|
|
||||||
TreeViewSearch
|
TreeViewSearch
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
topModules: Array
|
topModules: Array
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
onMounted(() => {
|
const { t } = useI18n();
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props
|
props,
|
||||||
|
t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.vcd-signal-info {
|
.vcd-module-info {
|
||||||
height: 80vh;
|
height: 80vh;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vcd-signal-wires {
|
.vcd-module-wires {
|
||||||
height: 80vh;
|
height: 80vh;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
@ -68,9 +66,17 @@ export default {
|
|||||||
|
|
||||||
.vcd-treeview {
|
.vcd-treeview {
|
||||||
background-color: var(--sidebar);
|
background-color: var(--sidebar);
|
||||||
padding: 10px;
|
padding: 10px 10px 10px 10px;
|
||||||
height: fit-content;
|
height: 98vh;
|
||||||
border-radius: 1.0em;
|
border-radius: 1.0em;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vcd-module-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
overflow: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
139
src/components/treeview/modules.vue
Normal file
139
src/components/treeview/modules.vue
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
<template>
|
||||||
|
<div class="module">
|
||||||
|
<div @click="clickItem()" class="vcd-treeview-item"
|
||||||
|
:class="module === globalLookup.currentModule ? 'vcd-treeview-selected' : ''">
|
||||||
|
<span class="module-tag-status" @click.stop="expandManage.click">
|
||||||
|
<div :class="expandManage.expandTagClass"></div>
|
||||||
|
</span>
|
||||||
|
<span class="iconfont icon-memory-chip"></span>
|
||||||
|
 {{ module.name }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="mods.length > 0" v-show="expandManage.expanded" class="vcd-subtree-wrapper">
|
||||||
|
<div style="width: 20px;"></div>
|
||||||
|
<div style="width: 100%;">
|
||||||
|
<modules
|
||||||
|
v-for="(child, index) in mods"
|
||||||
|
:module="child"
|
||||||
|
:key="index"
|
||||||
|
></modules>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/* eslint-disable */
|
||||||
|
import { reactive, onMounted } from 'vue';
|
||||||
|
import { emitter, globalLookup } from '@/hook/global';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "modules",
|
||||||
|
props: {
|
||||||
|
module: Object
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
const module = props.module;
|
||||||
|
globalLookup.initcurrentModule(module);
|
||||||
|
|
||||||
|
const signals = [];
|
||||||
|
const mods = [];
|
||||||
|
|
||||||
|
for (const wire of module.body) {
|
||||||
|
if (wire.body) {
|
||||||
|
mods.push(wire);
|
||||||
|
} else {
|
||||||
|
signals.push(wire);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickItem() {
|
||||||
|
emitter.emit('tree-view', signals);
|
||||||
|
// color change into selected
|
||||||
|
globalLookup.currentModule = module;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const expandManage = reactive({
|
||||||
|
expanded: true,
|
||||||
|
expandTagClass: mods.length === 0 ? '' : 'expand-tag',
|
||||||
|
click() {
|
||||||
|
this.expanded = !this.expanded;
|
||||||
|
if (this.expandTagClass) {
|
||||||
|
this.expandTagClass = this.expanded ? 'expand-tag' : 'collapse-tag';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
module,
|
||||||
|
mods,
|
||||||
|
signals,
|
||||||
|
clickItem,
|
||||||
|
expandManage,
|
||||||
|
globalLookup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.icon-memory-chip {
|
||||||
|
color: #FF7043;
|
||||||
|
}
|
||||||
|
|
||||||
|
.module {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vcd-subtree-wrapper {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vcd-treeview-item {
|
||||||
|
color: var(--sidebar-item-text);
|
||||||
|
cursor: pointer;
|
||||||
|
height: 27px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vcd-treeview-item::selection {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vcd-treeview-item:hover {
|
||||||
|
background-color: var(--vscode-button-hoverBackground);
|
||||||
|
border-radius: .3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vcd-treeview-selected {
|
||||||
|
background-color: var(--vscode-button-hoverBackground);
|
||||||
|
border-radius: .3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-tag-status {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand-tag {
|
||||||
|
height: 7px;
|
||||||
|
width: 7px;
|
||||||
|
border-top: solid 1.7px var(--sidebar-item-text);
|
||||||
|
border-left: solid 1.7px var(--sidebar-item-text);
|
||||||
|
transform: rotate(225deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapse-tag {
|
||||||
|
height: 7px;
|
||||||
|
width: 7px;
|
||||||
|
border-top: solid 1.7px var(--sidebar-item-text);
|
||||||
|
border-left: solid 1.7px var(--sidebar-item-text);
|
||||||
|
transform: rotate(135deg);
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,17 +1,91 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="tree-view-search-wrapper">
|
<div class="tree-view-search-wrapper">
|
||||||
<input type="text" class="tree-view-search" placeholder="Search Signal">
|
<div>
|
||||||
|
<el-input
|
||||||
|
:placeholder="t('search-signal')"
|
||||||
|
size="large"
|
||||||
|
v-model="searchManage.content"
|
||||||
|
input-style="font-size: 16px;"
|
||||||
|
@input="safeSearch"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="search-result" v-if="searchManage.content.trim().length > 0">
|
||||||
|
<div v-if="searchManage.searchResult.length > 0">
|
||||||
|
<div class="search-result-item"
|
||||||
|
v-for="(searchResult, index) in searchManage.searchResult"
|
||||||
|
:key="index"
|
||||||
|
:class="globalLookup.currentWires.has(searchResult.module) ? 'vcd-treeview-selected' : ''"
|
||||||
|
v-html="searchResult.htmlString"
|
||||||
|
@click="clickItem(searchResult.module)">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
{{ t('search-nothing') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { reactive } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { globalSetting, globalLookup } from '@/hook/global';
|
||||||
|
import { debounceWrapper, makeSearchResultItem } from '@/hook/utils';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'tree-view-search',
|
name: 'tree-view-search',
|
||||||
setup() {
|
setup() {
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const searchManage = reactive({
|
||||||
|
content: '',
|
||||||
|
searchResult: []
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function search() {
|
||||||
|
const searchString = searchManage.content.trim();
|
||||||
|
if (searchString.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
searchManage.searchResult = [];
|
||||||
|
|
||||||
|
const stacks = [ { name: '', body: globalLookup.topModules } ];
|
||||||
|
const searchRule = new Set(globalSetting.searchScope);
|
||||||
|
const caseSensitivity = globalSetting.caseSensitivity;
|
||||||
|
while (stacks.length > 0) {
|
||||||
|
const p = stacks.pop();
|
||||||
|
if (p.body && p.body.length) {
|
||||||
|
p.body.forEach(mod => stacks.push(mod));
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchResultItem = makeSearchResultItem(searchString, p, searchRule, caseSensitivity);
|
||||||
|
if (searchResultItem) {
|
||||||
|
searchManage.searchResult.push(searchResultItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickItem(signal) {
|
||||||
|
if (!signal.link) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (globalLookup.currentWires.has(signal)) {
|
||||||
|
globalLookup.currentWires.delete(signal);
|
||||||
|
} else {
|
||||||
|
globalLookup.currentWires.add(signal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const safeSearch = debounceWrapper(search, 500);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
searchManage,
|
||||||
|
safeSearch,
|
||||||
|
globalLookup,
|
||||||
|
debounceWrapper,
|
||||||
|
t,
|
||||||
|
clickItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -19,33 +93,39 @@ export default {
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.tree-view-search-wrapper {
|
.tree-view-search-wrapper {
|
||||||
height: 30px;
|
min-height: 30px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tree-view-search[type="text"] {
|
.search-result {
|
||||||
color: var(--input-foreground);
|
overflow-x: hidden;
|
||||||
background-color: var(--input-background);
|
overflow-y: scroll;
|
||||||
border-radius: var(--input-radius);
|
padding: 10px;
|
||||||
border: .5px solid var(--input-border);
|
margin: 10px;
|
||||||
font-size: 18px;
|
max-height: 40vh;
|
||||||
padding: 6px;
|
|
||||||
width: 98%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tree-view-search[type="text"]:focus {
|
.search-result-item {
|
||||||
color: var(--input-active-foreground);
|
display: flex;
|
||||||
background-color: var(--input-active-background);
|
align-items: center;
|
||||||
border: .5px solid var(--input-active-border);
|
height: 25px;
|
||||||
outline: none;
|
margin: 3px;
|
||||||
|
padding-left: 3px;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tree-view-search[type="text"]:hover {
|
.search-result-item:hover {
|
||||||
background-color: var(--input-hover);
|
background-color: var(--vscode-button-hoverBackground);
|
||||||
|
border-radius: .3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tree-view-search[type="text"]::placeholder {
|
.dep-arrow {
|
||||||
color: var(--input-placeholder);
|
height: 7px;
|
||||||
|
width: 7px;
|
||||||
|
border-top: solid 1.7px var(--sidebar-item-text);
|
||||||
|
border-left: solid 1.7px var(--sidebar-item-text);
|
||||||
|
transform: rotate(135deg);
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-left: 3px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,139 +1,105 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="signal">
|
<div>
|
||||||
<div @click="clickItem()" class="vcd-treeview-item"
|
<div>{{ t('signal') }}({{signals.content.length}})</div>
|
||||||
:class="signal === globalLookup.currentSignal ? 'vcd-treeview-selected' : ''">
|
<hr>
|
||||||
<span class="signal-tag-status" @click.stop="expandManage.click">
|
<div class="vcd-signal-signals-display">
|
||||||
<div :class="expandManage.expandTagClass"></div>
|
<div v-for="(signal, index) in signals.content" :key="index"
|
||||||
</span>
|
@click="clickItem(signal)"
|
||||||
<span class="iconfont icon-memory-chip"></span>
|
class="vcd-signal-signal-item"
|
||||||
 {{ signal.name }}
|
:class="globalLookup.currentWires.has(signal) ? 'vcd-treeview-selected' : ''">
|
||||||
|
<div><span class="iconfont icon-wave-square"></span> {{ signal.name }}</div>
|
||||||
|
<div>
|
||||||
|
<div :class="signal.caption ? 'vcd-signal-signal-caption' : ''">
|
||||||
|
{{ signal.caption }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="signal.body" v-show="expandManage.expanded" class="vcd-subtree-wrapper">
|
|
||||||
<div style="width: 20px;"></div>
|
|
||||||
<div style="width: 100%;">
|
|
||||||
<signals
|
|
||||||
v-for="(child, index) in signal.body"
|
|
||||||
:signal="child"
|
|
||||||
:key="index"
|
|
||||||
></signals>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
/* eslint-disable */
|
import { reactive } from 'vue';
|
||||||
import { reactive, onMounted } from 'vue';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import { emitter, globalLookup } from '@/hook/global';
|
import { emitter, globalLookup } from '@/hook/global';
|
||||||
|
|
||||||
|
/* eslint-disable */
|
||||||
export default {
|
export default {
|
||||||
name: "signals",
|
name: 'signals',
|
||||||
props: {
|
props: {},
|
||||||
signal: Object
|
setup() {
|
||||||
},
|
const { t } = useI18n();
|
||||||
setup(props) {
|
|
||||||
const signal = props.signal;
|
|
||||||
const signalChildern = signal.body;
|
|
||||||
|
|
||||||
globalLookup.initCurrentSignal(signal);
|
// signal : link, name, size, type
|
||||||
|
const signals = reactive({
|
||||||
|
content: []
|
||||||
|
});
|
||||||
|
|
||||||
const wires = [];
|
emitter.on('tree-view', sendWires => {
|
||||||
signal.body = [];
|
signals.content.length = 0;
|
||||||
for (const wire of signalChildern) {
|
for (const signal of sendWires) {
|
||||||
if (wire.body) {
|
const caption = signal.size === 1 ? '' : `${signal.size - 1}:0`;
|
||||||
signal.body.push(wire);
|
signals.content.push({
|
||||||
} else {
|
name: signal.name,
|
||||||
wires.push(wire);
|
caption
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function clickItem() {
|
|
||||||
emitter.emit('tree-view', wires);
|
|
||||||
// color change into selected
|
|
||||||
globalLookup.currentSignal = signal;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const expandManage = reactive({
|
|
||||||
expanded: true,
|
|
||||||
expandTagClass: signal.body.length === 0 ? '' : 'expand-tag',
|
|
||||||
click() {
|
|
||||||
this.expanded = !this.expanded;
|
|
||||||
if (this.expandTagClass) {
|
|
||||||
this.expandTagClass = this.expanded ? 'expand-tag' : 'collapse-tag';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function clickItem(signal) {
|
||||||
|
if (globalLookup.currentWires.has(signal)) {
|
||||||
|
globalLookup.currentWires.delete(signal);
|
||||||
|
} else {
|
||||||
|
globalLookup.currentWires.add(signal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
signal,
|
signals,
|
||||||
clickItem,
|
clickItem,
|
||||||
expandManage,
|
globalLookup,
|
||||||
globalLookup
|
t
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.icon-memory-chip {
|
.icon-wave-square {
|
||||||
color: #FF7043;
|
color: #00F600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.signal {
|
.vcd-signal-signals-display {
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vcd-subtree-wrapper {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vcd-treeview-item {
|
|
||||||
color: var(--sidebar-item-text);
|
color: var(--sidebar-item-text);
|
||||||
cursor: pointer;
|
padding: 0px 8px;
|
||||||
height: 27px;
|
}
|
||||||
|
|
||||||
|
.vcd-signal-signal-item {
|
||||||
|
margin: 3px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 25px;
|
||||||
|
padding-left: 3px;
|
||||||
|
cursor: pointer;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vcd-treeview-item::selection {
|
|
||||||
|
.vcd-signal-signal-item::selection {
|
||||||
background: none;
|
background: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vcd-treeview-item:hover {
|
.vcd-signal-signal-item:hover {
|
||||||
background-color: var(--vscode-button-hoverBackground);
|
background-color: var(--vscode-button-hoverBackground);
|
||||||
border-radius: .3em;
|
border-radius: .3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vcd-treeview-selected {
|
.vcd-signal-signal-caption {
|
||||||
background-color: var(--vscode-button-hoverBackground);
|
color: var(--sidebar-item-text);
|
||||||
border-radius: .3em;
|
border-radius: .5em;
|
||||||
}
|
background-color: var(--color-deepPurple);
|
||||||
|
padding: 3px;
|
||||||
.signal-tag-status {
|
font-size: 15px;
|
||||||
width: 25px;
|
|
||||||
height: 25px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-around;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.expand-tag {
|
|
||||||
height: 7px;
|
|
||||||
width: 7px;
|
|
||||||
border-top: solid 1.7px var(--sidebar-item-text);
|
|
||||||
border-left: solid 1.7px var(--sidebar-item-text);
|
|
||||||
transform: rotate(225deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.collapse-tag {
|
|
||||||
height: 7px;
|
|
||||||
width: 7px;
|
|
||||||
border-top: solid 1.7px var(--sidebar-item-text);
|
|
||||||
border-left: solid 1.7px var(--sidebar-item-text);
|
|
||||||
transform: rotate(135deg);
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,94 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div>Signals({{wires.content.length}})</div>
|
|
||||||
<hr>
|
|
||||||
<div class="vcd-signal-wires-display">
|
|
||||||
<div v-for="(wire, index) in wires.content" :key="index"
|
|
||||||
@click="clickItem(wire)"
|
|
||||||
class="vcd-signal-wire-item"
|
|
||||||
:class="globalLookup.currentWires.has(wire) ? 'vcd-treeview-selected' : ''">
|
|
||||||
<div><span class="iconfont icon-wave-square"></span> {{ wire.name }}</div>
|
|
||||||
<div>
|
|
||||||
<div :class="wire.caption ? 'vcd-signal-wire-caption' : ''">
|
|
||||||
{{ wire.caption }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
import { emitter, globalLookup } from '@/hook/global';
|
|
||||||
|
|
||||||
/* eslint-disable */
|
|
||||||
export default {
|
|
||||||
name: 'wires',
|
|
||||||
props: {},
|
|
||||||
setup() {
|
|
||||||
// wire : link, name, size, type
|
|
||||||
const wires = reactive({
|
|
||||||
content: []
|
|
||||||
});
|
|
||||||
|
|
||||||
emitter.on('tree-view', sendWires => {
|
|
||||||
wires.content.length = 0;
|
|
||||||
for (const wire of sendWires) {
|
|
||||||
const caption = wire.size === 1 ? '' : `${wire.size - 1}:0`;
|
|
||||||
wires.content.push({
|
|
||||||
name: wire.name,
|
|
||||||
caption
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function clickItem(wire) {
|
|
||||||
if (globalLookup.currentWires.has(wire)) {
|
|
||||||
globalLookup.currentWires.delete(wire);
|
|
||||||
} else {
|
|
||||||
globalLookup.currentWires.add(wire);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
wires,
|
|
||||||
clickItem,
|
|
||||||
globalLookup
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.icon-wave-square {
|
|
||||||
color: #00F600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vcd-signal-wires-display {
|
|
||||||
color: var(--sidebar-item-text);
|
|
||||||
padding: 0px 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vcd-signal-wire-item {
|
|
||||||
margin: 3px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
height: 25px;
|
|
||||||
cursor: pointer;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vcd-signal-wire-item:hover {
|
|
||||||
background-color: var(--vscode-button-hoverBackground);
|
|
||||||
border-radius: .3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vcd-signal-wire-caption {
|
|
||||||
color: var(--sidebar-item-text);
|
|
||||||
border-radius: .5em;
|
|
||||||
background-color: var(--color-deepPurple);
|
|
||||||
padding: 3px;
|
|
||||||
font-size: 15px;
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -5,21 +5,31 @@ const emitter = mitt();
|
|||||||
|
|
||||||
// 用于记载全局的一些对象,以便在不同组件中比较 ID
|
// 用于记载全局的一些对象,以便在不同组件中比较 ID
|
||||||
const globalLookup = reactive({
|
const globalLookup = reactive({
|
||||||
|
// 所有的顶层文件
|
||||||
|
topModules: [],
|
||||||
// 当前选中的 信号,也就是 tree-view 左列的,默认是第一个。不可复选。
|
// 当前选中的 信号,也就是 tree-view 左列的,默认是第一个。不可复选。
|
||||||
currentSignal: undefined,
|
currentModule: undefined,
|
||||||
// 当前选中的某个 信号 的 数据。可复选。
|
// 当前选中的某个 信号 的 数据。可复选。
|
||||||
currentWires: new Set(),
|
currentWires: new Set(),
|
||||||
|
|
||||||
initCurrentSignal(signal) {
|
initcurrentModule(module) {
|
||||||
if (this.currentSignal === undefined && signal) {
|
if (this.currentModule === undefined && module) {
|
||||||
this.currentSignal = signal;
|
this.currentModule = module;
|
||||||
|
}
|
||||||
|
// 创造 parent
|
||||||
|
if (module.body && module.body instanceof Array) {
|
||||||
|
for (const childModule of module.body) {
|
||||||
|
childModule.parent = module;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const globalSetting = {
|
const globalSetting = reactive({
|
||||||
caseSensitivity: false
|
caseSensitivity: false,
|
||||||
};
|
searchMode: 'so', // so, mo, sm
|
||||||
|
searchScope: ['wire', 'reg']
|
||||||
|
})
|
||||||
|
|
||||||
export {
|
export {
|
||||||
emitter,
|
emitter,
|
||||||
|
@ -28,7 +28,72 @@ async function readVcdFile() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function debounceWrapper(fn, delay) {
|
||||||
|
let timer
|
||||||
|
return function () {
|
||||||
|
if (timer) {
|
||||||
|
clearTimeout(timer)
|
||||||
|
}
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
fn()
|
||||||
|
}, delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param { string } searchString
|
||||||
|
* @param {{
|
||||||
|
* kind: 'var' | 'scope',
|
||||||
|
* type: 'wire' | 'reg' | 'module',
|
||||||
|
* name: string,
|
||||||
|
* size?: number,
|
||||||
|
* link?: string
|
||||||
|
* }} module
|
||||||
|
* @param { Set<string> } searchScope
|
||||||
|
* @param { boolean } caseSensitivity
|
||||||
|
* @returns { { htmlString: string, module } | null }
|
||||||
|
*/
|
||||||
|
function makeSearchResultItem(searchString, module, searchScope, caseSensitivity) {
|
||||||
|
if (searchScope.has(module.type)) {
|
||||||
|
let pattern = module.name;
|
||||||
|
if (!caseSensitivity) {
|
||||||
|
pattern = pattern.toLowerCase();
|
||||||
|
searchString = searchString.toLowerCase();
|
||||||
|
}
|
||||||
|
if (pattern.includes(searchString)) {
|
||||||
|
let p = module;
|
||||||
|
const deps = [];
|
||||||
|
while (p) {
|
||||||
|
if (p.name && p.type) {
|
||||||
|
deps.push(p);
|
||||||
|
}
|
||||||
|
p = p.parent;
|
||||||
|
}
|
||||||
|
let htmlString = '';
|
||||||
|
for (let i = deps.length - 1; i >= 0; -- i) {
|
||||||
|
const mod = deps[i];
|
||||||
|
if (mod.type === 'module') {
|
||||||
|
htmlString += '<span class="iconfont icon-memory-chip"></span> ' + mod.name;
|
||||||
|
} else {
|
||||||
|
htmlString += '<span class="iconfont icon-wave-square"></span> ' + mod.name;
|
||||||
|
}
|
||||||
|
if (i > 0) {
|
||||||
|
htmlString += '<div class="dep-arrow"></div>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
htmlString,
|
||||||
|
module
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getVcdStream,
|
getVcdStream,
|
||||||
readVcdFile
|
readVcdFile,
|
||||||
|
debounceWrapper,
|
||||||
|
makeSearchResultItem
|
||||||
};
|
};
|
17
src/i18n/en.json
Normal file
17
src/i18n/en.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"module": "Modules",
|
||||||
|
"signal": "Signals",
|
||||||
|
"search-signal": "Search Signal",
|
||||||
|
"language-setting": "Language",
|
||||||
|
"search-setting": "Search",
|
||||||
|
"case-sensitivity": "case sensitivity",
|
||||||
|
"search-mode": "search mode",
|
||||||
|
"search-scope": "search scope",
|
||||||
|
"signal-only": "Signal Only",
|
||||||
|
"module-only": "Module Only",
|
||||||
|
"signal-module": "Signal + Module",
|
||||||
|
"general-setting": "General",
|
||||||
|
"current-version": "current version",
|
||||||
|
"search-nothing": "find nothing",
|
||||||
|
"copyright": "The copyright of this software belongs to <a href=\"https://github.com/Digital-EDA\" target=\"_blank\">Digital-IDE</a> project team. Welcome to <a href=\"https://github.com/Digital-EDA/Digital-IDE\">Star</a>."
|
||||||
|
}
|
12
src/i18n/index.js
Normal file
12
src/i18n/index.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { createI18n } from 'vue-i18n';
|
||||||
|
|
||||||
|
import en from './en.json';
|
||||||
|
import zh from './zh.json';
|
||||||
|
|
||||||
|
const i18n = createI18n({
|
||||||
|
legacy: false,
|
||||||
|
locale: 'en',
|
||||||
|
messages: { en, zh }
|
||||||
|
});
|
||||||
|
|
||||||
|
export default i18n;
|
17
src/i18n/zh.json
Normal file
17
src/i18n/zh.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"module": "模块",
|
||||||
|
"signal": "信号",
|
||||||
|
"search-signal": "搜索信号",
|
||||||
|
"language-setting": "语言",
|
||||||
|
"search-setting": "搜索",
|
||||||
|
"case-sensitivity": "区分大小写",
|
||||||
|
"search-mode": "搜索模式",
|
||||||
|
"search-scope": "搜索范围",
|
||||||
|
"signal-only": "信号",
|
||||||
|
"module-only": "模块",
|
||||||
|
"signal-module": "信号 + 模块",
|
||||||
|
"general-setting": "通用",
|
||||||
|
"current-version": "当前版本",
|
||||||
|
"search-nothing": "没有找到任何符号",
|
||||||
|
"copyright": "本软件版权归 <a href=\"https://github.com/Digital-EDA\" target=\"_blank\">Digital-IDE</a> 项目组所有,欢迎 <a href=\"https://github.com/Digital-EDA/Digital-IDE\">Star</a>。"
|
||||||
|
}
|
12
src/main.js
12
src/main.js
@ -1,4 +1,10 @@
|
|||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue';
|
||||||
import App from './App.vue'
|
import App from './App.vue';
|
||||||
|
import i18n from './i18n';
|
||||||
|
import ElementPlus from 'element-plus'
|
||||||
|
import 'element-plus/dist/index.css'
|
||||||
|
|
||||||
createApp(App).mount('#app')
|
createApp(App)
|
||||||
|
.use(i18n)
|
||||||
|
.use(ElementPlus)
|
||||||
|
.mount('#app')
|
14
webpack.config.js
Normal file
14
webpack.config.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
const AutoImport = require('unplugin-auto-import/webpack')
|
||||||
|
const Components = require('unplugin-vue-components/webpack')
|
||||||
|
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
plugins: [
|
||||||
|
AutoImport({
|
||||||
|
resolvers: [ElementPlusResolver()],
|
||||||
|
}),
|
||||||
|
Components({
|
||||||
|
resolvers: [ElementPlusResolver()],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user