feat: 当前标签页始终显示在视野内

This commit is contained in:
zclzone 2022-11-27 20:04:11 +08:00
parent ed79e81b13
commit c626d2b785
3 changed files with 46 additions and 5 deletions

View File

@ -88,6 +88,28 @@ onBeforeUnmount(() => {
window.removeEventListener('resize', refreshIsOverflow) window.removeEventListener('resize', refreshIsOverflow)
observer.disconnect() observer.disconnect()
}) })
function handleScroll(x, width) {
const wrapperWidth = wrapper.value?.offsetWidth
const contentWidth = content.value?.offsetWidth
if (contentWidth <= wrapperWidth) return
// x
if (x < -translateX.value + 150) {
translateX.value = -(x - 150)
resetTranslateX(wrapperWidth, contentWidth)
}
// x
if (x + width > -translateX.value + wrapperWidth) {
translateX.value = wrapperWidth - (x + width)
resetTranslateX(wrapperWidth, contentWidth)
}
}
defineExpose({
handleScroll,
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -1,7 +1,8 @@
<template> <template>
<ScrollX> <ScrollX ref="scrollXRef">
<n-tag <n-tag
v-for="tag in tagsStore.tags" v-for="tag in tagsStore.tags"
ref="tabRefs"
:key="tag.path" :key="tag.path"
class="px-15 mx-5 rounded-4 cursor-pointer hover:color-primary" class="px-15 mx-5 rounded-4 cursor-pointer hover:color-primary"
:type="tagsStore.activeTag === tag.path ? 'primary' : 'default'" :type="tagsStore.activeTag === tag.path ? 'primary' : 'default'"
@ -30,6 +31,8 @@ import ScrollX from '@/components/common/ScrollX.vue'
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const tagsStore = useTagsStore() const tagsStore = useTagsStore()
const tabRefs = ref([])
const scrollXRef = ref(null)
const contextMenuOption = reactive({ const contextMenuOption = reactive({
show: false, show: false,
@ -48,6 +51,18 @@ watch(
{ immediate: true } { immediate: true }
) )
watch(
() => tagsStore.activeIndex,
async (activeIndex) => {
await nextTick()
const activeTabElement = tabRefs.value[activeIndex]?.$el
if (!activeTabElement) return
const { offsetLeft: x, offsetWidth: width } = activeTabElement
scrollXRef.value?.handleScroll(x + width, width)
},
{ immediate: true }
)
const handleTagClick = (path) => { const handleTagClick = (path) => {
tagsStore.setActiveTag(path) tagsStore.setActiveTag(path)
router.push(path) router.push(path)

View File

@ -10,6 +10,11 @@ export const useTagsStore = defineStore('tag', {
activeTag: activeTag || '', activeTag: activeTag || '',
} }
}, },
getters: {
activeIndex() {
return this.tags.findIndex((item) => item.path === this.activeTag)
},
},
actions: { actions: {
setActiveTag(path) { setActiveTag(path) {
this.activeTag = path this.activeTag = path
@ -26,11 +31,10 @@ export const useTagsStore = defineStore('tag', {
}, },
removeTag(path) { removeTag(path) {
if (path === this.activeTag) { if (path === this.activeTag) {
const activeIndex = this.tags.findIndex((item) => item.path === path) if (this.activeIndex > 0) {
if (activeIndex > 0) { router.push(this.tags[this.activeIndex - 1].path)
router.push(this.tags[activeIndex - 1].path)
} else { } else {
router.push(this.tags[activeIndex + 1].path) router.push(this.tags[this.activeIndex + 1].path)
} }
} }
this.setTags(this.tags.filter((tag) => tag.path !== path)) this.setTags(this.tags.filter((tag) => tag.path !== path))