fix: 优化组件渲染方式

This commit is contained in:
MTrun 2022-01-14 22:07:02 +08:00
parent 02c3f7478d
commit 3e511069b5
35 changed files with 359 additions and 232 deletions

View File

@ -0,0 +1,2 @@
import Echarts from './index.vue'
export { Echarts }

View File

@ -0,0 +1,13 @@
<template>
<div>
</div>
</template>
<script setup lang="ts">
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,12 @@
import node from './index.vue'
import image from '@/assets/images/chart/pie.png'
import { ConfigType } from '@/packages/index.d'
import { ChatCategoryEnum } from '../../index.d'
export const pieCommonConfig: ConfigType = {
key: 'PieCommon',
title: '饼图',
category: ChatCategoryEnum.PIE,
node: node,
image: image
}

View File

@ -0,0 +1,13 @@
<template>
<div>
饼图渲染
</div>
</template>
<script setup lang="ts">
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,3 @@
import { pieCommonConfig } from './PieCommon/index'
export default [pieCommonConfig]

View File

@ -1,11 +1,13 @@
import barCommon from './index.vue' import barCommon from './index.vue'
import barImg from '@/assets/images/chart/bar_y.png' import image from '@/assets/images/chart/bar_y.png'
import { ConfigType } from '@/packages/index.d' import { ConfigType } from '@/packages/index.d'
import { ChatCategoryEnum } from '../../index.d'
// 柱状图 // 柱状图
export const barCommonConfig: ConfigType = { export const barCommonConfig: ConfigType = {
key: 'Bar', key: 'BarCommon',
title: '基础', title: '基础',
category: ChatCategoryEnum.BAR,
node: barCommon, node: barCommon,
image: barImg image: image
} }

View File

@ -0,0 +1,3 @@
import { barCommonConfig } from './BarCommon/index'
export default [barCommonConfig]

View File

@ -0,0 +1,4 @@
export enum ChatCategoryEnum {
BAR = '柱状图',
PIE = '饼图'
}

View File

@ -1,3 +1,4 @@
import { barCommonConfig } from './bar/barCommon/index' import Bar from './Bar'
import Pie from './Pie'
export const BarList = [barCommonConfig] export const ChartList = [...Bar, ...Pie]

View File

@ -1,11 +1,12 @@
import BorderCommon from './index.vue' import BorderCommon from './index.vue'
import barImg from '@/assets/images/chart/bar_y.png' import image from '@/assets/images/chart/static.png'
import { ConfigType } from '@/packages/index.d' import { ConfigType } from '@/packages/index.d'
import { ChatCategoryEnum } from '../../index.d'
// 柱状图 export const borderCommonConfig: ConfigType = {
export const barCommonConfig: ConfigType = {
key: 'Border', key: 'Border',
title: '柱状图', title: '边框',
category: ChatCategoryEnum.Border,
node: BorderCommon, node: BorderCommon,
coverGraph: barImg image: image
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
柱状图组件渲染 边框
</div> </div>
</template> </template>

View File

@ -0,0 +1,3 @@
import { borderCommonConfig } from './BorderCommon/index'
export default [borderCommonConfig]

View File

@ -0,0 +1,3 @@
export enum ChatCategoryEnum {
Border = '边框',
}

View File

@ -1,3 +1,3 @@
import { barCommonConfig } from './border/borderCommon/index' import Border from './Border'
export const BarList = [barCommonConfig] export const DecorateList = [...Border]

0
src/packages/echarts/index.d.ts vendored Normal file
View File

View File

View File

@ -4,11 +4,23 @@ import { Component } from '@/router/types'
export type ConfigType = { export type ConfigType = {
key: string key: string
title: string title: string
category: string
node: Component node: Component
image: string image: string
[T: string]: unknown [T: string]: unknown
} }
export type PackagesType = {
Charts: ConfigType[] export enum PackagesCategoryEnum {
CHARTS = 'CHARTS',
TABLES = 'TABLES',
TEXTS = 'TEXTS',
DECORATES = 'DECORATES'
}
export type PackagesType = {
[PackagesCategoryEnum.CHARTS]: ConfigType[]
[PackagesCategoryEnum.TEXTS]: ConfigType[]
[PackagesCategoryEnum.TABLES]: ConfigType[]
[PackagesCategoryEnum.DECORATES]: ConfigType[]
} }

View File

@ -1,9 +1,11 @@
import { PackagesType } from '@/packages/index.d' import { PackagesCategoryEnum, PackagesType } from '@/packages/index.d'
import { BarList } from '@/packages/components/Chart/index' import { ChartList } from '@/packages/components/Chart/index'
import { DecorateList } from '@/packages/components/Decorate/index'
// 所有图表 // 所有图表
let packagesList: PackagesType = { let packagesList: PackagesType = {
Charts: BarList [PackagesCategoryEnum.CHARTS]: ChartList,
[PackagesCategoryEnum.DECORATES]: DecorateList
} }
export { packagesList } export { packagesList }

View File

@ -2,6 +2,7 @@ import { PackagesType, ConfigType } from '@/packages/index.d'
export { ConfigType } export { ConfigType }
export { PackagesType }
export interface PackagesStoreType { export interface PackagesStoreType {
packagesList: PackagesType packagesList: PackagesType
} }

View File

@ -1,5 +1,5 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { PackagesStoreType, ConfigType } from './packagesStore.d' import { PackagesStoreType, PackagesType } from './packagesStore.d'
import { packagesList } from '@/packages/index' import { packagesList } from '@/packages/index'
export const usePackagesStore = defineStore({ export const usePackagesStore = defineStore({
@ -8,11 +8,8 @@ export const usePackagesStore = defineStore({
packagesList packagesList
}), }),
getters: { getters: {
getPackagesList(): ConfigType | {} { getPackagesList(): PackagesType {
if (this.packagesList && this.packagesList.charts) { return this.packagesList
return this.packagesList.charts
}
return {}
} }
} }
}) })

