vue2封装Affix组件实现固定
一、封装组件
<template><div class="affix-placeholder" :style="wrapStyle"><div :class="{'affix': affixed}" :style="styles"><slot></slot></div></div>
</template>
<script>
/**
* @date 2023-3-9 10:09:50
*/
export default {props: {offset: {type: Number,default: 0},onAffix: {type: Function,default() {}},boundary: {type: String,default: ''}},data() {return {affixed: false,styles: {},affixedClientHeight: 0,wrapStyle: {}};},methods: {getScroll(w, top) {let ret = w[`page${(top ? 'Y' : 'X')}Offset`];const method = `scroll${top ? 'Top' : 'Left'}`;if (typeof ret !== 'number') {const d = w.document;// ie6,7,8 standard moderet = d.documentElement[method];if (typeof ret !== 'number') {// quirks moderet = d.body[method];}}return ret;},getOffset(element) {const rect = element.getBoundingClientRect();const body = document.body;const clientTop = element.clientTop || body.clientTop || 0;const clientLeft = element.clientLeft || body.clientLeft || 0;// const clientHeight = element.clientHeight || 0;const scrollTop = this.getScroll(window, true);const scrollLeft = this.getScroll(window);return {top: rect.bottom + scrollTop - clientTop - this.affixedClientHeight,left: rect.left + scrollLeft - clientLeft};},handleScroll() {const scrollTop = this.getScroll(window, true) + this.offsets; // handle setting offsetconst elementOffset = this.getOffset(this.$el);if (!this.affixed && scrollTop > elementOffset.top) {this.affixed = true;this.styles = {top: `${this.offsets}px`,left: `${elementOffset.left}px`,width: `${this.$el.offsetWidth}px`};this.onAffix(this.affixed);}// if setting boundaryif (this.boundary && scrollTop > elementOffset.top) {const el = document.getElementById(this.boundary.slice(1));if (el) {const boundaryOffset = this.getOffset(el);if ((scrollTop + this.offsets) > boundaryOffset.top) {const top = scrollTop - boundaryOffset.top;this.styles.top = `-${top}px`;}}}if (this.affixed && scrollTop < elementOffset.top) {this.affixed = false;this.styles = {};this.onAffix(this.affixed);}if (this.affixed && this.boundary) {const el = document.getElementById(this.boundary.slice(1));if (el) {const boundaryOffset = this.getOffset(el);if ((scrollTop + this.offsets) <= boundaryOffset.top) {this.styles.top = 0;}}}}},computed: {offsets() {if (this.boundary) {return 0;}return this.offset;}},mounted() {this.affixedClientHeight = this.$el.children[0].clientHeight;// this.wrapStyle = {height: `${this.affixedClientHeight}px`};window.addEventListener('scroll', this.handleScroll);window.addEventListener('resize', this.handleScroll);},beforeDestroy() {window.removeEventListener('scroll', this.handleScroll);window.removeEventListener('resize', this.handleScroll);}
};
</script>
<style scoped>
.affix{position: fixed;z-index: 99999;
}</style>
API
参数 | 说明 | 类型 | 默认值 |
offset | 距离窗口顶部达到指定偏移量后触发 | Number | 0 |
boundary | 设置 Affix 的活动范围,值为affix上级元素的id(可以是父元素,也可以是父元素的父元素...) | String(#parent) | |
on-affix | 固定状态改变时触发的回调函数 | Function(affixed) | 无 |
二、使用方法
<template><div class="test"><affix><div>这是一个固钉组件</div></affix><affix :offset="40"><div>这是一个固钉组件</div></affix></div>
</template><script>
import Affix from '@/components/Affix';
export default {name: 'test',components: {Affix}
};
</script>
转自Vue Affix组件
进行了一些优化,侵权联系必删!
vue2封装Affix组件实现固定相关推荐
- iview的Affix组件没有按照预期效果固定
<template> <Affix :offset-bottom="10"><Button style="text-align:center ...
- Vue实现跑马灯效果以及封装为组件发布
Vue 实现跑马灯效果 前言 最近做活动需要做跑马灯效果,其他同事也有实现,本来打算复制他们代码,发现都是使用setInterval实现了,也没有封装为组件,所以自己用CSS3实现了一下跑马灯效果,并 ...
- Vue中封装打印组件包括基本信息、表格用途出库单、入库单、请购单等单据
1.我们在工作中,在中后台系统应用中,经常会遇到打印的问题. 2.产品需求将列表详情数据能够打印生产单据,包括列表详情的所有数据. 3.通常我们可以通过接口拿到一定格式的JSON数据. 打印组件,总的 ...
- vue2知识点:组件的props属性、非props属性、props属性校验
文章目录 3.10props属性 举例:父组件给子组件传递属性msg和greetText,子组件用属性a和b接收,并打印输出 3.11props校验 举例 3.12非props属性 举例:定义子组件设 ...
- 【封装UI组件库】手把手教你仿一下Element-ui的Button组件(发布至npm)
所谓UI组件库,就是封装了平常项目开发中经常会使用的页面组件,发布至npm库中作为插件供项目组成员及其他开发者使用(不发布也行),目的就是为了避免多次重复劳动. 以插件的形式使用可以做到即插即用,非常 ...
- 封装 vue 组件的过程记录
在我们使用vue的开发过程中总会遇到这样的场景,封装自己的业务组件. 封装页面组件前要考虑几个问题: 1.该业务组件的使用场景 2.在什么条件下展示一些什么数据,数据类型是什么样的,及长度颜色等 3. ...
- vue商城项目开发:封装banner组件、组件参数传递
封装banner组件 在Home组件中引入: components: 在template中使用: 组件参数传递 轮播图可以封装成组件,但是每个页面要展示的图片内容可能不一样,所以要进行参数传递,你传什 ...
- asp.net core封装layui组件示例分享
什么封装?这里只是用了TagHelper,是啥?自己瞅文档去 在学习使用TagHelper的时候,最希望的就是能有个Demo能够让自己作为参考 怎么去封装一个组件? 不同的情况怎么去实现? 有没有更好 ...
- echart vue 图表大小_vue之将echart封装为组件
最近的新项目里,有大量数据图表类的需求,为了增强代码的复用性,减少冗余,我开始思考如何将echart封装为组件调用.本文将会以雷达图为案例,一步步讲解在vue项目中如何使用echart,如何将其封装为 ...
最新文章
- 操作系统--文件管理之索引
- 邓公数据结构C++语言版学习笔记——二叉树
- TensorFlow在Anaconda环境下创建
- python科学数据分析_python数据分析-科学计数法
- 【个人笔记】OpenCV4 C++ 快速入门 29课
- mysql5.7 bulk insert_Bulk Insert 高效快速插入数据
- IT面试经验:简历上项目经验怎么写?3招教你来包装!
- MongoDB Could not find host matching read preference { mode: \primary\ } for set repl_shard1
- MCS-51系列单片机硬件结构
- TabLayout 不显示下划线
- Android中startActivities的准确用法
- 2021漳州一中历年高考成绩查询,2021年漳州中考录取分数线,历年漳州各高中录取分数线排名...
- 当输入 https://www.baidu.com 时,返回页面的过程中发生了什么?
- Day 05- Vue3 Vue2响应式原理
- Spring MVC的请求处理流程
- SpringBoot 实现手机发送短信验证码
- # CF765F Souvenirs
- STC单片机蓝牙无线下载-烧写程序ISP(STC8 STC15 STC12 STC11 STC89)
- 亚马逊的运营思路是什么?有没有教程?
- 千万不要使用360安全管家