iT邦幫忙

2023 iThome 鐵人賽

DAY 7
1
Vue.js

Vue3歡樂套件箱耶系列 第 7

開箱7:偵測元素寬度~useResizeObserver範例應用

  • 分享至 

  • xImage
  •  

本篇開箱是VueUse中的useResizeObserver方法,簡單就能取元素的寬高

昨篇介紹的是針對整個螢幕的寬高去做偵測,但是如果今天的需求是當某一個元素寬度變化時...要去做不同的設計呢?這時候就可以使用useResizeObserver方法了

介紹

VueUse 是一個基於Vue.js 的開源函式庫,主要是以 composition API 做成的函式工具庫

官方網站
https://vueuse.org/

安裝

npm i @vueuse/core

典型應用

<template>
  <div ref="el">
    {{ text }}
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { useResizeObserver } from '@vueuse/core';
const el = ref(null);
const text = ref('');

useResizeObserver(el, entries => {
  const entry = entries[0];
  const { width, height } = entry.contentRect;
  text.value = `width: ${width}, height: ${height}`;
});
</script>

官方範例
https://vueuse.org/core/useResizeObserver/

今日姊姊Demo時間


成果

<template>
  <div class="container pt-8 border">
    <ul ref="el" class="bg-amber-200 w-1/2 p-4 m-auto">
      <li class="text-xl">我是ul的寬: {{ ulWidth }} x 高{{ ulHeight }}</li>
    </ul>

    <div class="px-4 py-2 bg-cyan-500 text-white mt-2" v-if="ulWidth <= 350">
      我是ul的寬度350以下才要出現
      <img
        src="https://miro.medium.com/v2/resize:fit:720/1*XGw9zUEZGYPNmeKGmyeX1g.jpeg"
        alt=""
      />
    </div>
  </div>
</template>
<script setup>
import { ref, watch } from 'vue';
import { useResizeObserver } from '@vueuse/core';
const el = ref(null);
const ulWidth = ref(0);
const ulHeight = ref(0);

useResizeObserver(el, entries => {
  const entry = entries[0];
  console.log('entry', entry);
  const { width, height } = entry.contentRect;
  ulWidth.value = width;
  ulHeight.value = height;
});
</script>

這樣就完成啦!!

Demo網址:https://master--hahasister-ironman-project.netlify.app/#/resizeObserver

備註

  • 在Vue中,可以使用ref屬性用來在Vue組件中訪問子組件或DOM元素的一種方法
<template>
  <div class="container pt-8 border">
    <ul ref="el" class="bg-amber-200 w-1/2 p-4 m-auto">
     ...
    </ul>
    ...
  </div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
const el = ref(null);

onMounted(() => {
  console.log('DOM ul:', el.value);
});
</script>

  • entry.contentRect所獲得的寬高,預設是content-box(內容物範圍),若需要box-sizing(含padding+border範圍)就需要改抓 borderBoxSize[0].inlineSize / borderBoxSize[0].blockSize

-實作原理是根據 Resize Observer API
ResizeObserver是一種Web API,用於監視DOM元素的大小變化,並在其大小變化時觸發回呼函數。它是為了解決監視元素大小變化的需求而引入的

所以我們也可以不使用useResizeObserver方法,改使用原生的ResizeObserver Web API,將程式碼改為以下,

<template>
  <div class="container pt-8 border">
    <ul ref="el" class="bg-amber-200 w-1/2 p-4 m-auto">
      <li class="text-xl">我是ul的寬: {{ ulWidth }} x 高{{ ulHeight }}</li>
    </ul>

    <div class="px-4 py-2 bg-cyan-500 text-white mt-2" v-if="ulWidth <= 350">
      我是ul的寬度350以下才要出現
      <img
        src="https://miro.medium.com/v2/resize:fit:720/1*XGw9zUEZGYPNmeKGmyeX1g.jpeg"
        alt=""
      />
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';

const el = ref(null);
const ulWidth = ref(0);
const ulHeight = ref(0);

const resizeObserver = new ResizeObserver(entries => {
  const entry = entries[0];
  const { width, height } = entry.contentRect;
  ulWidth.value = width;
  ulHeight.value = height;
});

onMounted(() => {
  console.log('DOM ul:', el.value);
  resizeObserver.observe(el.value);
});
</script>
  • const resizeObserver = new ResizeObserver(entries => { ... });:建立一個ResizeObserver實例,建構函數接受一個回呼函數,該函數會在觀察到的元素大小變化時被呼叫。回調函數中的entries參數是一個包含變化訊息的數組,通常我們只監視一個元素,所以在程式碼中取第一個元素。

  • onMounted(() => { ... });:在元件掛載後執行的鉤子函數。使用resizeObserver.observe(el.value)開始觀察元素的大小變化。

那我們明天再見了~


上一篇
開箱6:偵測螢幕寬度~useWindowSize範例應用
下一篇
開箱8:RWD斷點設計大公開~TailwindCSS設定範例
系列文
Vue3歡樂套件箱耶30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言