当前位置:首页 » 《休闲阅读》 » 正文

vue3 自定义指令 自动获取节点的width 和 height

20 人参与  2024年10月01日 13:20  分类 : 《休闲阅读》  评论

点击全文阅读


想写一个依赖库, 但是需要监听组件的width和height这些数据, 就找到了ResizeObserver这个方法,不想每次使用的时候都要创建和销毁 ResizeObserver, 索性就直接封装成为一个指令用来获取想要的信息,
ResizeObserver对象上能够获取的信息还是非常多的, 除了width, height 还有 top, bottom, left, top等, 需要使用到这些可以到MDN去查看他的使用方法

实现效果
当元素大小发生改变时,会自动更新width 和height 的值
在这里插入图片描述

一. 环境

"vue": "^3.4.29"

二. 代码

文件ResizeObserverStore.ts

class ResizeObserverStore {    // 存储目标元素和对应的ResizeObserver实例    observer= new Map<HTMLElement, ResizeObserver[]>();    // 获取目标元素对应的ResizeObserver实例    get(target: HTMLElement) {        return this.observer.get(target) || [];    }    // 设置目标元素对应的ResizeObserver实例    set(target: HTMLElement, observer: ResizeObserver) {        const observers = this.observer.get(target);        if (observers) {            observers.push(observer);        } else {            this.observer.set(target, [observer]);        }    };    // 销毁目标元素对应的ResizeObserver实例    remove(target: HTMLElement) {        const observers = this.observer.get(target);        // 销毁事件        if (observers) {            observers.forEach(observer => {                observer.disconnect();            });            this.observer.delete(target);        }    }}// 创建一个ResizeObserverStore实例const resizeObserverStore = new ResizeObserverStore();//  使用ResizeObserver监听目标元素的变化export const useResizeObserver = (target: HTMLElement, callback: ResizeObserverCallback) => {    const observer = new ResizeObserver(callback);    observer.observe(target);    resizeObserverStore.set(target, observer);    return observer;}// 移除ResizeObserver监听export const removeResizeObserver = (target: HTMLElement) => {    resizeObserverStore.remove(target);}

文件: directives.ts

import {App, Directive} from "vue";import {removeResizeObserver, useResizeObserver} from "ResizeObserverStore.ts";export const  vSize: Directive = {    mounted: (el, binding) => {        // 注册并使用resizeObserver        useResizeObserver(el, (entries) => {            binding.value.width = entries[0].contentRect.width            binding.value.height = entries[0].contentRect.height        })    },    beforeUnmount: (el) => {        // 销毁resizeObserver        removeResizeObserver(el)    },}export default (app: App)=>{    app.directive('size', vSize)}

该指令主要使用ResizeObserver对象,它可以用于监听元素边界尺寸的大小。

三. 使用 (全局 或 局部 使用都可以)

1. 全局注册

文件: main.ts

import {createApp} from "vue";import App from "./App.vue";import directives from "../directives";const app = createApp(App)// 在这里注册以下就可以使用了directives(app)app.mount("#app");

2. 局部使用

<template>  <div class="layout-box" v-size="size"></div></template><script setup lang="ts">  import {reactive, ref, watch, watchEffect} from "vue";  // 如果全局引入的话就不用在这里引用了  import {vSize} from "../directives";  const size = reactive({    width: 0,    height: 0  })  watchEffect(      () => {        console.log(size.width, size.height)      }  )</script><style lang="scss" scoped>.layout-box{  width: 100px;  height: 100px;  background-color: #f5f5f5;  border: 1px  solid #bd34fe;  overflow: auto;  resize: both;}</style>

写的比较简陋, 如果在使用过程中发现什么问题, 欢迎评论和私信,
如果发现问题, 欢迎一起解决


点击全文阅读


本文链接:http://zhangshiyu.com/post/166933.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • (番外)+(结局)林书意陆沉(林书意陆沉:全书+番外+后续)_(林书意陆沉)列表_笔趣阁(林书意陆沉:全书+番外+后续)
  • 京圈太子爷要退婚,我转头嫁给他哥精彩节选免费试读_沈锦夜青梅苏月完本
  • 妾室软又香,步步谋宠艳压群芳孟嫣然宋景和:结局+番外(孟嫣然宋景和:结局+番外)完结_(孟嫣然宋景和)列表_笔趣阁(妾室软又香,步步谋宠艳压群芳:结局+番外)
  • 丁克老公迎回双胞胎,我消失了厉穆辰乔玉景_丁克老公迎回双胞胎,我消失了厉穆辰乔玉景
  • 重生1959:从巡山员开始发家致富后续大结局更新+番外_[谭飞林舒清]情感冲突名场面试读章
  • 相思烬落冥河渡:结局+番外灵魂人物全书叶流萤冥渊在线
  • (番外)+(全书)(萧旗于尚恩)_失明后老公将闺蜜接来照顾我,我先跑为上列表_笔趣阁(萧旗于尚恩)(萧旗于尚恩)完结_(萧旗于尚恩)列表_笔趣阁(失明后老公将闺蜜接来照顾我,我先跑为上)
  • 季时越夏青栀(旧梦静默成诗:结局+番外)免费在线_季时越夏青栀全文后续(旧梦静默成诗:结局+番外)
  • 明月不可追:结局+番外(薛明月)全书浏览_明月不可追:结局+番外全书浏览
  • 独家《恰似晚风不留我:结局+番外》沈冉顾墨琛沈心_沈冉顾墨琛沈心(恰似晚风不留我:结局+番外)
  • 微风轻拂又见你:+后续完结全书林书意陆沉在线
  • 相思寸寸,终成陌路:结局+番外(楚宴辞温情雪)_相思寸寸,终成陌路:结局+番外(楚宴辞温情雪)

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1