mirror of
https://github.com/Tencent/tdesign-vue-next-starter.git
synced 2024-12-23 08:06:31 +08:00
Merge pull request #98 from Tencent/feat/multiple-tabs-support
feat: 支持多标签tab页的功能
This commit is contained in:
commit
f2d9752190
4
.env
4
.env
|
@ -1,3 +1,3 @@
|
||||||
VITE_SOME_KEY=123
|
VITE_SOME_KEY=123
|
||||||
# 打包路径
|
# 打包路径 根据项目不同按需配置
|
||||||
VITE_BASE_URL = /
|
VITE_BASE_URL = ./
|
17
.eslintrc
17
.eslintrc
|
@ -15,10 +15,7 @@
|
||||||
"defineProps": "readonly",
|
"defineProps": "readonly",
|
||||||
"defineEmits": "readonly"
|
"defineEmits": "readonly"
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": ["vue", "@typescript-eslint"],
|
||||||
"vue",
|
|
||||||
"@typescript-eslint"
|
|
||||||
],
|
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"parser": "@typescript-eslint/parser",
|
"parser": "@typescript-eslint/parser",
|
||||||
"sourceType": "module",
|
"sourceType": "module",
|
||||||
|
@ -28,12 +25,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"import/extensions": [
|
"import/extensions": [".js", ".jsx", ".ts", ".tsx"]
|
||||||
".js",
|
|
||||||
".jsx",
|
|
||||||
".ts",
|
|
||||||
".tsx"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-console": "off",
|
"no-console": "off",
|
||||||
|
@ -48,7 +40,7 @@
|
||||||
"import/no-unresolved": "off",
|
"import/no-unresolved": "off",
|
||||||
"import/no-extraneous-dependencies": "off",
|
"import/no-extraneous-dependencies": "off",
|
||||||
"import/prefer-default-export": "off",
|
"import/prefer-default-export": "off",
|
||||||
|
"import/first": "off", // https://github.com/vuejs/vue-eslint-parser/issues/58
|
||||||
"@typescript-eslint/no-explicit-any": "off",
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||||
"vue/first-attribute-linebreak": 0
|
"vue/first-attribute-linebreak": 0
|
||||||
|
@ -61,8 +53,7 @@
|
||||||
"vue/require-default-prop": 0,
|
"vue/require-default-prop": 0,
|
||||||
"vue/multi-word-component-names": 0,
|
"vue/multi-word-component-names": 0,
|
||||||
"vue/no-reserved-props": 0,
|
"vue/no-reserved-props": 0,
|
||||||
"vue/no-v-html": 0,
|
"vue/no-v-html": 0
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,6 +8,7 @@ export default {
|
||||||
isFooterAside: false,
|
isFooterAside: false,
|
||||||
isSidebarFixed: true,
|
isSidebarFixed: true,
|
||||||
isHeaderFixed: true,
|
isHeaderFixed: true,
|
||||||
|
isUseTabsRouter: false,
|
||||||
showHeader: true,
|
showHeader: true,
|
||||||
backgroundTheme: 'blueGrey',
|
backgroundTheme: 'blueGrey',
|
||||||
brandTheme: 'default',
|
brandTheme: 'default',
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { RouteRecordName } from 'vue-router';
|
||||||
import STYLE_CONFIG from '@/config/style';
|
import STYLE_CONFIG from '@/config/style';
|
||||||
|
|
||||||
export interface ResDataType {
|
export interface ResDataType {
|
||||||
|
@ -37,3 +38,17 @@ export interface NotificationItem {
|
||||||
date: string;
|
date: string;
|
||||||
quality: string;
|
quality: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TRouterInfo {
|
||||||
|
path: string;
|
||||||
|
routeIdx?: number;
|
||||||
|
title?: string;
|
||||||
|
name?: RouteRecordName;
|
||||||
|
isAlive?: boolean;
|
||||||
|
isHome?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TTabRouterType {
|
||||||
|
isRefreshing: boolean;
|
||||||
|
tabRouterList: Array<TRouterInfo>;
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,30 @@
|
||||||
<template>
|
<template>
|
||||||
<router-view v-slot="{ Component }">
|
<router-view v-if="!isRefreshing" v-slot="{ Component }">
|
||||||
<transition name="fade" mode="out-in">
|
<transition name="fade" mode="out-in">
|
||||||
|
<keep-alive :include="aliveViews">
|
||||||
<component :is="Component" />
|
<component :is="Component" />
|
||||||
|
</keep-alive>
|
||||||
</transition>
|
</transition>
|
||||||
</router-view>
|
</router-view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ComputedRef } from 'vue';
|
||||||
|
import { useTabsRouterStore } from '@/store';
|
||||||
|
|
||||||
|
const aliveViews = computed(() => {
|
||||||
|
const tabsRouterStore = useTabsRouterStore();
|
||||||
|
const { tabRouters } = tabsRouterStore;
|
||||||
|
|
||||||
|
return tabRouters.filter((route) => route.isAlive).map((route) => route.name);
|
||||||
|
}) as ComputedRef<string[]>;
|
||||||
|
|
||||||
|
const isRefreshing = computed(() => {
|
||||||
|
const tabsRouterStore = useTabsRouterStore();
|
||||||
|
const { refreshing } = tabsRouterStore;
|
||||||
|
return refreshing;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import '@/style/variables';
|
@import '@/style/variables';
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
import { defineComponent, computed } from 'vue';
|
import { defineComponent, computed, nextTick, onMounted, watch } from 'vue';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { usePermissionStore, useSettingStore } from '@/store';
|
import { usePermissionStore, useSettingStore, useTabsRouterStore } from '@/store';
|
||||||
|
|
||||||
import TDesignHeader from './components/Header.vue';
|
import LayoutHeader from './components/Header.vue';
|
||||||
import TDesignBreadcrumb from './components/Breadcrumb.vue';
|
import LayoutBreadcrumb from './components/Breadcrumb.vue';
|
||||||
import TDesignFooter from './components/Footer.vue';
|
import LayoutFooter from './components/Footer.vue';
|
||||||
import TDesignSideNav from './components/SideNav';
|
import LayoutSideNav from './components/SideNav';
|
||||||
import TDesignContent from './components/Content.vue';
|
import LayoutContent from './components/Content.vue';
|
||||||
|
import Setting from './setting.vue';
|
||||||
|
|
||||||
import { prefix } from '@/config/global';
|
import { prefix } from '@/config/global';
|
||||||
import TdesignSetting from './setting.vue';
|
|
||||||
import '@/style/layout.less';
|
import '@/style/layout.less';
|
||||||
|
|
||||||
const name = `${prefix}-base-layout`;
|
const name = `${prefix}-base-layout`;
|
||||||
|
@ -19,8 +20,10 @@ export default defineComponent({
|
||||||
name,
|
name,
|
||||||
setup() {
|
setup() {
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
const permissionStore = usePermissionStore();
|
const permissionStore = usePermissionStore();
|
||||||
const settingStore = useSettingStore();
|
const settingStore = useSettingStore();
|
||||||
|
const tabsRouterStore = useTabsRouterStore();
|
||||||
const { routers: menuRouters } = storeToRefs(permissionStore);
|
const { routers: menuRouters } = storeToRefs(permissionStore);
|
||||||
const setting = storeToRefs(settingStore);
|
const setting = storeToRefs(settingStore);
|
||||||
|
|
||||||
|
@ -57,10 +60,59 @@ export default defineComponent({
|
||||||
return newMenuRouters;
|
return newMenuRouters;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const appendNewRoute = () => {
|
||||||
|
const {
|
||||||
|
path,
|
||||||
|
meta: { title },
|
||||||
|
name,
|
||||||
|
} = route;
|
||||||
|
tabsRouterStore.appendTabRouterList({ path, title: title as string, name, isAlive: true });
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
appendNewRoute();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => route.path,
|
||||||
|
() => {
|
||||||
|
appendNewRoute();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleRemove = ({ value: path, index }) => {
|
||||||
|
const { tabRouters } = tabsRouterStore;
|
||||||
|
const nextRouter = tabRouters[index + 1] || tabRouters[index - 1];
|
||||||
|
|
||||||
|
tabsRouterStore.subtractCurrentTabRouter({ path, routeIdx: index });
|
||||||
|
if (path === route.path) {
|
||||||
|
router.push(nextRouter.path);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const handleChangeCurrentTab = (path: string) => {
|
||||||
|
router.push(path);
|
||||||
|
};
|
||||||
|
const handleRefresh = (currentPath: string, routeIdx: number) => {
|
||||||
|
tabsRouterStore.toggleTabRouterAlive(routeIdx);
|
||||||
|
nextTick(() => {
|
||||||
|
tabsRouterStore.toggleTabRouterAlive(routeIdx);
|
||||||
|
router.replace({ path: currentPath });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const handleCloseAhead = (path: string, routeIdx: number) => {
|
||||||
|
tabsRouterStore.subtractTabRouterAhead({ path, routeIdx });
|
||||||
|
};
|
||||||
|
const handleCloseBehind = (path: string, routeIdx: number) => {
|
||||||
|
tabsRouterStore.subtractTabRouterBehind({ path, routeIdx });
|
||||||
|
};
|
||||||
|
const handleCloseOther = (path: string, routeIdx: number) => {
|
||||||
|
tabsRouterStore.subtractTabRouterOther({ path, routeIdx });
|
||||||
|
};
|
||||||
|
|
||||||
const renderSidebar = () => {
|
const renderSidebar = () => {
|
||||||
return (
|
return (
|
||||||
settingStore.showSidebar && (
|
settingStore.showSidebar && (
|
||||||
<TDesignSideNav
|
<LayoutSideNav
|
||||||
showLogo={settingStore.showSidebarLogo}
|
showLogo={settingStore.showSidebarLogo}
|
||||||
layout={settingStore.layout}
|
layout={settingStore.layout}
|
||||||
isFixed={settingStore.isSidebarFixed}
|
isFixed={settingStore.isSidebarFixed}
|
||||||
|
@ -75,7 +127,7 @@ export default defineComponent({
|
||||||
const renderHeader = () => {
|
const renderHeader = () => {
|
||||||
return (
|
return (
|
||||||
settingStore.showHeader && (
|
settingStore.showHeader && (
|
||||||
<TDesignHeader
|
<LayoutHeader
|
||||||
showLogo={settingStore.showHeaderLogo}
|
showLogo={settingStore.showHeaderLogo}
|
||||||
theme={settingStore.displayMode}
|
theme={settingStore.displayMode}
|
||||||
layout={settingStore.layout}
|
layout={settingStore.layout}
|
||||||
|
@ -90,18 +142,72 @@ export default defineComponent({
|
||||||
const renderFooter = () => {
|
const renderFooter = () => {
|
||||||
return (
|
return (
|
||||||
<t-footer class={`${prefix}-footer-layout`}>
|
<t-footer class={`${prefix}-footer-layout`}>
|
||||||
<TDesignFooter />
|
<LayoutFooter />
|
||||||
</t-footer>
|
</t-footer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderContent = () => {
|
const renderContent = () => {
|
||||||
const { showBreadcrumb, showFooter } = settingStore;
|
const { showBreadcrumb, showFooter, isUseTabsRouter } = settingStore;
|
||||||
|
const { tabRouters } = tabsRouterStore;
|
||||||
return (
|
return (
|
||||||
<t-layout class={[`${prefix}-layout`]}>
|
<t-layout class={[`${prefix}-layout`]}>
|
||||||
|
{isUseTabsRouter && (
|
||||||
|
<t-tabs
|
||||||
|
theme="card"
|
||||||
|
class={`${prefix}-layout-tabs-nav`}
|
||||||
|
value={route.path}
|
||||||
|
onChange={handleChangeCurrentTab}
|
||||||
|
style={{ maxWidth: '100%', position: 'fixed', overflow: 'visible' }}
|
||||||
|
onRemove={handleRemove}
|
||||||
|
>
|
||||||
|
{tabRouters.map((router: any, idx: number) => (
|
||||||
|
<t-tab-panel
|
||||||
|
value={router.path}
|
||||||
|
key={`${router.path}_${idx}`}
|
||||||
|
label={
|
||||||
|
<t-dropdown
|
||||||
|
trigger="context-menu"
|
||||||
|
minColumnWidth={128}
|
||||||
|
popupProps={{ overlayClassName: 'router-tabs-dropdown' }}
|
||||||
|
v-slots={{
|
||||||
|
dropdown: () => (
|
||||||
|
<t-dropdown-menu>
|
||||||
|
<t-dropdown-item onClick={() => handleRefresh(router.path, idx)}>
|
||||||
|
<t-icon name="refresh" />
|
||||||
|
刷新
|
||||||
|
</t-dropdown-item>
|
||||||
|
{idx > 0 && (
|
||||||
|
<t-dropdown-item onClick={() => handleCloseAhead(router.path, idx)}>
|
||||||
|
<t-icon name="arrow-left" />
|
||||||
|
关闭左侧
|
||||||
|
</t-dropdown-item>
|
||||||
|
)}
|
||||||
|
{idx < tabRouters.length - 1 && (
|
||||||
|
<t-dropdown-item onClick={() => handleCloseBehind(router.path, idx)}>
|
||||||
|
<t-icon name="arrow-right" />
|
||||||
|
关闭右侧
|
||||||
|
</t-dropdown-item>
|
||||||
|
)}
|
||||||
|
<t-dropdown-item onClick={() => handleCloseOther(router.path, idx)}>
|
||||||
|
<t-icon name="close-circle" />
|
||||||
|
关闭其它
|
||||||
|
</t-dropdown-item>
|
||||||
|
</t-dropdown-menu>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{!router.isHome ? router.title : <t-icon name="home" />}
|
||||||
|
</t-dropdown>
|
||||||
|
}
|
||||||
|
removable={!router.isHome}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</t-tabs>
|
||||||
|
)}
|
||||||
<t-content class={`${prefix}-content-layout`}>
|
<t-content class={`${prefix}-content-layout`}>
|
||||||
{showBreadcrumb && <TDesignBreadcrumb />}
|
{showBreadcrumb && <LayoutBreadcrumb />}
|
||||||
<TDesignContent />
|
<LayoutContent />
|
||||||
</t-content>
|
</t-content>
|
||||||
{showFooter && renderFooter()}
|
{showFooter && renderFooter()}
|
||||||
</t-layout>
|
</t-layout>
|
||||||
|
@ -134,7 +240,7 @@ export default defineComponent({
|
||||||
<t-layout class={this.mainLayoutCls}>{[sidebar, content]}</t-layout>
|
<t-layout class={this.mainLayoutCls}>{[sidebar, content]}</t-layout>
|
||||||
</t-layout>
|
</t-layout>
|
||||||
)}
|
)}
|
||||||
<TdesignSetting />
|
<Setting />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -82,6 +82,9 @@
|
||||||
<t-form-item label="显示 Footer" name="showFooter">
|
<t-form-item label="显示 Footer" name="showFooter">
|
||||||
<t-switch v-model="formData.showFooter" />
|
<t-switch v-model="formData.showFooter" />
|
||||||
</t-form-item>
|
</t-form-item>
|
||||||
|
<t-form-item label="使用 多标签Tab页" name="isUseTabsRouter">
|
||||||
|
<t-switch v-model="formData.isUseTabsRouter"></t-switch>
|
||||||
|
</t-form-item>
|
||||||
</t-form>
|
</t-form>
|
||||||
<div class="setting-info">
|
<div class="setting-info">
|
||||||
<p>请复制后手动修改配置文件: /src/config/style.ts</p>
|
<p>请复制后手动修改配置文件: /src/config/style.ts</p>
|
||||||
|
|
|
@ -202,6 +202,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'DashboardBase',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, watch, ref, onUnmounted, nextTick, computed } from 'vue';
|
import { onMounted, watch, ref, onUnmounted, nextTick, computed } from 'vue';
|
||||||
|
|
||||||
|
@ -386,9 +393,11 @@ const getRankClass = (index: number) => {
|
||||||
return ['dashboard-rank', { 'dashboard-rank__top': index < 3 }];
|
return ['dashboard-rank', { 'dashboard-rank__top': index < 3 }];
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import './index.less';
|
@import './index.less';
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
@import '@/style/variables.less';
|
@import '@/style/variables.less';
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,13 @@
|
||||||
</card>
|
</card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'DashboardDetail',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { nextTick, onMounted, onUnmounted, watch, computed } from 'vue';
|
import { nextTick, onMounted, onUnmounted, watch, computed } from 'vue';
|
||||||
|
|
||||||
|
@ -149,6 +156,7 @@ const onMaterialChange = (value: string[]) => {
|
||||||
lineChart.setOption(getFolderLineDataSet({ dateTime: value, ...chartColors.value }));
|
lineChart.setOption(getFolderLineDataSet({ dateTime: value, ...chartColors.value }));
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import url('./index.less');
|
@import url('./index.less');
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -109,6 +109,13 @@
|
||||||
</t-dialog>
|
</t-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'DetailAdvanced',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
import { prefix } from '@/config/global';
|
import { prefix } from '@/config/global';
|
||||||
|
@ -175,6 +182,7 @@ const onConfirm = () => {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import url('./index.less');
|
@import url('./index.less');
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -26,6 +26,13 @@
|
||||||
</card>
|
</card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'DetailBase',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Card from '@/components/card/index.vue';
|
import Card from '@/components/card/index.vue';
|
||||||
|
|
||||||
|
@ -108,6 +115,7 @@ const BASE_INFO_DATA = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import url('./index.less');
|
@import url('./index.less');
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -68,6 +68,13 @@
|
||||||
</t-dialog>
|
</t-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'DetailDeploy',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, ref, watch, computed } from 'vue';
|
import { onMounted, onUnmounted, ref, watch, computed } from 'vue';
|
||||||
|
|
||||||
|
@ -195,6 +202,7 @@ const deleteClickOp = (e) => {
|
||||||
data.value.splice(e.rowIndex, 1);
|
data.value.splice(e.rowIndex, 1);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import url('../base/index.less');
|
@import url('../base/index.less');
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -49,6 +49,13 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'DetailSecondary',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
|
@ -114,6 +121,7 @@ const deleteMsg = () => {
|
||||||
store.setMsgData(changeMsg);
|
store.setMsgData(changeMsg);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import url('./index.less');
|
@import url('./index.less');
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -156,6 +156,13 @@
|
||||||
</div>
|
</div>
|
||||||
</t-form>
|
</t-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'FormBase',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { MessagePlugin } from 'tdesign-vue-next';
|
import { MessagePlugin } from 'tdesign-vue-next';
|
||||||
|
@ -190,6 +197,7 @@ const formatResponse = (res) => {
|
||||||
return { ...res, error: '上传失败,请重试', url: res.url };
|
return { ...res, error: '上传失败,请重试', url: res.url };
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import url('./index.less');
|
@import url('./index.less');
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -139,6 +139,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'FormStep',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
@ -186,6 +193,7 @@ const complete = () => {
|
||||||
router.replace({ path: '/detail/advanced' });
|
router.replace({ path: '/detail/advanced' });
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import url('./index.less');
|
@import url('./index.less');
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -66,6 +66,13 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'ListBase',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, computed } from 'vue';
|
import { ref, onMounted, computed } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
@ -171,6 +178,7 @@ const handleClickDelete = (row: { rowIndex: any }) => {
|
||||||
confirmVisible.value = true;
|
confirmVisible.value = true;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import '@/style/variables';
|
@import '@/style/variables';
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,13 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'ListCard',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, onMounted } from 'vue';
|
import { ref, computed, onMounted } from 'vue';
|
||||||
import { SearchIcon } from 'tdesign-icons-vue-next';
|
import { SearchIcon } from 'tdesign-icons-vue-next';
|
||||||
|
@ -141,6 +148,7 @@ const handleManageProduct = (product) => {
|
||||||
formData.value = { ...product, status: product?.isSetup ? '1' : '0' };
|
formData.value = { ...product, status: product?.isSetup ? '1' : '0' };
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import '@/style/variables.less';
|
@import '@/style/variables.less';
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<common-table />
|
<common-table />
|
||||||
</template>
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'ListFilter',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import CommonTable from '../components/CommonTable.vue';
|
import CommonTable from '../components/CommonTable.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -15,6 +15,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'ListTree',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { SearchIcon } from 'tdesign-icons-vue-next';
|
import { SearchIcon } from 'tdesign-icons-vue-next';
|
||||||
|
@ -34,6 +41,7 @@ const onInput = () => {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import '@/style/variables.less';
|
@import '@/style/variables.less';
|
||||||
.table-tree-container {
|
.table-tree-container {
|
||||||
|
|
|
@ -22,6 +22,11 @@
|
||||||
<footer class="copyright">Copyright @ 2021-2022 Tencent. All Rights Reserved</footer>
|
<footer class="copyright">Copyright @ 2021-2022 Tencent. All Rights Reserved</footer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'LoginIndex',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
@ -35,6 +40,7 @@ const switchType = (val: string) => {
|
||||||
type.value = val;
|
type.value = val;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
@import url('./index.less');
|
@import url('./index.less');
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -3,7 +3,11 @@
|
||||||
<t-button @click="() => $router.push('/')">返回首页</t-button>
|
<t-button @click="() => $router.push('/')">返回首页</t-button>
|
||||||
</result>
|
</result>
|
||||||
</template>
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'Result403',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Result from '@/components/result/index.vue';
|
import Result from '@/components/result/index.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -4,6 +4,12 @@
|
||||||
</result>
|
</result>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'Result404',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Result from '@/components/result/index.vue';
|
import Result from '@/components/result/index.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -3,7 +3,11 @@
|
||||||
<t-button @click="() => $router.push('/')">返回首页</t-button>
|
<t-button @click="() => $router.push('/')">返回首页</t-button>
|
||||||
</result>
|
</result>
|
||||||
</template>
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'Result500',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Result from '@/components/result/index.vue';
|
import Result from '@/components/result/index.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -18,11 +18,16 @@
|
||||||
</div>
|
</div>
|
||||||
</result>
|
</result>
|
||||||
</template>
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'ResultBrowserIncompatible',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Result from '@/components/result/index.vue';
|
import Result from '@/components/result/index.vue';
|
||||||
import Thumbnail from '@/components/thumbnail/index.vue';
|
import Thumbnail from '@/components/thumbnail/index.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import '@/style/variables.less';
|
@import '@/style/variables.less';
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'ResultFail',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import '@/style/variables.less';
|
@import '@/style/variables.less';
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,11 @@
|
||||||
</result>
|
</result>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'ResultNetworkError',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Result from '@/components/result/index.vue';
|
import Result from '@/components/result/index.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -9,7 +9,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'ResultSuccess',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import '@/style/variables.less';
|
@import '@/style/variables.less';
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,11 @@
|
||||||
</t-col>
|
</t-col>
|
||||||
</t-row>
|
</t-row>
|
||||||
</template>
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
export default {
|
||||||
|
name: 'UserIndex',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { nextTick, onMounted, onUnmounted, watch, computed } from 'vue';
|
import { nextTick, onMounted, onUnmounted, watch, computed } from 'vue';
|
||||||
import * as echarts from 'echarts/core';
|
import * as echarts from 'echarts/core';
|
||||||
|
@ -172,6 +177,7 @@ watch(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import url('./index.less');
|
@import url('./index.less');
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -11,13 +11,13 @@ export default [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'base',
|
path: 'base',
|
||||||
name: 'dashboardBase',
|
name: 'DashboardBase',
|
||||||
component: () => import('@/pages/dashboard/base/index.vue'),
|
component: () => import('@/pages/dashboard/base/index.vue'),
|
||||||
meta: { title: '概览仪表盘' },
|
meta: { title: '概览仪表盘' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'detail',
|
path: 'detail',
|
||||||
name: 'dashboardDetail',
|
name: 'DashboardDetail',
|
||||||
component: () => import('@/pages/dashboard/detail/index.vue'),
|
component: () => import('@/pages/dashboard/detail/index.vue'),
|
||||||
meta: { title: '统计报表' },
|
meta: { title: '统计报表' },
|
||||||
},
|
},
|
||||||
|
|
|
@ -13,25 +13,25 @@ export default [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'base',
|
path: 'base',
|
||||||
name: 'listBase',
|
name: 'ListBase',
|
||||||
component: () => import('@/pages/list/base/index.vue'),
|
component: () => import('@/pages/list/base/index.vue'),
|
||||||
meta: { title: '基础列表页' },
|
meta: { title: '基础列表页' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'card',
|
path: 'card',
|
||||||
name: 'listCard',
|
name: 'ListCard',
|
||||||
component: () => import('@/pages/list/card/index.vue'),
|
component: () => import('@/pages/list/card/index.vue'),
|
||||||
meta: { title: '卡片列表页' },
|
meta: { title: '卡片列表页' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'filter',
|
path: 'filter',
|
||||||
name: 'listFilter',
|
name: 'ListFilter',
|
||||||
component: () => import('@/pages/list/filter/index.vue'),
|
component: () => import('@/pages/list/filter/index.vue'),
|
||||||
meta: { title: '筛选列表页' },
|
meta: { title: '筛选列表页' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'tree',
|
path: 'tree',
|
||||||
name: 'listTree',
|
name: 'ListTree',
|
||||||
component: () => import('@/pages/list/tree/index.vue'),
|
component: () => import('@/pages/list/tree/index.vue'),
|
||||||
meta: { title: '树状筛选列表页' },
|
meta: { title: '树状筛选列表页' },
|
||||||
},
|
},
|
||||||
|
@ -46,13 +46,13 @@ export default [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'base',
|
path: 'base',
|
||||||
name: 'formBase',
|
name: 'FormBase',
|
||||||
component: () => import('@/pages/form/base/index.vue'),
|
component: () => import('@/pages/form/base/index.vue'),
|
||||||
meta: { title: '基础表单页' },
|
meta: { title: '基础表单页' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'step',
|
path: 'step',
|
||||||
name: 'formStep',
|
name: 'FormStep',
|
||||||
component: () => import('@/pages/form/step/index.vue'),
|
component: () => import('@/pages/form/step/index.vue'),
|
||||||
meta: { title: '分步表单页' },
|
meta: { title: '分步表单页' },
|
||||||
},
|
},
|
||||||
|
@ -67,25 +67,25 @@ export default [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'base',
|
path: 'base',
|
||||||
name: 'detailBase',
|
name: 'DetailBase',
|
||||||
component: () => import('@/pages/detail/base/index.vue'),
|
component: () => import('@/pages/detail/base/index.vue'),
|
||||||
meta: { title: '基础详情页' },
|
meta: { title: '基础详情页' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'advanced',
|
path: 'advanced',
|
||||||
name: 'detailAdvanced',
|
name: 'DetailAdvanced',
|
||||||
component: () => import('@/pages/detail/advanced/index.vue'),
|
component: () => import('@/pages/detail/advanced/index.vue'),
|
||||||
meta: { title: '多卡片详情页' },
|
meta: { title: '多卡片详情页' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'deploy',
|
path: 'deploy',
|
||||||
name: 'detailDeploy',
|
name: 'DetailDeploy',
|
||||||
component: () => import('@/pages/detail/deploy/index.vue'),
|
component: () => import('@/pages/detail/deploy/index.vue'),
|
||||||
meta: { title: '数据详情页' },
|
meta: { title: '数据详情页' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'secondary',
|
path: 'secondary',
|
||||||
name: 'detailSecondary',
|
name: 'DetailSecondary',
|
||||||
component: () => import('@/pages/detail/secondary/index.vue'),
|
component: () => import('@/pages/detail/secondary/index.vue'),
|
||||||
meta: { title: '二级详情页' },
|
meta: { title: '二级详情页' },
|
||||||
},
|
},
|
||||||
|
@ -100,43 +100,43 @@ export default [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'success',
|
path: 'success',
|
||||||
name: 'resultSuccess',
|
name: 'ResultSuccess',
|
||||||
component: () => import('@/pages/result/success/index.vue'),
|
component: () => import('@/pages/result/success/index.vue'),
|
||||||
meta: { title: '成功页' },
|
meta: { title: '成功页' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'fail',
|
path: 'fail',
|
||||||
name: 'resultFail',
|
name: 'ResultFail',
|
||||||
component: () => import('@/pages/result/fail/index.vue'),
|
component: () => import('@/pages/result/fail/index.vue'),
|
||||||
meta: { title: '失败页' },
|
meta: { title: '失败页' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'network-error',
|
path: 'network-error',
|
||||||
name: 'warningNetworkError',
|
name: 'ResultNetworkError',
|
||||||
component: () => import('@/pages/result/network-error/index.vue'),
|
component: () => import('@/pages/result/network-error/index.vue'),
|
||||||
meta: { title: '网络异常' },
|
meta: { title: '网络异常' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '403',
|
path: '403',
|
||||||
name: 'warning403',
|
name: 'Result403',
|
||||||
component: () => import('@/pages/result/403/index.vue'),
|
component: () => import('@/pages/result/403/index.vue'),
|
||||||
meta: { title: '无权限' },
|
meta: { title: '无权限' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '404',
|
path: '404',
|
||||||
name: 'warning404',
|
name: 'Result404',
|
||||||
component: () => import('@/pages/result/404/index.vue'),
|
component: () => import('@/pages/result/404/index.vue'),
|
||||||
meta: { title: '访问页面不存在页' },
|
meta: { title: '访问页面不存在页' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '500',
|
path: '500',
|
||||||
name: 'warning500',
|
name: 'Result500',
|
||||||
component: () => import('@/pages/result/500/index.vue'),
|
component: () => import('@/pages/result/500/index.vue'),
|
||||||
meta: { title: '服务器出错页' },
|
meta: { title: '服务器出错页' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'browser-incompatible',
|
path: 'browser-incompatible',
|
||||||
name: 'warningBrowserIncompatible',
|
name: 'ResultBrowserIncompatible',
|
||||||
component: () => import('@/pages/result/browser-incompatible/index.vue'),
|
component: () => import('@/pages/result/browser-incompatible/index.vue'),
|
||||||
meta: { title: '浏览器不兼容页' },
|
meta: { title: '浏览器不兼容页' },
|
||||||
},
|
},
|
||||||
|
|
|
@ -11,7 +11,7 @@ export default [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'index',
|
path: 'index',
|
||||||
name: 'userIndex',
|
name: 'UserIndex',
|
||||||
component: () => import('@/pages/user/index.vue'),
|
component: () => import('@/pages/user/index.vue'),
|
||||||
meta: { title: '个人中心' },
|
meta: { title: '个人中心' },
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,5 +8,6 @@ export * from './modules/notification';
|
||||||
export * from './modules/permission';
|
export * from './modules/permission';
|
||||||
export * from './modules/user';
|
export * from './modules/user';
|
||||||
export * from './modules/setting';
|
export * from './modules/setting';
|
||||||
|
export * from './modules/tabs-router';
|
||||||
|
|
||||||
export default store;
|
export default store;
|
||||||
|
|
51
src/store/modules/tabs-router.ts
Normal file
51
src/store/modules/tabs-router.ts
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { TRouterInfo, TTabRouterType } from '@/interface';
|
||||||
|
import { store } from '@/store';
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
tabRouterList: [{ path: '/dashboard/base', routeIdx: 0, title: '仪表盘', name: 'DashboardBase', isHome: true }],
|
||||||
|
isRefreshing: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useTabsRouterStore = defineStore('tabsRouter', {
|
||||||
|
state: () => state,
|
||||||
|
getters: {
|
||||||
|
tabRouters: (state: TTabRouterType) => state.tabRouterList,
|
||||||
|
refreshing: (state: TTabRouterType) => state.isRefreshing,
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
toggleTabRouterAlive(routeIdx: number) {
|
||||||
|
this.isRefreshing = !this.isRefreshing;
|
||||||
|
this.tabRouters[routeIdx].isAlive = !this.tabRouterList[routeIdx].isAlive;
|
||||||
|
},
|
||||||
|
appendTabRouterList(newRoute: TRouterInfo) {
|
||||||
|
if (!this.tabRouterList.find((route: TRouterInfo) => route.path === newRoute.path)) {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
this.tabRouterList = this.tabRouterList.concat(newRoute);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
subtractCurrentTabRouter(newRoute: TRouterInfo) {
|
||||||
|
const { routeIdx } = newRoute;
|
||||||
|
this.tabRouterList = this.tabRouterList.slice(0, routeIdx).concat(this.tabRouterList.slice(routeIdx + 1));
|
||||||
|
},
|
||||||
|
subtractTabRouterBehind(newRoute: TRouterInfo) {
|
||||||
|
const { routeIdx } = newRoute;
|
||||||
|
this.tabRouterList = this.tabRouterList.slice(0, routeIdx + 1);
|
||||||
|
},
|
||||||
|
subtractTabRouterAhead(newRoute: TRouterInfo) {
|
||||||
|
const { routeIdx } = newRoute;
|
||||||
|
this.tabRouterList = this.tabRouterList.slice(routeIdx);
|
||||||
|
},
|
||||||
|
subtractTabRouterOther(newRoute: TRouterInfo) {
|
||||||
|
const { routeIdx } = newRoute;
|
||||||
|
this.tabRouterList = [this.tabRouterList?.[routeIdx]];
|
||||||
|
},
|
||||||
|
removeTabRouterList() {
|
||||||
|
this.tabRouterList = [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export function getTabsRouterStore() {
|
||||||
|
return useTabsRouterStore(store);
|
||||||
|
}
|
|
@ -56,13 +56,22 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-content-layout {
|
||||||
|
padding: @spacer-3;
|
||||||
|
}
|
||||||
|
|
||||||
&-layout{
|
&-layout{
|
||||||
height: calc(100vh - 64px);
|
height: calc(100vh - 64px);
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
&-tabs-nav {
|
||||||
|
max-width: 100%;
|
||||||
|
position: fixed;
|
||||||
|
overflow: visible;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
&-tabs-nav + .@{prefix}-content-layout {
|
||||||
|
padding-top: 48px + @spacer-3;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-content-layout {
|
|
||||||
padding: @spacer-3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-footer-layout {
|
&-footer-layout {
|
||||||
|
@ -151,6 +160,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.route-tabs-dropdown {
|
||||||
|
.t-icon {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.logo-container {
|
.logo-container {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user