vue3自定義指令自動(dòng)獲取節(jié)點(diǎn)的width和height代碼示例
前言
想寫一個(gè)依賴庫, 但是需要監(jiān)聽組件的width和height這些數(shù)據(jù), 就找到了ResizeObserver
這個(gè)方法,不想每次使用的時(shí)候都要?jiǎng)?chuàng)建和銷毀 ResizeObserver
, 索性就直接封裝成為一個(gè)指令用來獲取想要的信息,
ResizeObserver對象上能夠獲取的信息還是非常多的, 除了width, height
還有 top, bottom, left, top
等, 需要使用到這些可以到MDN去查看他的使用方法
實(shí)現(xiàn)效果當(dāng)元素大小發(fā)生改變時(shí),會自動(dòng)更新width 和height 的值
一. 環(huán)境
"vue": "^3.4.29"
二. 代碼
文件ResizeObserverStore.ts
class ResizeObserverStore { // 存儲目標(biāo)元素和對應(yīng)的ResizeObserver實(shí)例 observer= new Map<HTMLElement, ResizeObserver[]>(); // 獲取目標(biāo)元素對應(yīng)的ResizeObserver實(shí)例 get(target: HTMLElement) { return this.observer.get(target) || []; } // 設(shè)置目標(biāo)元素對應(yīng)的ResizeObserver實(shí)例 set(target: HTMLElement, observer: ResizeObserver) { const observers = this.observer.get(target); if (observers) { observers.push(observer); } else { this.observer.set(target, [observer]); } }; // 銷毀目標(biāo)元素對應(yīng)的ResizeObserver實(shí)例 remove(target: HTMLElement) { const observers = this.observer.get(target); // 銷毀事件 if (observers) { observers.forEach(observer => { observer.disconnect(); }); this.observer.delete(target); } } } // 創(chuàng)建一個(gè)ResizeObserverStore實(shí)例 const resizeObserverStore = new ResizeObserverStore(); // 使用ResizeObserver監(jiān)聽目標(biāo)元素的變化 export const useResizeObserver = (target: HTMLElement, callback: ResizeObserverCallback) => { const observer = new ResizeObserver(callback); observer.observe(target); resizeObserverStore.set(target, observer); return observer; } // 移除ResizeObserver監(jiān)聽 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對象,它可以用于監(jiān)聽元素邊界尺寸的大小。
三. 使用 (全局 或 局部 使用都可以)
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>
總結(jié)
到此這篇關(guān)于vue3自定義指令自動(dòng)獲取節(jié)點(diǎn)的width和height的文章就介紹到這了,更多相關(guān)vue3自動(dòng)獲取節(jié)點(diǎn)的width和height內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue項(xiàng)目中ESlint規(guī)范示例代碼
這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目中ESlint規(guī)范的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07一篇文章帶你使用Typescript封裝一個(gè)Vue組件(簡單易懂)
這篇文章主要介紹了使用Typescript封裝一個(gè)Vue組件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06利用Vue實(shí)現(xiàn)卡牌翻轉(zhuǎn)的特效
這篇文章主要介紹了如何利用Vue實(shí)現(xiàn)一個(gè)春節(jié)抽??撁?,采用了卡牌翻轉(zhuǎn)的形式。文中的實(shí)現(xiàn)方法講解詳細(xì),快跟隨小編一起學(xué)習(xí)一下吧2022-02-02vue3.0+echarts實(shí)現(xiàn)立體柱圖
這篇文章主要為大家詳細(xì)介紹了vue3.0+echarts實(shí)現(xiàn)立體柱圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09基于vue-cli3多頁面開發(fā)apicloud應(yīng)用的教程詳解
這篇文章主要介紹了基于vue-cli3多頁面開發(fā)apicloud應(yīng)用,本文采用vue-cli+APIcloud的方式寫解決以上痛點(diǎn),開發(fā)靈活,并且打包之后體積更小速度更快,需要的朋友可以參考下2019-06-06