Vuetify中dialog弹窗打开时如何隐藏页面主滚动条?
问题背景
基于Vuetify开发应用时,dialog弹窗打开后页面会同时出现两个滚动条,需求是仅在弹窗处于打开状态时隐藏页面主滚动条。
此前尝试执行document.body.style.overflow = "hidden";实现效果,但方案未生效,相关逻辑写在组件mounted钩子中,代码如下:
async mounted() { this.$store.commit("SET_LOADING", true); try { await this.loadData(); if (!this.item) { this.$showDialog({ title: "Something Wrong", body: `Member not found!`, }); this.closePage(); } else { // here document.body.style.overflow = "hidden"; await this.$store.dispatch("area/get"); this.role = this.item?.roles[0]; if ( this.item?.user && this.$store.state.user?.roles?.find( (x) => x == this.$roles.Admin ) ) this.email = this.item?.user.email; } } catch (error) { Promise.reject(error); } finally { this.$store.commit("SET_LOADING", false); } },
双滚动条效果参考:
解决方案
直接修改body样式不生效的核心原因是:Vuetify默认将滚动容器绑定在带data-app属性的根应用节点(即<v-app>渲染出的元素)上,而非body节点,所以修改body的overflow属性不会影响主滚动条。
推荐方案:使用组件自带属性(无副作用)
Vuetify的v-dialog组件原生提供了hide-overflow属性,只要在弹窗组件上加上该属性,组件会自动在打开时隐藏根容器滚动条、关闭时恢复原有样式,不需要手动操作DOM,也不会出现样式忘记恢复导致页面锁死滚动的问题。
- 直接使用v-dialog组件时写法如下:
<v-dialog v-model="dialogVisible" hide-overflow width="600"> <!-- 弹窗自定义内容 --> </v-dialog>
- 如果是用
this.$showDialog这种全局封装的弹窗方法,直接找到封装该方法的v-dialog组件,给它补上hide-overflow属性即可。
手动控制方案
如果需要手动控制滚动条状态,不要操作body节点,改为操作Vuetify的根应用节点即可:
// 弹窗打开时执行,隐藏主滚动条 document.querySelector('[data-app]').style.overflow = 'hidden' // 弹窗关闭时必须执行,恢复主滚动条,避免页面无法滚动 document.querySelector('[data-app]').style.overflow = 'auto'
注意:把样式修改逻辑写在mounted钩子里的写法本身存在逻辑问题,这段逻辑的执行时机和弹窗实际打开时机不匹配,应该把滚动条控制逻辑绑定到弹窗的打开/关闭事件回调中执行。
内容的提问来源于stack exchange,提问作者Razel
相关产品推荐
相关产品推荐

