<template>
<div class="menu-page">
<el-container style="height: 100vh;">
<el-aside width="25%" style="background-color: #545c64; color: white; overflow-y: auto; padding: unset">
<el-menu
class="menuList"
@select="handleSelect"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
>
<el-menu-item index="1">全部</el-menu-item>
<el-menu-item v-for="item in groupedContent" :index="item.menuType" :key="item.menuType">{{item.menuType}}</el-menu-item>
</el-menu>
</el-aside>
<el-main>
<div v-for="(group, index) in groupedContent" :id="group.menuType" :ref="group.menuType">
<h2 >{{ group.menuType }}</h2>
<div v-for="item in group.items" :key="item.id">
<!-- 渲染内容,比如图片、描述等 -->
<p>{{ item.name }}</p>
<!-- 其他字段的显示 -->
</div>
</div>
</el-main>
</el-container>
</div>
</template>
<script>
import {listInsuranceAll, selectMenuList} from "@/api/insurance/insurance";
export default {
data() {
return {
selectedMenu: null, // 初始选中第一项
menus: [],
selectedDishes: [], // 当前选中的菜单类别对应的菜品列表
};
},
computed: {
groupedContent() {
// 使用 reduce 方法来分组内容
return this.selectedDishes.reduce((groups, item) => {
const menuType = item.menuType;
if (!groups[menuType]) {
groups[menuType] = { menuType, items: [] };
}
groups[menuType].items.push(item);
return groups;
}, {});
// 将对象转换为数组以便于在模板中迭代
return Object.values(this.groupedContent).sort((a, b) => {
// 你可以根据需要添加排序逻辑,比如根据 menuType 的顺序
return a.menuType.localeCompare(b.menuType);
});
},
},
created() {
this.selectAll();
this.selectMenus();
},
methods: {
selectAll() {
listInsuranceAll({'status': 'Y', 'menuType': -1}).then(res => {
this.selectedDishes = res.data;
})
},
handleSelect(index) {
console.log(index)
this.selectedMenu = index;
// 当前窗口正中心位置到指定dom位置的距离
document.getElementById(index).scrollIntoView();
}
}
};
</script>
<style scoped>
.menu-page {
display: flex;
flex-direction: row;
height: 85vh; /* 设置为视口高度 */
overflow: hidden; /* 隐藏超出的内容 */
padding: unset;
}
.el-aside {
/* 左侧菜单样式,可以根据需要调整 */
border-right: 1px solid #eee;
}
.el-main {
/* 右侧内容样式,可以根据需要调整 */
flex: 1;
overflow-y: auto; /* 允许垂直滚动 */
padding: 20px;
}
.dish-item {
margin-bottom: 10px;
}
</style>
方法一: 利用锚链接 / 直接改变hash值
说道页面内的跳转, 有过一段时间开发经验的同学想到的第一种方法应该就是这种,锚链接的使用方式也很简单, 如果想要跳转到id为targetBox 的 div
只需要加上window.location.hash = ‘’#targetBox" z或者加上如下点击链接就行:
点我就能跳转
但是使用此种方法也是有缺陷的, 因为它改变了页面的路由地址, 在vue的项目中,实现spa单页应用的原理就是通过修改hash值来改变加载内容, 一旦这样跳转, 页面路由就会出现问题,因此在vue项目中这种方式基本上无法使用.
方法二: 利用scrollTop
这种方式也是很常见的一种, 利用页面的高度差,跳转到特定位置, 如果高度差为100:
document.getElementById(‘targetBox’).scrollTop = 100
由于项目当中的语音对话框是实时更新的,这种方法在当高度差实时发生变换的时候并不好用.
方法三: 通过让元素获得焦点
这个方法之前没有用过,其原理是通过让元素支持focus事件,让元素获取焦点,div正常情况下是无法像input元素一样获得焦点的,但是正如我们可以通过给div加上conteneditable属性让div元素变得可以编辑一样,在这里我们也可以通过给div元素加上tabindex = "0"的属性让元素可以获取焦点:
document.getElementById(“targetBox”).focus();
这样实现跳转之后的元素会加上一个蓝色的选中边框,可通过设置outline:none;属性取消.
方法四: 利用scrollIntoView方法
此方法可以简单的通过获取元素就让当前的元素滚动到浏览器窗口的可视区域内:
document.getElementById(“targetBox”).scrollIntoView();
通过设置alignToTop参数来设置元素的显示位置, 如果为true,元素的顶端将和其所在滚动区的可视区域的顶端对齐,如果为false,元素的底端将和其所在滚动区的可视区域的底端对齐.显然这种方式最是简单,推荐这种.
原文链接:https://blog.csdn.net/cjFrontEnd/article/details/99709971