一、封装组件

<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组件实现固定相关推荐

  1. iview的Affix组件没有按照预期效果固定

    <template> <Affix :offset-bottom="10"><Button style="text-align:center ...

  2. Vue实现跑马灯效果以及封装为组件发布

    Vue 实现跑马灯效果 前言 最近做活动需要做跑马灯效果,其他同事也有实现,本来打算复制他们代码,发现都是使用setInterval实现了,也没有封装为组件,所以自己用CSS3实现了一下跑马灯效果,并 ...

  3. Vue中封装打印组件包括基本信息、表格用途出库单、入库单、请购单等单据

    1.我们在工作中,在中后台系统应用中,经常会遇到打印的问题. 2.产品需求将列表详情数据能够打印生产单据,包括列表详情的所有数据. 3.通常我们可以通过接口拿到一定格式的JSON数据. 打印组件,总的 ...

  4. vue2知识点:组件的props属性、非props属性、props属性校验

    文章目录 3.10props属性 举例:父组件给子组件传递属性msg和greetText,子组件用属性a和b接收,并打印输出 3.11props校验 举例 3.12非props属性 举例:定义子组件设 ...

  5. 【封装UI组件库】手把手教你仿一下Element-ui的Button组件(发布至npm)

    所谓UI组件库,就是封装了平常项目开发中经常会使用的页面组件,发布至npm库中作为插件供项目组成员及其他开发者使用(不发布也行),目的就是为了避免多次重复劳动. 以插件的形式使用可以做到即插即用,非常 ...

  6. 封装 vue 组件的过程记录

    在我们使用vue的开发过程中总会遇到这样的场景,封装自己的业务组件. 封装页面组件前要考虑几个问题: 1.该业务组件的使用场景 2.在什么条件下展示一些什么数据,数据类型是什么样的,及长度颜色等 3. ...

  7. vue商城项目开发:封装banner组件、组件参数传递

    封装banner组件 在Home组件中引入: components: 在template中使用: 组件参数传递 轮播图可以封装成组件,但是每个页面要展示的图片内容可能不一样,所以要进行参数传递,你传什 ...

  8. asp.net core封装layui组件示例分享

    什么封装?这里只是用了TagHelper,是啥?自己瞅文档去 在学习使用TagHelper的时候,最希望的就是能有个Demo能够让自己作为参考 怎么去封装一个组件? 不同的情况怎么去实现? 有没有更好 ...

  9. echart vue 图表大小_vue之将echart封装为组件

    最近的新项目里,有大量数据图表类的需求,为了增强代码的复用性,减少冗余,我开始思考如何将echart封装为组件调用.本文将会以雷达图为案例,一步步讲解在vue项目中如何使用echart,如何将其封装为 ...

最新文章

  1. 操作系统--文件管理之索引
  2. 邓公数据结构C++语言版学习笔记——二叉树
  3. TensorFlow在Anaconda环境下创建
  4. python科学数据分析_python数据分析-科学计数法
  5. 【个人笔记】OpenCV4 C++ 快速入门 29课
  6. mysql5.7 bulk insert_Bulk Insert 高效快速插入数据
  7. IT面试经验:简历上项目经验怎么写?3招教你来包装!
  8. MongoDB Could not find host matching read preference { mode: \primary\ } for set repl_shard1
  9. MCS-51系列单片机硬件结构
  10. TabLayout 不显示下划线
  11. Android中startActivities的准确用法
  12. 2021漳州一中历年高考成绩查询,2021年漳州中考录取分数线,历年漳州各高中录取分数线排名...
  13. 当输入 https://www.baidu.com 时,返回页面的过程中发生了什么?
  14. Day 05- Vue3 Vue2响应式原理
  15. Spring MVC的请求处理流程
  16. SpringBoot 实现手机发送短信验证码
  17. # CF765F Souvenirs
  18. STC单片机蓝牙无线下载-烧写程序ISP(STC8 STC15 STC12 STC11 STC89)
  19. 亚马逊的运营思路是什么?有没有教程?
  20. 千万不要使用360安全管家

热门文章

  1. RocketMQ常见问题-消息重复消费和消息重复的问题
  2. 听说,要把南京大学的大门拆了
  3. 日程安排小程序实战教程(上篇)
  4. 22/02/17学习笔记
  5. struct in_addr 结构体
  6. 二十三 HDP搭建大数据环境
  7. mx解析和邮件服务器,邮件交换记录(MX)解析和查询
  8. (二)地理信息中对地球的描述-地球的大地水准面、地球椭球体、大地基准面
  9. leecode刷题第五天
  10. 基于python-opencv实时识别黑线赛道(三)之上位机PID调控前篇