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

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

25 人参与  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)
  • 赞助本站

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

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

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