广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Element Plus实现Affix 固钉
  • 257
分享到

Element Plus实现Affix 固钉

2024-04-02 19:04:59 257人浏览 安东尼
摘要

目录一、组件介绍二、源码分析2.1 template2.2 script2.3 实现总结:一、组件介绍 Affix组件用于将页面元素固定在特定可视区域。 1.1 属性

一、组件介绍

Affix组件用于将页面元素固定在特定可视区域。

1.1 属性

  • position:指定固钉的位置,可设置为top或bottom,默认为top
  • offset: 设置偏移距离,默认为0
  • target:指定容器CSS 选择器),让固钉始终保持在容器内,超过范围则隐藏,默认的容器是document.documentElement。
  • z-index: 固钉的层级,默认100

1.2 事件

  • scroll: 容器滚动时触发事件,参数是:固钉的scrollTop值和状态(是否fixed)
  • change: 固钉状态改变时触发,参数是固钉当前是否处于fixed状态

二、源码分析

2.1 template


<template>
  <div ref="root" class="el-affix" :style="rootStyle">
    <div :class="{'el-affix--fixed': state.fixed}" :style="affixStyle">
      <slot></slot>
    </div>
  </div>
</template>

template部分很简单,通过slot接收内容

2.2 script


// 部分核心代码,代码顺序有所调整
setup(props, { emit }) {
    // target容器 ref
    const target = ref(null) 
    // 固钉ref,与template中的ref属性配合,得到html元素
    const root = ref(null)
    // 滚动容器ref
    const scrollContainer = ref(null)
    
    // 固钉状态
    const state = Reactive({
      fixed: false,
      height: 0, // height of root
      width: 0, // width of root
      scrollTop: 0, // scrollTop of documentElement
      clientHeight: 0, // clientHeight of documentElement
      transfORM: 0,
    })
    
    onMounted(() => {
      // 根据传入的target确定 target容器
      if (props.target) {
        target.value = document.querySelector(props.target)
        if (!target.value) {
          throw new Error(`target is not existed: ${props.target}`)
        }
      } else {
        target.value = document.documentElement
      }
      
      // 根据固钉元素,向上寻找滚动容器
      scrollContainer.value = getScrollContainer(root.value)
      // 监听滚动容器的scroll事件
      on(scrollContainer.value, 'scroll', onScroll)
      // 监听固钉元素的resize事件
      addResizeListener(root.value, updateState)
    })
    
    // 滚动容器的scroll事件的响应函数
    const onScroll = () => {
      // 更新固钉状态
      updateState()
      
      emit('scroll', {
        scrollTop: state.scrollTop,
        fixed: state.fixed,
      })
    }
    
    // 更新固钉状态函数
    const updateState = () => {
      const rootRect = root.value.getBoundinGClientRect()
      const targetRect = target.value.getBoundingClientRect()
      state.height = rootRect.height
      state.width = rootRect.width
      state.scrollTop = scrollContainer.value === window ? document.documentElement.scrollTop : scrollContainer.value.scrollTop
      state.clientHeight = document.documentElement.clientHeight

      if (props.position === 'top') {
        if (props.target) {
          const difference = targetRect.bottom - props.offset - state.height
          // targetRect.bottom > 0 对应的是让固钉始终保持在容器内,超过范围则隐藏
          state.fixed = props.offset > rootRect.top && targetRect.bottom > 0
          // 用于处理场景:滚动过程中,target容器可视区域不足以显示整个固钉,则固钉应相应偏移,只展示部分
          state.transform = difference < 0 ? difference : 0
        } else {
          state.fixed = props.offset > rootRect.top
        }
      } else {
        if (props.target) {
          const difference = state.clientHeight - targetRect.top - props.offset - state.height
          state.fixed = state.clientHeight - props.offset < rootRect.bottom && state.clientHeight > targetRect.top
          state.transform = difference < 0 ? -difference : 0
        } else {
          state.fixed = state.clientHeight - props.offset < rootRect.bottom
        }
      }
    }
    // 监测固钉fixed状态变化,并对外emit change事件
    watch(() => state.fixed, () => {
      emit('change', state.fixed)
    })
    
    // 计算属性,通过固钉的状态自动更新固钉的样式
    const affixStyle = computed(() => {
      if (!state.fixed) {
        return
      }
      const offset = props.offset ? `${props.offset}px` : 0
      const transform = state.transform ? `translateY(${state.transform}px)` : ''

      return {
        height: `${state.height}px`,
        width: `${state.width}px`,
        top: props.position === 'top' ? offset : '',
        bottom: props.position === 'bottom' ? offset : '',
        transform: transform,
        zIndex: props.zIndex,
      }
    })
}

2.3 实现总结:

  • 通过监听滚动容器的scroll事件(及固钉自身的resize事件);
  • 事件响应函数中动态获取固钉及target容器的DOM属性并以此计算固钉的状态;
  • 利用计算属性自动更新固钉的样式;

到此这篇关于Element Plus实现Affix 固钉的文章就介绍到这了,更多相关Element Affix 固钉内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Element Plus实现Affix 固钉

