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生成。

相关推荐
Justinc.4 分钟前
CSS3新增边框属性(五)
前端·css·css3
fruge12 分钟前
纯css制作声波扩散动画、js+css3波纹催眠动画特效、【css3动画】圆波扩散效果、雷达光波效果完整代码
javascript·css·css3
neter.asia20 分钟前
vue中如何关闭eslint检测?
前端·javascript·vue.js
~甲壳虫21 分钟前
说说webpack中常见的Plugin?解决了什么问题?
前端·webpack·node.js
十一吖i39 分钟前
前端将后端返回的文件下载到本地
vue.js·elementplus
光影少年40 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
As977_41 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
susu108301891143 分钟前
vue3 css的样式如果background没有,如何覆盖有background的样式
前端·css
Ocean☾1 小时前
前端基础-html-注册界面
前端·算法·html
Rattenking1 小时前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js