refactor(路由与用户管理): 优化路由处理和用户登出逻辑
- 修改用户登出时的重定向逻辑,确保用户显式返回登录页,避免保留重定向参数 - 引入默认动态路由子项,简化路由配置 - 更新后端路由初始化逻辑,确保动态路由的正确处理 - 增强代码可读性,修复部分代码风格问题
This commit is contained in:
@@ -180,8 +180,8 @@ export default defineComponent({
|
|||||||
.then(async () => {
|
.then(async () => {
|
||||||
// 清除缓存/token等
|
// 清除缓存/token等
|
||||||
Session.clear();
|
Session.clear();
|
||||||
// 使用 reload 时,不需要调用 resetRoute() 重置路由
|
// 显式回到登录页,避免保留之前受保护页面的重定向参数
|
||||||
window.location.reload();
|
await router.replace('/login');
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
} else if (path === 'wareHouse') {
|
} else if (path === 'wareHouse') {
|
||||||
|
|||||||
@@ -4,14 +4,12 @@ import { useUserInfo } from '/@/stores/userInfo';
|
|||||||
import { useRequestOldRoutes } from '/@/stores/requestOldRoutes';
|
import { useRequestOldRoutes } from '/@/stores/requestOldRoutes';
|
||||||
import { Session } from '/@/utils/storage';
|
import { Session } from '/@/utils/storage';
|
||||||
import { NextLoading } from '/@/utils/loading';
|
import { NextLoading } from '/@/utils/loading';
|
||||||
import { dynamicRoutes, notFoundAndNoPower } from '/@/router/route';
|
import { dynamicRoutes, defaultDynamicRouteChildren, notFoundAndNoPower } from '/@/router/route';
|
||||||
import { formatTwoStageRoutes, formatFlatteningRoutes, router } from '/@/router/index';
|
import { formatTwoStageRoutes, formatFlatteningRoutes, router } from '/@/router/index';
|
||||||
import { useRoutesList } from '/@/stores/routesList';
|
import { useRoutesList } from '/@/stores/routesList';
|
||||||
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
|
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
|
||||||
import { getUserMenus } from '/@/api/system/menu/index';
|
import { getUserMenus } from '/@/api/system/menu/index';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const layouModules: any = import.meta.glob('../layout/routerView/*.{vue,tsx}');
|
const layouModules: any = import.meta.glob('../layout/routerView/*.{vue,tsx}');
|
||||||
const viewsModules: any = import.meta.glob('../views/**/*.{vue,tsx}');
|
const viewsModules: any = import.meta.glob('../views/**/*.{vue,tsx}');
|
||||||
|
|
||||||
@@ -43,11 +41,12 @@ export async function initBackEndControlRoutes() {
|
|||||||
await useUserInfo().setPermissions();
|
await useUserInfo().setPermissions();
|
||||||
// 获取路由菜单数据
|
// 获取路由菜单数据
|
||||||
await getBackEndControlRoutes();
|
await getBackEndControlRoutes();
|
||||||
let menuRoute = Session.get('userMenu')
|
let menuRoute = Session.get('userMenu');
|
||||||
// 存储接口原始路由(未处理component),根据需求选择使用
|
// 存储接口原始路由(未处理component),根据需求选择使用
|
||||||
useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(menuRoute)));
|
useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(menuRoute)));
|
||||||
// 处理路由(component),替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由
|
// 处理路由(component),替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由
|
||||||
dynamicRoutes[0].children?.push(...await backEndComponent(menuRoute));
|
dynamicRoutes[0].children = [...defaultDynamicRouteChildren];
|
||||||
|
dynamicRoutes[0].children?.push(...(await backEndComponent(menuRoute)));
|
||||||
// 添加动态路由
|
// 添加动态路由
|
||||||
await setAddRoute();
|
await setAddRoute();
|
||||||
// 设置路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
// 设置路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组
|
||||||
@@ -104,10 +103,10 @@ export async function setAddRoute() {
|
|||||||
* @returns 返回后端路由菜单数据
|
* @returns 返回后端路由菜单数据
|
||||||
*/
|
*/
|
||||||
export async function getBackEndControlRoutes() {
|
export async function getBackEndControlRoutes() {
|
||||||
let menuRoute = Session.get('userMenu')
|
let menuRoute = Session.get('userMenu');
|
||||||
let permissions = Session.get('permissions')
|
let permissions = Session.get('permissions');
|
||||||
if (!menuRoute || !permissions) {
|
if (!menuRoute || !permissions) {
|
||||||
await refreshBackEndControlRoutes()
|
await refreshBackEndControlRoutes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,10 +118,10 @@ export async function getBackEndControlRoutes() {
|
|||||||
export async function refreshBackEndControlRoutes() {
|
export async function refreshBackEndControlRoutes() {
|
||||||
// 获取路由
|
// 获取路由
|
||||||
await getUserMenus().then((res: any) => {
|
await getUserMenus().then((res: any) => {
|
||||||
Session.set('userMenu',res.data.menuList)
|
Session.set('userMenu', res.data.menuList);
|
||||||
Session.set('permissions',res.data.permissions)
|
Session.set('permissions', res.data.permissions);
|
||||||
})
|
});
|
||||||
await useUserInfo().setPermissions()
|
await useUserInfo().setPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,16 +139,16 @@ export function setBackEndControlRefreshRoutes() {
|
|||||||
* @returns 返回处理成函数后的 component
|
* @returns 返回处理成函数后的 component
|
||||||
*/
|
*/
|
||||||
export function backEndComponent(routes: any) {
|
export function backEndComponent(routes: any) {
|
||||||
if (!routes) return;
|
if (!routes) return [];
|
||||||
return routes.map((item: any) => {
|
return routes.map((item: any) => {
|
||||||
if (item.children && item.children.length > 0) {
|
if (item.children && item.children.length > 0) {
|
||||||
item.children.some((ci: any) => {
|
item.children.some((ci: any) => {
|
||||||
if (!ci.meta.isHide) {
|
if (!ci.meta.isHide) {
|
||||||
item.redirect = ci
|
item.redirect = ci;
|
||||||
return true
|
return true;
|
||||||
}
|
}
|
||||||
return false
|
return false;
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
if (item.component) item.component = dynamicImport(dynamicViewsModules, item.component as string);
|
if (item.component) item.component = dynamicImport(dynamicViewsModules, item.component as string);
|
||||||
item.children && backEndComponent(item.children);
|
item.children && backEndComponent(item.children);
|
||||||
|
|||||||
@@ -21,16 +21,7 @@ import { RouteRecordRaw } from 'vue-router';
|
|||||||
* @description 各字段请查看 `/@/views/system/menu/component/addMenu.vue 下的 ruleForm`
|
* @description 各字段请查看 `/@/views/system/menu/component/addMenu.vue 下的 ruleForm`
|
||||||
* @returns 返回路由菜单数据
|
* @returns 返回路由菜单数据
|
||||||
*/
|
*/
|
||||||
export const dynamicRoutes: Array<RouteRecordRaw> = [
|
export const defaultDynamicRouteChildren: Array<RouteRecordRaw> = [
|
||||||
{
|
|
||||||
path: '/',
|
|
||||||
name: '/',
|
|
||||||
component: () => import('/@/layout/index.vue'),
|
|
||||||
redirect: '/home',
|
|
||||||
meta: {
|
|
||||||
isKeepAlive: true,
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
{
|
||||||
path: '/home',
|
path: '/home',
|
||||||
name: 'home',
|
name: 'home',
|
||||||
@@ -61,7 +52,18 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
|
|||||||
icon: 'iconfont icon-diannao',
|
icon: 'iconfont icon-diannao',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
];
|
||||||
|
|
||||||
|
export const dynamicRoutes: Array<RouteRecordRaw> = [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: '/',
|
||||||
|
component: () => import('/@/layout/index.vue'),
|
||||||
|
redirect: '/home',
|
||||||
|
meta: {
|
||||||
|
isKeepAlive: true,
|
||||||
|
},
|
||||||
|
children: [...defaultDynamicRouteChildren],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -72,9 +72,9 @@ const performLogout = () => {
|
|||||||
Session.clear();
|
Session.clear();
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
isHandlingTokenExpired = false;
|
isHandlingTokenExpired = false;
|
||||||
// 跳转到后台管理登录页,确保完全刷新
|
// Hash 路由统一回登录页,避免跳到错误地址
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.href = '/login';
|
window.location.href = '/#/login';
|
||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,18 +6,15 @@
|
|||||||
<span>店铺维度统计</span>
|
<span>店铺维度统计</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<!-- 销售趋势图表 -->
|
|
||||||
<div class="chart-container">
|
|
||||||
<el-card>
|
|
||||||
<template #header>
|
|
||||||
<div class="card-header">销售趋势</div>
|
|
||||||
</template>
|
|
||||||
<div ref="salesChartRef" class="chart"></div>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
<!-- 搜索条件 -->
|
<!-- 搜索条件 -->
|
||||||
<div class="search-container">
|
<div class="search-container">
|
||||||
<el-form :model="searchParams" :inline="true" class="search-form">
|
<el-form :model="searchParams" :inline="true" class="search-form">
|
||||||
|
<el-form-item label="店铺">
|
||||||
|
<el-select v-model="searchParams.shopId" placeholder="选择店铺">
|
||||||
|
<el-option label="全部店铺" value="" />
|
||||||
|
<el-option v-for="shop in shopList" :key="shop.id" :label="shop.name" :value="shop.id" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="时间范围">
|
<el-form-item label="时间范围">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="searchParams.dateRange"
|
v-model="searchParams.dateRange"
|
||||||
@@ -26,14 +23,61 @@
|
|||||||
start-placeholder="开始日期"
|
start-placeholder="开始日期"
|
||||||
end-placeholder="结束日期"
|
end-placeholder="结束日期"
|
||||||
value-format="YYYY-MM-DD"
|
value-format="YYYY-MM-DD"
|
||||||
|
:shortcuts="[
|
||||||
|
{
|
||||||
|
text: '最近7天',
|
||||||
|
value: () => {
|
||||||
|
const end = new Date();
|
||||||
|
const start = new Date();
|
||||||
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
|
||||||
|
return [start, end];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '最近30天',
|
||||||
|
value: () => {
|
||||||
|
const end = new Date();
|
||||||
|
const start = new Date();
|
||||||
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
|
||||||
|
return [start, end];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '最近90天',
|
||||||
|
value: () => {
|
||||||
|
const end = new Date();
|
||||||
|
const start = new Date();
|
||||||
|
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
|
||||||
|
return [start, end];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '今年',
|
||||||
|
value: () => {
|
||||||
|
const end = new Date();
|
||||||
|
const start = new Date(new Date().getFullYear(), 0, 1);
|
||||||
|
return [start, end];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '去年',
|
||||||
|
value: () => {
|
||||||
|
const end = new Date(new Date().getFullYear() - 1, 11, 31);
|
||||||
|
const start = new Date(new Date().getFullYear() - 1, 0, 1);
|
||||||
|
return [start, end];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="时间粒度">
|
<el-form-item label="时间粒度">
|
||||||
<el-select v-model="searchParams.granularity" placeholder="选择时间粒度">
|
<el-select v-model="searchParams.granularity" placeholder="选择时间粒度">
|
||||||
|
<el-option label="小时" value="hour" />
|
||||||
<el-option label="日" value="day" />
|
<el-option label="日" value="day" />
|
||||||
<el-option label="周" value="week" />
|
<el-option label="周" value="week" />
|
||||||
<el-option label="月" value="month" />
|
<el-option label="月" value="month" />
|
||||||
<el-option label="季度" value="quarter" />
|
<el-option label="季度" value="quarter" />
|
||||||
|
<el-option label="年" value="year" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@@ -42,6 +86,15 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 销售趋势图表 -->
|
||||||
|
<div class="chart-container">
|
||||||
|
<el-card>
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">销售趋势 - {{ selectedShopName }}</div>
|
||||||
|
</template>
|
||||||
|
<div ref="salesChartRef" class="chart"></div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
<!-- 核心指标 -->
|
<!-- 核心指标 -->
|
||||||
<div class="stats-cards">
|
<div class="stats-cards">
|
||||||
<el-card class="stats-card">
|
<el-card class="stats-card">
|
||||||
@@ -73,19 +126,85 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 店铺列表 -->
|
||||||
|
<div class="shop-list">
|
||||||
|
<el-card>
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">店铺列表</div>
|
||||||
|
</template>
|
||||||
|
<el-table :data="shopList" style="width: 100%" @row-click="handleShopClick">
|
||||||
|
<el-table-column prop="id" label="店铺ID" width="100" />
|
||||||
|
<el-table-column prop="name" label="店铺名称" />
|
||||||
|
<el-table-column prop="type" label="店铺类型">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag size="small">{{ scope.row.type === 'physical' ? '线下店铺' : '线上店铺' }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="status" label="状态">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag size="small" :type="scope.row.status === 'active' ? 'success' : 'danger'">
|
||||||
|
{{ scope.row.status === 'active' ? '营业中' : '已关闭' }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="primary" size="small" @click="handleShopSelect(scope.row.id)">查看详情</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted } from 'vue';
|
import { ref, reactive, onMounted, computed, watch } from 'vue';
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
const searchParams = reactive({
|
const searchParams = reactive({
|
||||||
|
shopId: '',
|
||||||
dateRange: [],
|
dateRange: [],
|
||||||
granularity: 'day',
|
granularity: 'day',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 监听店铺选择变化,自动更新数据
|
||||||
|
watch(
|
||||||
|
() => searchParams.shopId,
|
||||||
|
() => {
|
||||||
|
handleSearch();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 监听时间粒度变化,自动更新数据
|
||||||
|
watch(
|
||||||
|
() => searchParams.granularity,
|
||||||
|
() => {
|
||||||
|
handleSearch();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
interface Shop {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
status: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const shopList = ref<Shop[]>([]);
|
||||||
|
|
||||||
|
// 模拟店铺列表数据
|
||||||
|
const getMockShopList = () => {
|
||||||
|
return [
|
||||||
|
{ id: '1', name: '店铺A', type: 'physical', status: 'active' },
|
||||||
|
{ id: '2', name: '店铺B', type: 'online', status: 'active' },
|
||||||
|
{ id: '3', name: '店铺C', type: 'physical', status: 'active' },
|
||||||
|
{ id: '4', name: '店铺D', type: 'online', status: 'active' },
|
||||||
|
{ id: '5', name: '店铺E', type: 'physical', status: 'active' },
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
const statsData = reactive({
|
const statsData = reactive({
|
||||||
totalSales: 1258000,
|
totalSales: 1258000,
|
||||||
orderCount: 5230,
|
orderCount: 5230,
|
||||||
@@ -100,15 +219,47 @@ const statsData = reactive({
|
|||||||
const salesChartRef = ref();
|
const salesChartRef = ref();
|
||||||
let salesChart: echarts.ECharts | null = null;
|
let salesChart: echarts.ECharts | null = null;
|
||||||
|
|
||||||
|
// 计算选中的店铺名称
|
||||||
|
const selectedShopName = computed(() => {
|
||||||
|
if (!searchParams.shopId) return '全部店铺';
|
||||||
|
const shop = shopList.value.find((s) => s.id === searchParams.shopId);
|
||||||
|
return shop ? shop.name : '未知店铺';
|
||||||
|
});
|
||||||
|
|
||||||
// 模拟销售趋势数据
|
// 模拟销售趋势数据
|
||||||
const getMockSalesTrend = () => {
|
const getMockSalesTrend = (shopId: string) => {
|
||||||
const dates = ['1月', '2月', '3月', '4月', '5月', '6月'];
|
let dates: string[] = [];
|
||||||
|
const baseSales = shopId ? 800000 + parseInt(shopId) * 100000 : 1000000;
|
||||||
|
const baseOrders = shopId ? 3000 + parseInt(shopId) * 500 : 4000;
|
||||||
|
|
||||||
|
// 根据时间粒度生成不同的时间标签
|
||||||
|
switch (searchParams.granularity) {
|
||||||
|
case 'hour':
|
||||||
|
dates = ['0时', '4时', '8时', '12时', '16时', '20时'];
|
||||||
|
break;
|
||||||
|
case 'day':
|
||||||
|
dates = ['1日', '5日', '10日', '15日', '20日', '25日'];
|
||||||
|
break;
|
||||||
|
case 'week':
|
||||||
|
dates = ['第1周', '第2周', '第3周', '第4周', '第5周', '第6周'];
|
||||||
|
break;
|
||||||
|
case 'month':
|
||||||
|
dates = ['1月', '2月', '3月', '4月', '5月', '6月'];
|
||||||
|
break;
|
||||||
|
case 'quarter':
|
||||||
|
dates = ['Q1', 'Q2', 'Q3', 'Q4'];
|
||||||
|
break;
|
||||||
|
case 'year':
|
||||||
|
dates = ['2022年', '2023年', '2024年', '2025年', '2026年'];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dates = ['1月', '2月', '3月', '4月', '5月', '6月'];
|
||||||
|
}
|
||||||
|
|
||||||
return dates.map((date) => ({
|
return dates.map((date) => ({
|
||||||
date,
|
date,
|
||||||
sales: 1000000 + Math.random() * 500000,
|
sales: baseSales + Math.random() * 500000,
|
||||||
orders: 4000 + Math.random() * 2000,
|
orders: baseOrders + Math.random() * 2000,
|
||||||
xx: 4000 + Math.random() * 2020,
|
|
||||||
ss: 4000 + Math.random() * 2010,
|
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -123,17 +274,28 @@ const handleSearch = () => {
|
|||||||
orderGrowth: 12.3 + Math.random() * 3,
|
orderGrowth: 12.3 + Math.random() * 3,
|
||||||
refundRateChange: -0.5 + Math.random() * 1,
|
refundRateChange: -0.5 + Math.random() * 1,
|
||||||
logisticsRateGrowth: 1.2 + Math.random() * 0.5,
|
logisticsRateGrowth: 1.2 + Math.random() * 0.5,
|
||||||
salesTrend: getMockSalesTrend(),
|
salesTrend: getMockSalesTrend(searchParams.shopId),
|
||||||
};
|
};
|
||||||
Object.assign(statsData, mockData);
|
Object.assign(statsData, mockData);
|
||||||
initSalesChart(mockData.salesTrend);
|
initSalesChart(mockData.salesTrend);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleReset = () => {
|
const handleReset = () => {
|
||||||
|
searchParams.shopId = '';
|
||||||
searchParams.dateRange = [];
|
searchParams.dateRange = [];
|
||||||
searchParams.granularity = 'day';
|
searchParams.granularity = 'day';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleShopClick = (shop: Shop) => {
|
||||||
|
searchParams.shopId = shop.id;
|
||||||
|
handleSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleShopSelect = (shopId: string) => {
|
||||||
|
searchParams.shopId = shopId;
|
||||||
|
handleSearch();
|
||||||
|
};
|
||||||
|
|
||||||
const initSalesChart = (salesTrend: any[]) => {
|
const initSalesChart = (salesTrend: any[]) => {
|
||||||
if (!salesChartRef.value) return;
|
if (!salesChartRef.value) return;
|
||||||
|
|
||||||
@@ -200,6 +362,9 @@ const initSalesChart = (salesTrend: any[]) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
// 初始化店铺列表
|
||||||
|
shopList.value = getMockShopList();
|
||||||
|
// 初始化数据
|
||||||
handleSearch();
|
handleSearch();
|
||||||
|
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
@@ -271,4 +436,8 @@ onMounted(() => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 400px;
|
height: 400px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shop-list {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user