Affix是一种常用于前端界面设计的组件,它可以让网页元素固定在页面中的某个位置,随着用户的滚动而保持不变。
通常用于固定导航栏、侧边栏等。通过设置相应的CSS样式和JavaScript代码,我们可以轻松地实现Affix组件的效果。
Affix可以增强网页的用户体验,让用户在页面滚动时能够方便地访问重要的导航链接或信息,提高页面的可用性。
需要先安装vue3-dxui
yarn add vue3-dxui
或者
npm install vue3-dxui
全局main.ts中引入css
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import 'vue3-dxui/dxui/dxui.css'
createApp(App).use(store).use(router).mount('#app')
按需引入
<script>
import { Affix } from 'vue3-dxui'
export default {
components: {
Affix
}
}
</script>
<template>
<div
v-show="fixed"
:style="{
position: 'fixed',
top: affix.top,
'z-index': affix.zIndex,
bottom: affix.bottom
}"
>
<slot />
</div>
<div :style="{ opacity: fixed ? 0 : 1 }" ref="affixTarget">
<slot />
</div>
</template>
<script lang="ts">
import { reactive, ref, onMounted, onBeforeUnmount, watch, SetupContext } from 'vue'
// import { useRouter } from 'vue-router'
import { Data } from './types/index'
export default {
name: 'Affix',
emits: ['affixChange'],
props: {
// 是否禁用,禁用就不会产生固定效果,和正常的元素一样显示
disabled: {
require: false,
default: false,
type: Boolean
},
top: {
require: false,
default: undefined,
type: Number
},
bottom: {
require: false,
default: undefined,
type: Number
},
zIndex: {
require: false,
default: 1,
type: Number
}
},
setup(props: Data, context: SetupContext) {
const affix = reactive({
top: props.top + 'px',
bottom: props.bottom + 'px',
zIndex: props.zIndex
})
const affixTarget = ref<any>()
const fixed = ref(false)
const handleScroll = () => {
if (props.disabled) {
return
}
const { top, bottom } = affixTarget?.value?.getBoundingClientRect()
if (props.top !== undefined && top < props.top) {
fixed.value = true
affix.bottom = 'auto'
affix.top = props.top + 'px'
} else if (props.bottom !== undefined && window.innerHeight - bottom < props.bottom) {
fixed.value = true
affix.bottom = props.bottom + 'px'
affix.top = 'auto'
} else {
fixed.value = false
}
}
onMounted(() => {
window.addEventListener('scroll', handleScroll)
window.addEventListener('resize', handleScroll)
handleScroll()
})
onBeforeUnmount(() => {
window.removeEventListener('scroll', handleScroll)
window.removeEventListener('resize', handleScroll)
})
watch(fixed, (value) => {
context.emit('affixChange', value)
})
return {
affix,
fixed,
affixTarget
}
}
}
</script>
<style lang="scss">
@import '@/scss/layout.scss';
</style>
名称 | 说明 |
---|---|
disabled | boolean类型,默认为false,当为true时,affix组件默认不生效,看起来和一般的dom一样。开发者可能会在某些特殊的情况下禁用或者启用affix组件 |
top | number类型 距离窗口顶部达到指定偏移量后触发 比如传入100,就是当组件距离视窗顶部为100px时开始固定 |
bottom | number类型 距离窗口底部达到指定偏移量后触发 比如传入100,就是当组件距离视窗底部为100px时开始固定 |
zIndex | number类型 默认值为1 设置fixed后,组件zindex的值,实际开发中,页面比较复杂,说不定affix 在fixed后还被某些内容覆盖,zindex将帮助开发更加灵活地处理 |
名称 | 说明 |
---|---|
@affixChange | 当affix组件的fixed状态发生改变时,触发的回调函数,返回当前的fixed状态布尔值 |
dxui组件库是我个人搭建的vue3 前端交互组件库,倾向于pc网站的交互模式。