vue指令快速设置元素的高度

在项目中经常有需要将列表的高度设置成剩余可视区域的高度,一般的做法是用ref获取后,计算元素的top,然后通过v-bind()将top注入到style中

cn.vuejs.org/api/sfc-css...

css 复制代码
height: calc(100vh - v-bind(top))

下面介绍一种通过指令和css变量的方式快速设置列表高度的方法,下面是代码示例。

ts 复制代码
import type { DirectiveBinding, Directive } from 'vue'

const PREFIX = '--bounding-info-'
interface IOptions {
  prefix?: string
}

const setStyles = (el: HTMLElement, options: IOptions = {}) => {
  const { prefix = PREFIX } = options
  const boundingClientRectInfo = el.getBoundingClientRect()
  const { width, height, top, right, bottom, left, x, y } = boundingClientRectInfo
  const rawStylesStr = el.getAttribute('style')
  const rawStyles = rawStylesStr ? rawStylesStr.split(';').filter((item) => !!item && !item.includes(prefix)) : []
  const bindingStyles = [
    {
      name: 'width',
      value: width
    },
    {
      name: 'height',
      value: height
    },
    {
      name: 'top',
      value: top
    },
    {
      name: 'right',
      value: right
    },
    {
      name: 'bottom',
      value: bottom
    },
    {
      name: 'left',
      value: left
    },
    {
      name: 'x',
      value: x
    },
    {
      name: 'y',
      value: y
    }
  ].map((item) => `${prefix}${item.name}: ${item.value}px`)
  const newStyles = rawStyles.concat(bindingStyles)
  el.setAttribute('style', newStyles.join(';'))
}
const boundingInfoToCssVar: Directive = {
  mounted(el: HTMLElement, binding: DirectiveBinding) {
    setStyles(el, binding.arg as IOptions)
  },
  updated(el: HTMLElement, binding: DirectiveBinding, vnode, prevVnode) {
    setStyles(el, binding.arg as IOptions)
  }
  // beforeUnmount(el: HTMLElement, binding: DirectiveBinding) {
  //   console.log(el)
  // }
}

export const name = 'BoundingInfoToCssVar'
export default boundingInfoToCssVar

使用方法

html 复制代码
<div
  v-if="activated"
  v-bounding-info-to-css-var:[boundingInfoOptions]
  style="font-size: 12px"
  :style="styles"
  @click="closeHandle"
  class="overflow"
/>

<script lang="ts" setup>
const boundingInfoOptions = { prefix: '--bounding-info-' }
</script>

<style lang="less">
.overflow {
  height: calc(100vh - var(--bounding-info-top));
}
</style>

这是一个使用 Vue.js 实现的指令,它将元素的边界信息转换为 CSS 变量,并将这些 CSS 变量应用到元素的样式上。

以下是代码的详细解释:

  • setStyles函数用于设置元素的样式。它接受一个元素和一个可选的配置对象作为参数。配置对象可以包含一个前缀选项,用于指定生成的 CSS 变量的前缀。

    • 函数内部首先获取元素的边界信息,包括宽度、高度、上边界、右边界、下边界、左边界、水平偏移量和垂直偏移量。
    • 然后,它从元素的现有样式中提取出不包含指定前缀的样式,并将其存储在rawStyles数组中。
    • 接下来,它根据边界信息生成一组 CSS 变量,并将其存储在bindingStyles数组中。每个 CSS 变量的名称都以指定的前缀开头,后面跟着对应的边界信息名称,值为边界信息的值,单位为像素。
    • 最后,它将原始样式和生成的绑定样式合并成一个新的样式字符串,并将其设置回元素的style属性中。
  • boundingInfoToCssVar指令用于将边界信息转换为 CSS 变量。它包含mountedupdated两个生命周期钩子函数。

    • mounted函数在指令首次绑定到元素时被调用,它调用setStyles函数来设置元素的样式。
    • updated函数在指令的绑定值发生变化时被调用,它也调用setStyles函数来更新元素的样式。
  • 代码最后导出了指令的名称和定义,以便在其他地方使用。

使用这个指令时,可以在模板中使用v-bounding-info-css-var指令来绑定一个对象,该对象可以包含一个prefix选项,用于指定 CSS 变量的前缀。例如:

html 复制代码
<!-- 此处的元素将具有带有 --my-prefix- 前缀的 CSS 变量 -->
<div v-bounding-info-css-var="{ prefix: '--my-prefix-' }"></div>

这样,元素的边界信息将被转换为带有指定前缀的 CSS 变量,并应用到元素的样式上。

这段代码是一个使用 Vue.js 的示例,它包含一个具有条件渲染和一个自定义指令 v-bounding-info-to-css-var<div> 元素。下面是代码的详细解释:

html 复制代码
<div
  v-if="activated"
  v-bounding-info-to-css-var:[boundingInfoOptions]
  style="font-size: 12px"
  :style="styles"
  @click="closeHandle"
  class="list"
 />
  • v-if="activated":这是一个条件渲染指令,只有当 activated 变量的值为 true 时,这个 <div> 元素才会被渲染。
  • v-bounding-info-to-css-var:[boundingInfoOptions]:这是一个自定义指令,它接受一个参数 boundingInfoOptions,这个参数会被传递给指令的处理函数。
  • style="font-size: 12px":这是一个内联样式,用于设置 <div> 元素的字体大小为 12px
  • :style="styles":这是一个 v-bind 指令,它将 styles 变量绑定到 <div> 元素的 style 属性上。
  • @click="closeHandle":这是一个事件监听指令,当点击 <div> 元素时,会触发 closeHandle 函数。
  • class="list":这是一个类名,用于给 <div> 元素添加一个名为 list 的类。
js 复制代码
const boundingInfoOptions = { prefix: '--bounding-info-' }
  • boundingInfoOptions:这是一个对象,它包含了自定义指令 v-bounding-info-to-css-var 所需的参数。在这个例子中,prefix 是一个参数,它的值为 --bounding-info-
css 复制代码
.list { height: calc(100vh - var(--bounding-info-top)); }
  • .list:这是一个类选择器,用于选择具有 list 类的元素。
  • height: calc(100vh - var(--bounding-info-top));:这是一个 CSS 样式声明,它使用了 calc 函数来计算元素的高度。100vh 表示视窗的高度,var(--bounding-info-top) 表示一个变量,它的值是由自定义指令 v-bounding-info-to-css-var 设置的上边界距离。通过减去上边界的距离,得到了元素的高度。

总的来说,这段代码的目的是在一个具有特定条件(activatedtrue)的情况下,渲染一个 <div> 元素。这个元素具有一些样式,并且当点击时会触发一个函数。此外,它还使用了一个自定义指令来将元素的边界信息转换为 CSS 变量,并使用这些变量来设置元素的样式。

以上代码作者编写,大部分文字和少部分代码由coze生成。

相关推荐
腾讯TNTWeb前端团队5 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰8 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪8 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪9 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy9 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom10 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom10 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom10 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom10 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom10 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试