feat: active widget on the tab

This commit is contained in:
Qiuxia Fan 2022-01-10 14:43:07 +08:00
parent d41ace3580
commit cce5a8826c
3 changed files with 56 additions and 27 deletions

View File

@ -105,9 +105,13 @@ export const dashboardStore = defineStore({
this.layout[idx].children?.push(i); this.layout[idx].children?.push(i);
}, },
addTabWidget(tabIndex: number) { addTabWidget(tabIndex: number) {
const activedGridItem = this.activedGridItem.split("-")[0];
const idx = this.layout.findIndex( const idx = this.layout.findIndex(
(d: LayoutConfig) => d.i === this.activedGridItem (d: LayoutConfig) => d.i === activedGridItem
); );
if (idx < 0) {
return;
}
const { children } = this.layout[idx].children[tabIndex]; const { children } = this.layout[idx].children[tabIndex];
const newWidget = { const newWidget = {
x: 0, x: 0,

View File

@ -49,29 +49,30 @@ limitations under the License. -->
<Icon size="sm" iconName="clearclose" @click="removeTab" /> <Icon size="sm" iconName="clearclose" @click="removeTab" />
</div> </div>
</div> </div>
<grid-layout <div class="tab-layout">
v-model:layout="state.layout" <grid-layout
:col-num="24" v-model:layout="state.layout"
:row-height="10" :col-num="24"
:is-draggable="true" :row-height="10"
:is-resizable="true" :is-draggable="true"
@layout-updated="layoutUpdatedEvent" :is-resizable="true"
> @layout-updated="layoutUpdatedEvent"
<grid-item
v-for="item in state.layout"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
:key="item.i"
> >
<Widget <grid-item
:data="item" v-for="item in state.layout"
:active="dashboardStore.activedGridItem === item.i" :x="item.x"
/> :y="item.y"
</grid-item> :w="item.w"
</grid-layout> :h="item.h"
:i="item.i"
:key="item.i"
@click="clickTabGrid($event, item)"
:class="{ active: activeTabWidget === item.i }"
>
<Widget :data="item" :active="activeTabWidget === item.i" />
</grid-item>
</grid-layout>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { defineProps, reactive, ref, watch } from "vue"; import { defineProps, reactive, ref, watch } from "vue";
@ -82,13 +83,14 @@ import { useDashboardStore } from "@/store/modules/dashboard";
const props = defineProps({ const props = defineProps({
data: { data: {
type: Object as PropType<{ type: string; children: any[]; i: string }>, type: Object as PropType<LayoutConfig>,
default: () => ({ children: [] }), default: () => ({ children: [] }),
}, },
active: { type: Boolean, default: false }, active: { type: Boolean, default: false },
}); });
const dashboardStore = useDashboardStore(); const dashboardStore = useDashboardStore();
const activeTabIndex = ref<number>(0); const activeTabIndex = ref<number>(0);
const activeTabWidget = ref<string>("0");
const editTabIndex = ref<number>(NaN); // edit tab item name const editTabIndex = ref<number>(NaN); // edit tab item name
const state = reactive<{ const state = reactive<{
layout: LayoutConfig[]; layout: LayoutConfig[];
@ -96,6 +98,7 @@ const state = reactive<{
layout: layout:
dashboardStore.layout[props.data.i].children[activeTabIndex.value].children, dashboardStore.layout[props.data.i].children[activeTabIndex.value].children,
}); });
function layoutUpdatedEvent(newLayout: LayoutConfig[]) { function layoutUpdatedEvent(newLayout: LayoutConfig[]) {
state.layout = newLayout; state.layout = newLayout;
} }
@ -120,8 +123,20 @@ function handleClick(el: any) {
} }
editTabIndex.value = NaN; editTabIndex.value = NaN;
} }
function addTabWidget() { function addTabWidget(e: any) {
e.stopPropagation();
activeTabWidget.value = String(state.layout.length);
dashboardStore.addTabWidget(activeTabIndex.value); dashboardStore.addTabWidget(activeTabIndex.value);
dashboardStore.activeGridItem(
`${props.data.i}-${activeTabIndex.value}-${activeTabWidget.value}`
);
}
function clickTabGrid(e: any, item: LayoutConfig) {
e.stopPropagation();
activeTabWidget.value = item.i;
dashboardStore.activeGridItem(
`${props.data.i}-${activeTabIndex.value}-${item.i}`
);
} }
document.body.addEventListener("click", handleClick, false); document.body.addEventListener("click", handleClick, false);
watch( watch(
@ -148,8 +163,8 @@ watch(
.tab-name { .tab-name {
max-width: 80px; max-width: 80px;
height: 25px; height: 20px;
line-height: 25px; line-height: 20px;
outline: none; outline: none;
color: #333; color: #333;
font-style: normal; font-style: normal;
@ -206,4 +221,13 @@ watch(
box-shadow: 0px 1px 4px 0px #00000029; box-shadow: 0px 1px 4px 0px #00000029;
border-radius: 5px; border-radius: 5px;
} }
.tab-layout {
height: calc(100% - 55px);
overflow: auto;
}
.vue-grid-item.active {
border: 1px solid #409eff;
}
</style> </style>

View File

@ -55,6 +55,7 @@ export default defineComponent({
dashboardStore.setLayout(newLayout); dashboardStore.setLayout(newLayout);
} }
function clickGrid(item: LayoutConfig) { function clickGrid(item: LayoutConfig) {
console.log(item);
dashboardStore.activeGridItem(item.i); dashboardStore.activeGridItem(item.i);
} }
return { return {