Vue.js中resize事件监听器无法修改data变量值的问题
解决Vue中Resize事件无法修改Data变量的问题
嘿,我太懂你碰到的这个坑了!问题出在普通函数里的this指向——当你在addEventListener里用function()定义回调时,这个回调里的this指向的是window对象,而不是你的Vue组件实例,所以根本访问不到data里的sliderWidth变量。
下面给你几个靠谱的解决方案:
方案1:使用箭头函数(最简洁)
箭头函数不会绑定自己的this,它会继承外层作用域的this(也就是你的Vue组件实例),这样就能直接修改data里的变量了:
<template> <div id="slider"></div> </template> <script> export default { name: 'Slider', mounted() { // 用箭头函数替代普通function window.addEventListener('resize', () => { this.sliderWidth = document.getElementById('slider').offsetWidth; }); // 初始化时先赋值一次,避免页面加载时sliderWidth为0 this.sliderWidth = document.getElementById('slider').offsetWidth; }, data() { return { sliderWidth: 0, }; }, // 组件销毁前移除监听,防止内存泄漏 beforeUnmount() { window.removeEventListener('resize', () => { this.sliderWidth = document.getElementById('slider').offsetWidth; }); } }; </script>
方案2:提前保存Vue实例的引用
如果习惯用普通函数,可以在回调外面先把组件实例的this存起来(比如叫vm),然后在回调里用这个变量访问data:
mounted() { const vm = this; // 保存组件实例的引用 window.addEventListener('resize', function() { vm.sliderWidth = document.getElementById('slider').offsetWidth; }); // 初始化赋值 vm.sliderWidth = document.getElementById('slider').offsetWidth; }
方案3:用Vue的$refs替代getElementById(更符合Vue风格)
Vue推荐用$refs来操作DOM,比原生的getElementById更优雅,也更贴合Vue的组件化思想:
<template> <!-- 给div加ref属性 --> <div ref="slider"></div> </template> <script> export default { name: 'Slider', mounted() { const updateSliderWidth = () => { this.sliderWidth = this.$refs.slider.offsetWidth; }; window.addEventListener('resize', updateSliderWidth); // 初始化赋值 updateSliderWidth(); }, data() { return { sliderWidth: 0, }; }, beforeUnmount() { const updateSliderWidth = () => { this.sliderWidth = this.$refs.slider.offsetWidth; }; window.removeEventListener('resize', updateSliderWidth); } }; </script>
额外提醒:一定要记得在组件销毁时移除resize事件监听,不然会造成内存泄漏哦!
内容的提问来源于stack exchange,提问作者Carlos Pisarello
相关产品推荐
相关产品推荐

