Vue3中监听页面窗体大小改变

<template>
	<div class="container">
		<h1> 测量数据</h1>
		<hr>
		<!-- -->
		<div class="plugins-tips">
			<el-row>
				<el-date-picker v-model="QueryDate" type="date" placeholder="Pick a day" :size="size" />

				<el-button type="primary" @click="QueryGlueMeasurement()">
					查询
				</el-button>
				<el-button type="primary" @click="ToExcel()">
					导出excel
				</el-button> 
			</el-row>
			<div> 
			</div>
			<br>
			<br>
			<br>
			<br>
			<br>
		</div>
	</div>
</template>

<script setup lang="ts" name="laserParameter">
import { ref, reactive, onMounted, getCurrentInstance, watch, onUnmounted } from 'vue'
import { global_const } from '../../globalconst'
import axios from 'axios'
import dateFormat from '../../globalFun'
import XEUtils from 'xe-utils'
import { ElMessage } from 'element-plus' 
const QueryDate = ref('')
const TableHeight = ref('400')

const screenWidth = ref(window.innerWidth)
const screenHeigth = ref(window.innerHeight)
  
const  onResize=()=> {
    screenWidth.value = window.innerWidth;
    screenHeigth.value = window.innerHeight;
  }

onMounted(async () => {
	QueryDate.value = dateFormat(new Date(), 'YYYY-MM-DD') 
	window.addEventListener("resize", onResize);
})
onUnmounted(() => {
    window.removeEventListener("resize", onResize);
  });

watch(screenHeigth, (newValue, oldValue) => {
	TableHeight.value = (document.documentElement.clientHeight-300).toString()
}) 

</script>

<style scoped>
.dialog-footer button:first-child {
	margin-right: 10px;
}

</style>

