相关文章推荐
想出国的大象  ·  vue ...·  1 月前    · 
无聊的莴苣  ·  Vue 中 $set() 与 ...·  1 月前    · 
坚韧的跑步鞋  ·  Layui ...·  1 月前    · 
挂过科的镜子  ·  VUE 使用 select ...·  1 月前    · 
重感情的丝瓜  ·  macOS SDK 疑難解答 - ...·  8 月前    · 
冷冷的夕阳  ·  MG动画 | ...·  12 月前    · 

项目中有一个需求,搜索框的宽度需要根据页面宽度动态变化,例如宽度小于等于1280时搜索框的宽度为280px,大于1920时宽度为360px,在1280和1920之间则根据比例缩放。

由于页面是flex布局,并且靠两端对齐的,所以给搜索框设置 min-width max-width 基本上是排不上用场了。当时首先想到的是 媒体查询 ,但是 媒体查询 不能实现按比例缩放的效果。后来想到通过 JS 获取页面的 innerWidth ,然后根据这个值来判断搜索框应该取多少宽度。

那么这个逻辑应该放在什么位置呢?先在计算属性里面试了下,代码如下:

<template>
	<el-input v-model="search" :style="{'width': `${searchFormWidth}px`}"
</template>
<script>
export default {
	computed: {
		searchFormWidth() {
	      let w = window.innerWidth;
	      if(w <= 1280) {
	        return 280
	      } else if (w < 1920) {
	        return ((w - 1280)*80)/640 + 280
	      } else {
	        return 360
</script>

计算属性具有缓存,并且依赖改变后,会重新计算,所以经常用于动态样式绑定。但是经过试验后发现, searchFormWidth 只会在组件初始化的时候调用一次,之后页面缩放无法改变搜索框宽度。

看来计算属性只能监听响应式依赖的变化,对于 window 对象属性的变化无法检测。那就另辟蹊径,通过监听浏览器的窗口缩放事件 window.onresize ,在组件的 mounted 钩子里面绑定监听回调,然后在 methods 中定义 searchFormWidth 方法动态计算宽度。

<template>
	<el-input v-model="search" :style="{'width': `${searchWidth}px`}"
</template>
<script>
export default {
	data() {
		return {
			searchWidth: 280
	mounted() {
		this.searchFormWidth(); // 组件初始化的时候不会触发onresize事件,这里强制执行一次
	    window.onresize = () => {
	      if(!this.timer){ // 使用节流机制,降低函数被触发的频率
	        this.timer = true;
	        let that = this; // 匿名函数的执行环境具有全局性,为防止this丢失这里用that变量保存一下
	        setTimeout(function(){
	          that.searchFormWidth();
	          that.timer = false;
	        },400)
	destroyed() {
		// 组件销毁后解绑事件
		window.onresize = null;
	methods: {
		searchFormWidth() {
	      let w = window.innerWidth;
	      if(w <= 1280) {
	        this.searchWidth = 280
	      } else if (w < 1920) {
	        this.searchWidth = ((w - 1280)*80)/640 + 280
	      } else {
	        this.searchWidth = 360
</script>

这边有个注意点,也就是在组件销毁后需要手动解绑事件

在 Vue 中通过 v-on 绑定的事件,在组件销毁后会自动解绑。

window 对象上的事件,例如 window.onresizewindow.addEventListener ,组件销毁后是不会解绑的,必须手动在 destroyed 钩子中解绑。还有一些定时器也是一样操作。

至于为什么建议在 destroyed 钩子而不是 beforeDestroy ,因为通常组件中可能还嵌套了很多子组件,我们知道父子组件生命周期顺序:

1. 加载渲染过程
父组件 beforeCreate -> 父组件 created -> 父组件 beforeMount -> 子组件 beforeCreate -> 子组件 created -> 子组件 beforeMount -> 子组件 mounted -> 父组件 mounted
2. 子组件更新过程
父组件 beforeUpdate -> 子组件 beforeUpdate -> 子组件 updated -> 父组件 updated
3. 父组件更新过程
父组件 beforeUpdate -> 父组件 updated
4. 销毁过程
父组件 beforeDestroy -> 子组件 beforeDestroy -> 子组件 destroyed -> 父组件 destroyed

从上面就可以看出,父组件进入 beforeDestroy ,子组件此时并没有销毁,在这个时候如果解绑事件,可能会导致子组件出问题,因此建议在 destroyed 钩子中解绑。

参考:
vue项目如何监听窗口变化,达到页面自适应?

原生 document 对象上,就有这些数据。 // 宽度: document.body.clientWidth // 高度: document.body.clientHeight data() { // 可直接挂载到data数据上 return { Width: document.body.clientWidth, Height: document.body.clientHeight, mounted() { window.onresize = function () { console.log("宽度", document.documentElement.clientWidth); console.log("高度", document.documentElement.clientHeight); return { screenWidth: document.body.clientWidth, // 屏幕宽度 screenHeight: document.body.clientHeight, // 屏幕高度 2、在mounted函数中获取 mounted() { const that = this; window.onresize = () => { return ( VUE动态获取浏览器宽高,动态获取元素宽高,动态设置元素的宽高或样式动态获取浏览器宽高动态获取元素宽高动态设置元素的宽高或样式 动态获取浏览器宽高 created(){ window.addEventListener('resize', this.GetWindowInfo); //注册监听器 this.GetWindowInfo() //页面创建时先调用一次 methods:{ GetWindowInfo(){ var width = window.innerWidth // 宽 return { windowWidth: document.documentElement.clientWidth, // 实时屏幕宽度 windowHeight: document.documentElement.clientHeight // 实时屏幕高度 mounted() { // 实时获取浏览器宽度高度 const that = this window.onresize = () => .. 当Vue页面需要显示在不同尺寸的移动端屏幕上时,一些固定尺寸的组件就会有不一致的表现效果。在使用element样式库时,有些组件还是贴心的给出了:width的参数,可以使用:width:200直接修改宽度;但有些组件就没有提供这种方法,比如文件拖动上传组件的尺寸是写死的360×180,并且无法通过改变父元素upload-demo的样式来修改内部样式: 而现在的一个需求就是想让这个组件的宽度永远填满页面。 修改组件内部class的样式 修改element的内部样式的两种方式 首先在组件上添加自己的一 vue如何动态获取浏览器的高度和宽度,对于某些小伙伴来说间直接是简单到不能再简单了,为什么要整理这篇文章呢,源于最近项目中有高度、宽度自适应需求,需要适应不同分辨率的高度及宽度,在不同分辨率下效果区别不会很大,而我正好带着一位实习生小伙伴,所以把这需求给他让他练练手,结果可想而知了,所以整理这篇文章也是为了给后面的小伙伴提供参考而已,好了废话不多说,直接上源码。HTML代码:javascript代... vue 获取当前屏幕的宽度,图片等比例缩放这个是一个背景图,点击对应的圆圈就会出现一个蒙层上面显示详情,但是只要当前窗口大小变化了,因为我的蒙层大小是固定的px,所以不会变,就不在图片对应的位置了我们要绑定样式style,等后面要根据当前的屏幕来给蒙层动态设置宽高:to="{name:'/streetDetails',query:{code:'310151101'}}":style="style0... 有时页面需要根据浏览器宽高进行样式或逻辑的变化,这时候就需要 实时 获取浏览器窗口宽高。 在生命周期钩子函数 mounted() 中通过 document.body.clientWidth | document.body.clientHeight 获取浏览器宽高,然后通过 window.onresize 监听浏览器窗口变化,当变化时修改 data() 变量来实现。 <template> <h2>当前宽度: {{ screenWidth