vue之粘性定位组件
sticky/Sticky.vue
<template>
<div :style="{height:height+'px',zIndex:zIndex}">
<div
:class="className"
:style="{top:(isSticky ? stickyTop +'px' : ''),zIndex:zIndex,position:position,width:width,height:height+'px'}"
>
<slot>
<div>sticky</div>
</slot>
</div>
</div>
</template>
<script>
export default {
name: 'Sticky',
props: {
stickyTop: {
type: Number,
default: 0
},
zIndex: {
type: Number,
default: 1
},
className: {
type: String,
default: ''
}
},
data() {
return {
active: false,
position: '',
width: undefined,
height: undefined,
isSticky: false
}
},
mounted() {
this.height = this.$el.getBoundingClientRect().height
window.addEventListener('scroll', this.handleScroll)
window.addEventListener('resize', this.handleResize)
},
activated() {
this.handleScroll()
},
destroyed() {
window.removeEventListener('scroll', this.handleScroll)
window.removeEventListener('resize', this.handleResize)
},
methods: {
sticky() {
if (this.active) {
return
}
this.position = 'fixed'
this.active = true
this.width = this.width + 'px'
this.isSticky = true
},
handleReset() {
if (!this.active) {
return
}
this.reset()
},
reset() {
this.position = ''
this.width = 'auto'
this.active = false
this.isSticky = false
},
handleScroll() {
const width = this.$el.getBoundingClientRect().width
this.width = width || 'auto'
const offsetTop = this.$el.getBoundingClientRect().top
if (offsetTop < this.stickyTop) {
this.sticky()
return
}
this.handleReset()
},
handleResize() {
if (this.isSticky) {
this.width = this.$el.getBoundingClientRect().width + 'px'
}
}
}
}
</script>
sticky/index.js
import Sticky from "./Sticky.vue";
Sticky.install = function(vue) {
vue.component(Sticky.name, Sticky);
};
export default Sticky;
main.js
import Sticky from '@/components/commom/sticky/index.js'
Vue.use(Sticky)
使用组件
<template>
<div class="home">
<ul>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<Sticky :sticky-top="200" >
<li class="sticky_demo">我是要sticky的</li>
</Sticky>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
<li>我是夏利</li>
</ul>
</div>
</template>
<script>
export default {
name: "Home",
data() {
return {};
},
methods: {},
};
</script>
<style lang="scss" scoped>
.home {
height: 100%;
width: 100%;
}
ul {
display: block;
height: 3000px;
}
.sticky_demo{
background: #000;
}
</style>