View File

@ -1,3 +0,0 @@
import Charts from './index.vue'
export { Charts }

View File

@ -1,108 +0,0 @@
<template>
<div class="go-chart-common">
<n-menu
class="chart-menu-width"
v-model:value="selectValue"
:options="menuOptions"
:icon-size="16"
:indent="18"
/>
<div class="chart-content-list">
<div class="item-box" v-for="(item, index) in menuOptions" :key="index">
<div class="list-header">
<AppleControlBtn :mini="true" :disabled="true"></AppleControlBtn>
<n-text class="list-header-text" depth="3">{{ item.title }}</n-text>
</div>
<div class="list-center go-flex-center">
<img class="list-img" :src="item.image" />
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { reactive, ref, watchEffect } from 'vue'
import { AppleControlBtn } from '@/components/AppleControlBtn/index'
const props = defineProps({
packagesList: {
type: Array,
default: () => []
}
})
let menuOptions: any[] = reactive([])
watchEffect(() => {
console.log(props.packagesList)
menuOptions = props.packagesList
})
const selectValue = ref<string>(menuOptions[0]['key'])
</script>
<style lang="scss" scoped>
/* 此高度与 ContentBox 组件关联*/
$topHeight: 60px;
/* 列表项宽度 */
$itemWidth: 86%;
/* 图片高度 */
$imgWidth: 90%;
@include go('chart-common') {
display: flex;
height: calc(100vh - #{$--header-height} - #{$topHeight});
.chart-menu-width {
flex-shrink: 0;
@include filter-bg-color('background-color2-shallow');
}
.chart-content-list {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
padding: 10px 0;
.item-box {
margin: 0 7%;
margin-top: 5px;
width: $itemWidth;
overflow: hidden;
border-radius: 6px;
@include filter-bg-color('background-color2');
.list-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 4px 15px;
@include filter-bg-color('background-color4');
&-text {
font-size: 12px;
margin-left: 8px;
}
}
.list-center {
padding: 6px 0;
.list-img {
width: $imgWidth;
border-radius: 6px;
}
}
}
}
@include deep() {
.n-menu-item {
height: 30px;
&.n-menu-item--selected {
&::before {
background-color: rgba(0, 0, 0, 0);
}
}
.n-menu-item-content {
text-align: center;
padding: 0px 14px !important;
font-size: 12px !important;
}
}
}
}
</style>

View File

@ -1,3 +0,0 @@
import Decorates from './index.vue'
export { Decorates }

View File

@ -1,9 +0,0 @@
<template>
<div>
我是装饰咯
</div>
</template>
<script setup lang="Ts"></script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,3 @@
import ItemBox from './index.vue'
export { ItemBox }

View File

@ -0,0 +1,55 @@
<template>
<div class="item-box" v-for="(item, index) in menuOptions" :key="index">
<div class="list-header">
<AppleControlBtn :mini="true" :disabled="true"></AppleControlBtn>
<n-text class="list-header-text" depth="3">{{ item.title }}</n-text>
</div>
<div class="list-center go-flex-center">
<img class="list-img" :src="item.image" />
</div>
</div>
</template>
<script setup lang="ts">
import { AppleControlBtn } from '@/components/AppleControlBtn/index'
defineProps({
menuOptions: {
type: Array,
default: () => []
}
})
</script>
<style lang="scss" scoped>
/* 列表项宽度 */
$itemWidth: 86%;
/* 内容高度 */
$centerHeight: 80px;
.item-box {
margin: 0 7%;
margin-bottom: 15px;
width: $itemWidth;
overflow: hidden;
border-radius: 6px;
@include filter-bg-color('background-color2');
.list-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 2px 15px;
@include filter-bg-color('background-color3');
&-text {
font-size: 12px;
margin-left: 8px;
}
}
.list-center {
padding: 6px 0;
height: $centerHeight;
.list-img {
height: 100%;
border-radius: 6px;
}
}
}
</style>

