做论坛网站前段用什么框架好点,遂宁市建设局网站,成都建设银行网站首页,wordpress4.7安装效果 注意点
useStore涉及的部分是pina的缓存#xff0c;需要改成自己的#xff1b;userStore.tabStore是获取缓存里的页签#xff0c;userStore.$patch(state { state.tabStore tabStoreList.value }) 是存储改变的页签注意我的页签是根据路由path来判断的#xf… 效果 注意点
useStore涉及的部分是pina的缓存需要改成自己的userStore.tabStore是获取缓存里的页签userStore.$patch(state { state.tabStore tabStoreList.value }) 是存储改变的页签注意我的页签是根据路由path来判断的不是根据fullPath可能有的需求是要使用fullPath
templatedivdiv{{isAtLeft}} -{{isAtLeft ? 滚动条头在最左侧 : }}/divdiv{{isAtRight}} -{{isAtRight ? 滚动条尾在最右侧 : }}/divdiv{{tabsMenuIndex}}/div/divdiv classbox-all flex-row v-iftabStoreList.lengthdiv classbtn_box v-if!_.isEmpty(tabStoreList) hasScroll !isAtLeft clickscrollLeftel-icon classbtn_icon size16DArrowLeft //el-icon/divdiv classtab_box reftab_box!-- pre{{tabStoreList}}/pre --!-- {{tabStoreList.length}} --template v-for(item,index) in tabStoreList :keyindexel-popover refpopoverRef :visibleshowPopoverPath item.path placementbottom :widthfit-contenttemplate #referencediv :id_id_item.path classtab_item :classtabsMenuValue item.path ? active_bgi : clickclickItem(item,index) contextmenu.preventtabRightClick(item,index){{item.tabName}}el-icon classclose_icon size16 styleposition:relative;top:3px;click.stopdeleteTab(item,index)Close //el-icon/div/templatediv classpopover_contentdiv classpopover_btn clickcloseRight(1,item,index)关闭全部/divdiv classpopover_btn mt clickcloseRight(2,item,index)关闭其他/divdiv classpopover_btn mt clickcloseRight(3,item,index)关闭左侧/divdiv classpopover_btn mt clickcloseRight(4,item,index)关闭右侧/div/div/el-popover/template/divdiv classbtn_box v-if!_.isEmpty(tabStoreList) hasScroll !isAtRight clickscrollRightel-icon classbtn_icon size16DArrowRight //el-icon/div/div
/templatescript setup
import { ref, watch, onMounted, onBeforeUnmount, nextTick } from vue
import useStore from /store/index.js
import { useRouter, useRoute } from vue-router
import _ from lodash
import { Close, DArrowLeft, DArrowRight } from element-plus/icons-vueconst route useRoute()
const router useRouter()
const { userStore } useStore()let tabsMenuValue ref() // 当前选择的tab标签页
let tabsMenuIndex ref() // 当前选择的tab标签页对应下标
let tabStoreList ref(userStore.tabStore || []) // 标签页集合 取自缓存 同时会更新缓存数据// 点击切换
const clickItem (item) {router.push({ path: item.path })
}
// 删除
const deleteTab (item, index) {tabStoreList.value tabStoreList.value.filter((it, i) i ! index)userStore.$patch(state {state.tabStore tabStoreList.value})// 判断是否是点击删除当前高亮标签 高亮删除需跳新页面if (item.path tabsMenuValue.value) {let nextIndex index - 1if (nextIndex -1) { // 说明删第一个tabif (tabStoreList.value.length 0) { // 说明删了后面没有tab了// 跳转首页或不处理} else {let nextPath tabStoreList.value[0].pathrouter.push({ path: nextPath })}} else {let nextPath tabStoreList.value[nextIndex].pathrouter.push({ path: nextPath })}}
}let popoverRef ref(null)
let showPopoverPath ref(false)
// 标签右键事件
const tabRightClick (item) {// console.log(item, index);showPopoverPath.value item.path
}
// 弹出框右键事件
const closeRight (type, item, index) {// console.log(type, item, index);// 全部 其他 左侧 右侧if (type 1) {tabStoreList.value []} else if (type 2) {tabStoreList.value tabStoreList.value.filter((it, i) i index)let nextPath tabStoreList.value[0].pathrouter.push({ path: nextPath })} else if (type 3) {if (tabsMenuIndex.value index) {let nextPath tabStoreList.value[index].pathrouter.push({ path: nextPath })}tabStoreList.value tabStoreList.value.filter((it, i) i index)} else if (type 4) {if (tabsMenuIndex.value index) {let nextPath tabStoreList.value[index].pathrouter.push({ path: nextPath })}tabStoreList.value tabStoreList.value.filter((it, i) i index)}userStore.$patch(state {state.tabStore tabStoreList.value})
}const tab_box ref(null) // 滚动条元素
const hasScroll ref(false) // 是否存在滚动条
const isAtLeft ref(true); // 滚动条头在最左侧
const isAtRight ref(false); // 滚动条尾在最右侧// 左右控制滚动条移动
const scrollLeft () {tab_box.value.scrollLeft tab_box.value.scrollLeft - 800
}
const scrollRight () {tab_box.value.scrollLeft tab_box.value.scrollLeft 800
}
// 处理滚动事件
const handleScroll () {if (tab_box.value) {// 判断是否滚动到最左侧isAtLeft.value tab_box.value.scrollLeft 0;if (hasScroll.value) {// 判断是否滚动到最右侧isAtRight.value tab_box.value.scrollLeft tab_box.value.clientWidth tab_box.value.scrollWidth;} else {isAtRight.value false}}
};
// 处理鼠标滚轮事件
const handleWheel (event) {if (tab_box.value) {event.preventDefault(); // 防止默认的垂直滚动// 根据鼠标滚轮的方向调整 scrollLefttab_box.value.scrollLeft event.deltaY; // deltaY 表示垂直滚动的距离handleScroll(); // 更新滚动位置}
};watch(route, val {const { path, matched } valif (!matched.length) returnconst flatPermissionList userStore.flatPermissionListconsole.log(页签监听, path, val, matched,)console.log(权限全路径, flatPermissionList);let matchedTitle matched[matched.length - 1]?.meta?.title || let tabName flatPermissionList.find(it it.permissionUrl path)?.permissionName || matchedTitleconsole.log(tabName, tabName);// let keepAliveName matched[matched.length - 1].name// console.log(keepAliveName, keepAliveName);// 现在是根据路由的path来查找tabStore中是否存在相同的path如果存在则不添加如果不存在则添加可能要改成fullPath判断 解决编辑新增的特殊页tabsMenuValue.value pathlet hasTabName userStore.tabStore.findIndex(it it.path path) ! -1// console.log(userStore.tabStore.findIndex(it it.path path), hasTabName);if (!hasTabName) {userStore.$patch(state {state.tabStore.push({// ...val,tabName: tabName,// keepAliveName: keepAliveName,path: val.path,// name: val.name,// params: val.params,// query: val.query,// hash: val.hash,// fullPath: val.fullPath,// meta: val.meta,// close: true, // 是否支持关闭})})}tabStoreList.value userStore.tabStore// 找到当前路由下标tabsMenuIndex.value tabStoreList.value.findIndex(it it.path path)if (tab_box.value) {// 手动滑动到当前路由下标console.log(手动滑动到当前路由下标, tabsMenuIndex.value * 180, hasScroll.value);tab_box.value.scrollLeft tabsMenuIndex.value * 180}
}, { immediate: true, deep: true })watch(() tabStoreList.value, () {nextTick(() {if (tab_box.value) {hasScroll.value tab_box.value.scrollWidth tab_box.value.clientWidth}// 当没有滚动条时候一定是在最左侧if (!hasScroll.value) {isAtLeft.value trueisAtRight.value false}// // 同时页签变化时候 时刻计算滚动条位置// handleScroll()})
}, { immediate: true, deep: true })const handleClickOutside () {showPopoverPath.value null
};// 在组件挂载时添加全局点击事件监听器
onMounted(() {window.addEventListener(click, handleClickOutside);if (tab_box.value) {tab_box.value.addEventListener(scroll, handleScroll);tab_box.value.addEventListener(wheel, handleWheel); // 添加鼠标滚轮事件监听}
});// 在组件卸载时移除全局点击事件监听器
onBeforeUnmount(() {window.removeEventListener(click, handleClickOutside);if (tab_box.value) {tab_box.value.removeEventListener(scroll, handleScroll);tab_box.value.removeEventListener(wheel, handleWheel); // 移除鼠标滚轮事件监听}
});
/scriptstyle langscss scoped
.box-all {width: 100%;max-width: 100%;.btn_box {display: inline-block;width: 46px;// height: 38px;background: #f9f9f9;border-radius: 0px 0px 0px 0px;cursor: pointer;.btn_icon {position: relative;top: 11px;left: 12px;}.btn_icon:hover {color: #00706b;}}.btn_box:first-child {box-shadow: 15px 0px 17px 1px rgba(0, 0, 0, 0.1);z-index: 0;}.btn_box:last-child {box-shadow: -15px 0px 17px 1px rgba(0, 0, 0, 0.1);}
}
.tab_box {// padding: 0 30px; // 可以看到到头的空白width: 100%;max-width: 100%;// height: 40px !important;// min-height: 40px !important;// max-height: 40px !important;white-space: nowrap;overflow-x: auto;// overflow-y: none;background-color: transparent;// transition: transform 0.5s ease;transition: scroll-left 0.3s ease; /* 添加过渡效果 */scroll-behavior: smooth; /* 添加平滑滚动效果 */.tab_item {line-height: 39px;cursor: pointer;display: inline-block;width: 180px;text-align: center;background: #f6f6f6;border-radius: 0px 0px 0px 0px;border-right: 1px solid #edecec;.close_icon:hover {color: red;}}.tab_item:hover {color: #00706b;font-weight: 700;// background-color: #edf6f6;border-radius: 8px 8px 0 0;}.active_bgi {color: #00706b;font-weight: 700;background-color: #fff;border-radius: 8px 8px 0 0;}
}/* 滚动条整体样式 */
.tab_box::-webkit-scrollbar {width: 1px; /* 竖直滚动条宽度 */height: 1px; /* 水平滚动条高度 */
}
/* 滚动条滑块 */
.tab_box::-webkit-scrollbar-thumb {background: transparent; /* 设置滑块为完全透明 */border-radius: 4px; /* 圆角滑块 */
}
/* 滚动条滑块在悬停时的样式 */
.tab_box::-webkit-scrollbar-thumb:hover {background: transparent; /* 在悬停时略微可见 */
}/* 滚动条轨道背景 */
.tab_box::-webkit-scrollbar-track {background: transparent; /* 设置轨道为完全透明 */
}
::-webkit-scrollbar-track-piece {background-color: #fff; /* 设置轨道为完全透明 不设置不生效 */
}.popover_content {text-align: center;.popover_btn {cursor: pointer;}.popover_btn:hover {color: #00706b;font-weight: 700;}
}
/style