<think>我们正在处理一个关于在Vue3中使用TypeScript监听窗口大小变化的问题。根据提供的引用,我们可以总结出以下关键点: 1.Vue中,我们可以通过监听`window`的`resize`事件来响应窗口大小的变化。 2. 为了避免频繁触发事件,通常需要进行防抖处理(debounce)或节流处理(throttle)。 3.Vue3中,我们可以在组件的`mounted`生命周期钩子中添加事件监听,并在`beforeUnmount`钩子中移除事件监听,以避免内存泄漏。 结合TypeScript,我们需要在Vue3组件中以类型安全的方式实现这一功能。 ### 实现步骤: 1. **创建防抖函数**:为了避免窗口大小变化时频繁触发事件,我们需要一个防抖函数。可以使用Lodash的`_.debounce`或者自己实现一个简单的防抖函数。 2. **在`mounted`钩子中绑定事件**:在组件挂载时,将防抖后的处理函数绑定到`window`的`resize`事件上。 3. **在`beforeUnmount`钩子中移除事件**:在组件销毁前,移除事件监听,防止内存泄漏。 4. **定义处理函数**:这个函数用于处理窗口大小变化时的逻辑,比如更新组件的响应式数据。 ### 代码示例: 下面是一个使用Vue3和TypeScript实现的示例: ```typescript <template> <div> 当前窗口宽度: {{ windowWidth }}px </div> </template> <script lang="ts"> import { defineComponent, ref, onMounted, onBeforeUnmount } from &#39;vue&#39;; export default defineComponent({ setup() { const windowWidth = ref(window.innerWidth); // 处理窗口大小变化的函数 const handleResize = () => { windowWidth.value = window.innerWidth; // 这里可以添加其他需要随窗口大小变化而执行的代码 }; // 防抖函数(简单实现) const debounce = (fn: Function, delay: number) => { let timer: number | null = null; return () => { if (timer) { clearTimeout(timer); } timer = setTimeout(() => { fn(); }, delay); }; }; // 使用防抖包装处理函数 const debouncedHandleResize = debounce(handleResize, 200); // 组件挂载时添加事件监听 onMounted(() => { window.addEventListener(&#39;resize&#39;, debouncedHandleResize); }); // 组件卸载前移除事件监听 onBeforeUnmount(() => { window.removeEventListener(&#39;resize&#39;, debouncedHandleResize); }); return { windowWidth }; } }); </script> ``` ### 说明: 1. **防抖函数**:我们实现了一个简单的防抖函数,它会在事件停止触发200毫秒后执行处理函数。这样可以避免在窗口调整过程中频繁更新数据,减少性能开销。 2. **使用Composition API**:在`setup`函数中,我们使用`ref`创建响应式变量`windowWidth`来存储当前窗口宽度。 3. **生命周期钩子**:使用`onMounted`和`onBeforeUnmount`来添加和移除事件监听器。这是Vue3的Composition API中处理生命周期的方式。 4. **类型安全**:TypeScript帮助我们为函数参数和变量提供了类型注解,确保类型安全。 ### 注意事项: - 如果需要更复杂的防抖或节流功能,可以考虑使用Lodash等库。 - 在组件卸载时一定要移除事件监听,否则可能导致内存泄漏。 - 如果需要在多个组件中使用相同的逻辑,可以考虑将这段代码提取为一个可重用的Composition Function(组合式函数)。 ### 组合式函数封装: 为了复用,我们可以将窗口大小监听逻辑封装成一个组合式函数: ```typescript // useWindowResize.ts import { ref, onMounted, onBeforeUnmount } from &#39;vue&#39;; export function useWindowResize(delay = 200) { const width = ref(window.innerWidth); const height = ref(window.innerHeight); const handleResize = () => { width.value = window.innerWidth; height.value = window.innerHeight; }; const debounce = (fn: Function, delay: number) => { let timer: number | null = null; return () => { if (timer) { clearTimeout(timer); } timer = setTimeout(() => { fn(); }, delay); }; }; const debouncedHandleResize = debounce(handleResize, delay); onMounted(() => { window.addEventListener(&#39;resize&#39;, debouncedHandleResize); }); onBeforeUnmount(() => { window.removeEventListener(&#39;resize&#39;, debouncedHandleResize); }); return { width, height }; } ``` 然后在组件中使用: ```typescript <template> <div> 宽度: {{ width }}px, 高度: {{ height }}px </div> </template> <script lang="ts"> import { defineComponent } from &#39;vue&#39;; import { useWindowResize } from &#39;./useWindowResize&#39;; export default defineComponent({ setup() { const { width, height } = useWindowResize(); return { width, height }; } }); </script> ``` 这样,我们就实现了一个在Vue3中使用TypeScript监听窗口大小变化的功能,并且封装成了可复用的组合式函数。 §§相关问题§§ 1. 如何在Vue3中处理其他全局事件(如scroll)? 2. Vue3的组合式函数(Composition Functions)有哪些优势? 3. 除了防抖,还有哪些优化事件处理性能的方法?</think>### 在 Vue3 + TypeScript 中监听窗口大小变化 在 Vue3 中使用 TypeScript 监听窗口大小变化,可以通过组合式 API 实现。以下是完整解决方案: #### 1. 基本实现(带防抖优化) ```typescript <template> <div>窗口宽度: {{ windowWidth }}px</div> </template> <script setup lang="ts"> import { ref, onMounted, onBeforeUnmount } from &#39;vue&#39;; const windowWidth = ref(window.innerWidth); // 防抖处理 let debounceTimer: number | null = null; const handleResize = () => { if (debounceTimer) clearTimeout(debounceTimer); debounceTimer = setTimeout(() => { windowWidth.value = window.innerWidth; console.log("新宽度:", windowWidth.value); // 这里添加你的业务逻辑 }, 200); // 200ms防抖延迟 }; onMounted(() => { window.addEventListener(&#39;resize&#39;, handleResize); }); onBeforeUnmount(() => { window.removeEventListener(&#39;resize&#39;, handleResize); }); </script> ``` #### 2. 封装为可复用组合函数 创建 `useWindowResize.ts`: ```typescript import { ref, onMounted, onBeforeUnmount } from &#39;vue&#39;; export default function useWindowResize(delay = 200) { const width = ref(window.innerWidth); const height = ref(window.innerHeight); let timer: number | null = null; const handler = () => { if (timer) clearTimeout(timer); timer = setTimeout(() => { width.value = window.innerWidth; height.value = window.innerHeight; }, delay); }; onMounted(() => window.addEventListener(&#39;resize&#39;, handler)); onBeforeUnmount(() => window.removeEventListener(&#39;resize&#39;, handler)); return { width, height }; } ``` 在组件中使用: ```typescript <script setup lang="ts"> import useWindowResize from &#39;./useWindowResize&#39;; const { width, height } = useWindowResize(300); // 300ms防抖 </script> <template> <div> 宽度: {{ width }}px <br> 高度: {{ height }}px </div> </template> ``` #### 3. 使用 Lodash 防抖(推荐) 安装依赖: ```bash npm install lodash-es @types/lodash-es ``` 优化版组合函数: ```typescript // useWindowResize.ts import { ref } from &#39;vue&#39;; import { debounce } from &#39;lodash-es&#39;; export default function useWindowResize(options = { debounce: 200 }) { const width = ref(window.innerWidth); const height = ref(window.innerHeight); const handler = debounce(() => { width.value = window.innerWidth; height.value = window.innerHeight; }, options.debounce); window.addEventListener(&#39;resize&#39;, handler); return { width, height }; } ``` #### 关键要点: 1. **生命周期管理**: - 在 `onMounted` 添加事件监听 - 在 `onBeforeUnmount` 移除监听,避免内存泄漏[^2] 2. **防抖处理**: - 避免频繁触发影响性能 - 推荐使用 Lodash 的 `_.debounce`[^4][^5] 3. **响应式数据**: - 使用 `ref` 创建响应式变量 - 自动更新组件视图 4. **TypeScript 类型**: - 明确事件处理器类型:`(this: Window, ev: UIEvent) => any` - 使用 `number` 类型存储超时标识 #### 注意事项: - 移动端开发需考虑设备旋转事件 (`orientationchange`) - 复杂布局建议配合 CSS 媒体查询实现响应式 - 服务器端渲染 (SSR) 需添加 `if (typeof window !== &#39;undefined&#39;)` 判断
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值