View File

@ -0,0 +1,29 @@
import { reactive, ref, watch } from 'vue'
import { ConfigType } from '@/packages/index.d'
export const useHandleOptions = (packages) => {
watch(
// @ts-ignore
() => props.selectOptions,
(newData: { list: ConfigType[] }) => {
if (!newData) return
newData.list.forEach((e: ConfigType) => {
const value: ConfigType[] = (packages.categorys as any)[e.category]
// @ts-ignore
packages.categorys[e.category] =
value && value.length ? [...value, e] : [e]
})
for (const val in packages.categorys) {
packages.menuOptions.push({
key: val,
label: val
})
}
selectValue.value = packages.menuOptions[0]['key']
},
{
deep: true,
immediate: true
}
)
}

View File

@ -0,0 +1,3 @@
import OptionContent from './index.vue'
export { OptionContent }

View File

@ -0,0 +1,120 @@
<template>
<div class="go-chart-common">
<n-menu
class="chart-menu-width"
v-model:value="selectValue"
:options="packages.menuOptions"
:icon-size="16"
:indent="18"
@update:value="clickItemHandle"
/>
<div class="chart-content-list">
<ItemBox :menuOptions="packages.selectOptions" />
</div>
</div>
</template>
<script setup lang="ts">
import { reactive, ref, watch } from 'vue'
import { ItemBox } from '../ItemBox/index'
import { ConfigType } from '@/packages/index.d'
const props = defineProps({
selectOptions: {
type: Object,
default: () => []
}
})
let packages = reactive<{
[T: string]: any
}>({
//
menuOptions: [],
//
selectOptions: {},
//
categorys: {},
//
saveSelectOptions: {}
})
const selectValue = ref<string>()
//
const setSelectOptions = (categorys: any) => {
for (const val in categorys) {
packages.selectOptions = categorys[val]
break
}
}
watch(
// @ts-ignore
() => props.selectOptions,
(newData: { list: ConfigType[] }) => {
if (!newData) return
newData.list.forEach((e: ConfigType) => {
const value: ConfigType[] = (packages.categorys as any)[e.category]
// @ts-ignore
packages.categorys[e.category] =
value && value.length ? [...value, e] : [e]
})
for (const val in packages.categorys) {
packages.menuOptions.push({
key: val,
label: val
})
}
setSelectOptions(packages.categorys)
selectValue.value = packages.menuOptions[0]['key']
},
{
deep: true,
immediate: true
}
)
//
const clickItemHandle = (key: string) => {
packages.selectOptions = packages.categorys[key]
}
</script>
<style lang="scss" scoped>
/* 此高度与 ContentBox 组件关联*/
$topHeight: 60px;
$menuWidth: 65px;
@include go('chart-common') {
display: flex;
height: calc(100vh - #{$--header-height} - #{$topHeight});
.chart-menu-width {
width: $menuWidth;
flex-shrink: 0;
@include filter-bg-color('background-color2-shallow');
}
.chart-content-list {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
padding: 10px 0;
}
@include deep() {
.n-menu-item {
height: 30px;
&.n-menu-item--selected {
&::before {
background-color: rgba(0, 0, 0, 0);
}
}
.n-menu-item-content {
text-align: center;
padding: 0px 14px !important;
font-size: 12px !important;
}
}
}
}
</style>

View File

@ -1,3 +0,0 @@
import Tables from './index.vue'
export { Tables }

View File

@ -1,9 +0,0 @@
<template>
<div>
我是表格咯
</div>
</template>
<script setup lang="Ts"></script>
<style lang="scss" scoped></style>

View File

@ -1,3 +0,0 @@
import Texts from './index.vue'
export { Texts }

View File

@ -1,9 +0,0 @@
<template>
<div>
我是信息咯
</div>
</template>
<script setup lang="Ts"></script>
<style lang="scss" scoped></style>

View File

@ -1,11 +1,8 @@
import { reactive, ref } from 'vue' import { reactive, ref } from 'vue'
import { icon } from '@/plugins' import { icon } from '@/plugins'
import { Charts } from '../components/Charts'
import { Tables } from '../components/Tables'
import { Texts } from '../components/Texts'
import { Decorates } from '../components/Decorates'
import { renderLang, renderIcon } from '@/utils' import { renderLang, renderIcon } from '@/utils'
import { themeColor, setItem, getCharts } from './layoutHook' import { themeColor, setItem, getCharts } from './layoutHook'
import { PackagesCategoryEnum } from '@/packages/index.d'
// 图表 // 图表
import { usePackagesStore } from '@/store/modules/packagesStore/packagesStore' import { usePackagesStore } from '@/store/modules/packagesStore/packagesStore'
// 图标 // 图标
@ -18,65 +15,56 @@ const {
} = icon.carbon } = icon.carbon
// 图表 // 图表
const { packagesList } = usePackagesStore() const { getPackagesList } = usePackagesStore()
const menuOptions: any[] = reactive([]) const menuOptions = reactive<{
[T: string]: any
}>([])
const infoObj = new Map([ const packagesListObj = {
[ [PackagesCategoryEnum.CHARTS]: {
'Charts', icon: renderIcon(RoadmapIcon),
{ label: renderLang('图表')
icon: renderIcon(RoadmapIcon), },
label: renderLang('图表'), // [PackagesCategoryEnum.TEXTS]: {
node: Charts // icon: renderIcon(SpellCheckIcon),
} // label: renderLang('信息')
], // },
[ // [PackagesCategoryEnum.TABLES]: {
'Tables', // icon: renderIcon(GraphicalDataFlowIcon),
{ // label: renderLang('表格')
icon: renderIcon(TableSplitIcon), // },
label: renderLang('表格'), [PackagesCategoryEnum.DECORATES]: {
node: Tables icon: renderIcon(GraphicalDataFlowIcon),
} label: renderLang('装饰')
], }
[ }
'Texts',
{
icon: renderIcon(SpellCheckIcon),
label: renderLang('信息'),
node: Tables
}
],
[
'Decorates',
{
icon: renderIcon(GraphicalDataFlowIcon),
label: renderLang('表格'),
node: Decorates
}
],
])
Object.getOwnPropertyNames(packagesList).forEach(function (key) { // 处理列表
menuOptions.push({ const handlePackagesList = () => {
key: key, for (const val in getPackagesList) {
icon: infoObj.get(key)?.icon, menuOptions.push({
label: infoObj.get(key)?.label, key: val,
node: infoObj.get(key)?.node, // @ts-ignore
// @ts-ignore string 赋值给 any 的问题 icon: packagesListObj[val].icon,
packagesList: packagesList[key] // @ts-ignore
}) label: packagesListObj[val].label,
}) // @ts-ignore
list: getPackagesList[val]
})
}
}
handlePackagesList()
// 记录选中值 // 记录选中值
let beforeSelect: string = menuOptions[0]['key'] let beforeSelect: string = menuOptions[0]['key']
const selectValue = ref<string>(menuOptions[0]['key']) const selectValue = ref<string>(menuOptions[0]['key'])
// 选中的对象值 // 选中的对象值
const selecOptions = ref(menuOptions[0]) const selectOptions = ref(menuOptions[0])
// 点击 item // 点击 item
const clickItemHandle = <T extends { node: any }>(key: string, item: T) => { const clickItemHandle = (key: string, item: any) => {
// 处理渲染的 node selectOptions.value = item
selecOptions.value = item
// 处理折叠 // 处理折叠
if (beforeSelect === key) { if (beforeSelect === key) {
setItem('charts', !getCharts.value) setItem('charts', !getCharts.value)
@ -90,7 +78,7 @@ export {
getCharts, getCharts,
BarChartIcon, BarChartIcon,
themeColor, themeColor,
selecOptions, selectOptions,
selectValue, selectValue,
clickItemHandle, clickItemHandle,
menuOptions menuOptions

View File

@ -23,11 +23,14 @@
@update:value="clickItemHandle" @update:value="clickItemHandle"
/> />
<div class="menu-component-box"> <div class="menu-component-box">
<transition name="component-fade" mode="out-in"> <Skeleton
<keep-alive> :load="!selectOptions"
<component :is="selecOptions.node" :packagesList="selecOptions.packagesList" :key="selectValue"></component> round
</keep-alive> text
</transition> :repeat="2"
style="width: 90%;"
/>
<OptionContent v-if="selectOptions" :selectOptions="selectOptions" :key="selectValue" />
</div> </div>
</div> </div>
</aside> </aside>
@ -37,11 +40,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref, toRefs } from 'vue' import { reactive, ref, toRefs } from 'vue'
import { ContentBox } from '../ContentBox/index' import { ContentBox } from '../ContentBox/index'
import { OptionContent } from './components/OptionContent'
import { import {
getCharts, getCharts,
BarChartIcon, BarChartIcon,
themeColor, themeColor,
selecOptions, selectOptions,
selectValue, selectValue,
clickItemHandle, clickItemHandle,
menuOptions menuOptions