本文链接: https://www.lsjlt.com/news/130748.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Element Plus实现Affix 固钉
    目录一、组件介绍二、源码分析2.1 template2.2 script2.3 实现总结:一、组件介绍 Affix组件用于将页面元素固定在特定可视区域。 1.1 属性 ...
    99+
    2022-11-12
  • vue3中实现使用element-plus调用message
    目录vue3使用element-plus调用message1. 全局引入element之后2. 在Composition API中setup方法传入了两个变量3. 还有一种方法是使用...
    99+
    2022-11-13
  • element-plus下拉框怎么实现全选
    这篇文章主要介绍“element-plus下拉框怎么实现全选”,在日常操作中,相信很多人在element-plus下拉框怎么实现全选问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”element-plus下拉框...
    99+
    2023-06-30
  • vue element plus多语言切换怎么实现
    这篇文章主要讲解了“vue element plus多语言切换怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue element plus多...
    99+
    2023-06-22
  • 怎么用Vue3和Element Plus实现自动导入
    $ pnpm i unplugin-auto-import unplugin-vue-components unplugin-icons -D3.2 修改 vite.config.ts 文件4 其他4.1 ELMessage 弹框样式未生效...
    99+
    2023-05-22
    Vue3 element plus
  • Vue3.x+Element Plus如何实现分页器组件
    这篇文章主要介绍“Vue3.x+Element Plus如何实现分页器组件”,在日常操作中,相信很多人在Vue3.x+Element Plus如何实现分页器组件问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法...
    99+
    2023-07-05
  • vite+vue3.0+ts+element-plus快速搭建项目的实现
    目录vite 作用使用的环境搭建项目 配置vite.config.tstsconfig.jsonApp.vueViewsroutermain.tsvite 出了 2.x 版本,抱着学...
    99+
    2022-11-12
  • 利用Vue3和element-plus实现图片上传组件
    目录前言具体代码图片上传上传组件前言 element-plus 提供了 uploader 组件,但是不好定制化,所以自己又造了个轮子,实现了一个图片上传的组件,它的预期行为是: 1....
    99+
    2022-11-13
  • element-plus下拉框实现全选的示例代码
    目录前言下拉框的简单使用全选互斥下拉框多选全选互斥的实现多个下拉框互斥一般全选的实现前言 实习确实能学到不少东西,但是学到的东西果然还是需要沉淀下来,不然后面立马又忘记了。 下拉框的...
    99+
    2022-11-13
  • element 表格多级表头子列固定的实现
    element 中 table 固定列使用fixed 属性;但是多级表头时只能固定第一列; 设置对应子列表头的宽度和父系表头的宽度可以使对应的列固定; 不需要固定的列则不需要设置宽度...
    99+
    2022-11-13
  • 基于vue3和element-plus的暗黑模式如何实现
    这篇文章主要介绍“基于vue3和element-plus的暗黑模式如何实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“基于vue3和element-plus的暗黑模式如何实现”文章能帮助大家解决问...
    99+
    2023-07-06
  • 基于vue3和element-plus的暗黑模式怎么实现
    本篇内容介绍了“基于vue3和element-plus的暗黑模式怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、基本使用因为是通过...
    99+
    2023-07-04
  • element表格多级表头子列固定怎么实现
    这篇“element表格多级表头子列固定怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“element表格多级表头子列...
    99+
    2023-07-02
  • 利用Vue3+Element-plus实现大文件分片上传组件
    目录一、背景二、技术栈三、核心代码实现四、总结一、背景 实际项目中遇到需要上传几十个G的3d模型文件,传统上传就不适用了。 结合element提供的上传组件自己封装了文件分片上传的组...
    99+
    2023-01-28
    elementui分片上传 vue element ui教程 element ui 上传文件组件
  • element-plus中如何实现按需导入与全局导入
    目录按需导入:全局导入按需导入: 安装插件 首先需要引入额外的插件:前**vite-plugin-components已重命名为unplugin-vue-components** ...
    99+
    2022-11-12
  • Vue3使用Element Plus实现列表界面的方法步骤
    目录前言效果图目录简介修改vite配置文件Element Plus简介Element Plus安装和引用table完成列表界面运行vue项目总结前言 哈喽大家好,本期我们用Eleme...
    99+
    2023-05-16
    elementplus列表界面 element plus列表 vue列表展示
  • Vue3+Vite+TS实现二次封装element-plus业务组件sfasga
    目录1.结构字符串2.返回tuple元组3.访问Dict字典4.运用库5.在列表中切片/步进 6.用 ranges 1.结构字符串 你会经常需求打印字符串。要是有很多变量,防止下面这...
    99+
    2022-11-12
  • 如何利用Vue3和element-plus实现图片上传组件
    这篇文章将为大家详细讲解有关如何利用Vue3和element-plus实现图片上传组件,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前言element-plus 提供了 uploader 组件,但是不好定...
    99+
    2023-06-29
  • element-plus中怎么实现按需导入与全局导入
    这篇文章主要介绍了element-plus中怎么实现按需导入与全局导入,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。按需导入:安装插件首先需要引入额外的插件:前**vite-...
    99+
    2023-06-21
  • vue3怎么集成Element-plus实现按需自动引入组件
    本文小编为大家详细介绍“vue3怎么集成Element-plus实现按需自动引入组件”,内容详细,步骤清晰,细节处理妥当,希望这篇“vue3怎么集成Element-plus实现按需自动引入组件”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢...
    99+
    2023-07-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作