How to make reactive window parameters in Vue.js | window.innerWidth is not reactive
Answer a question i have the trouble that i have to do some calculations based on the innerWidth of the window but whenever i change my window width my computed property doesnt get triggered, how do i
Answer a question
i have the trouble that i have to do some calculations based on the innerWidth of the window but whenever i change my window width my computed property doesnt get triggered, how do i make it work?
Here is my code simplyfied:
var vm = new Vue({
el: '#elment',
computed: {
calculation: function(){
console.log(window.innerWidth)
return window.innerWidth;
}
}
})
The console prints me the width just on the begin 1x. How do i make this reactive? My alternative way was to add an event listener to the body in the mounted hook and to do my calculations there.
Answers
At this moment, there’s no way in VueJS to natively “watch” a window property or making it reactive.
Let's just rewind some concepts of EventBus
in Vue. Vue is capable of creating another truly independent & reactive Vue Instance that is decoupled from the main instance. We often do this when starting a new Vue app or creating an EventBus.
So the solution for this is to create a “WindowInstanceMap”. Create a reactive innerWidth
data and an event listener that silently “mutates” it.
import Vue from 'vue'
const WindowInstanceMap = new Vue({
data() {
return {
innerWidth: 0
}
},
created() {
const self = this;
window.addEventListener('resize', e => {
self.innerWidth = window.innerWidth
})
},
})
export default WindowInstanceMap
With this, we have created a clone of the window interface and innerWidth is reactive. Now let’s try to use it somewhere. Let’s import this in App.js
first to “inititalize” the component:
// App.js
import WindowInstanceMap from './WindowInstanceMap.js'
This will trigger the create()
lifecycle of WindowInstanceMap
and register the resize event listener to window.
Now in my components. All we need to do is map it to a computed
prop.
// SomeComponent.vue
import WindowInstanceMap from './WindowInstanceMap.js'
export default {
computed: {
innerWidth () { return WindowInstanceMap.innerWidth }
}
}
I hope this helps.
更多推荐
所有评论(0)