Reputation: 33
I need to pass a value to a style property inside data, but, because of how vuejs and how JS scopes work, it won't let me access through this.data.property:
Vue.component ('loader-component', {
template: '#loader-template',
mounted: function() {
this.animationTest();
},
data: function() {
return {
svg: true,
timer: 0,
// styles
position: {
marginLeft: '',
marginTop: '',
float: 'left'
}
};
},
methods: {
animation: function() {
let timer = 0,
itemWidth = 60,
domWidth = document.getElementById('awesome-body').clientWidth,
domHeight = document.getElementById('awesome-body').clientHeight,
marginL = -2 * itemWidth,
marginT = Math.floor((Math.random() * domHeight) + 1);
this.position.marginTop = marginT;
setInterval(function() {
marginL = marginL + timer * 5;
timer++;
// console.log(marginL);
this.position.marginLeft = marginL;
}, 1000); // time interval in milliseconds
}
} // methods finishes
});
This will trigger the next error:
Cannot set property 'marginLeft' of undefined.
What's the syntax to go directly from the setInterval function to data.marginTop?
Thanks!
Upvotes: 0
Views: 2619
Reputation: 1379
I think you should try another approach. The problem is that you are referring to an element that isn't rendered yet.
There is several ways to accomplish what you want to do.
With this approach you'll be able to bind data to style, and when your data is updated it automatically update your template.
<template>
<div :style="{ 'margin-left': whateverFunction() }">
</div>
</template>
<script>
...
methods: {
whateverFunction () {
return this.some_attribute + 'px'
}
}
...
</script>
Instead of a function, this also could be a computed property, or an attribute too.
You seem want to achieve a transition on an element, so the simple way to do that is to use the built-in system. And if you want to have more control in your transition, there is javascript hooks to help you manipulate the data during the transition time.
If you really want to access to DOM element inside your code, you should use boolean to wait until your template is totally rendered enter link description here and use ref
special attribute to easily get the desired element.
If you want specific help on a part of your code, give us a jsfiddle to test and debug it.
Upvotes: 0
Reputation: 3288
The this
is referencing the setInterval function and not the component. Do this:
methods: {
animation: function() {
let component = this,
timer = 0,
itemWidth = 60,
domWidth = document.getElementById('awesome-body').clientWidth,
domHeight = document.getElementById('awesome-body').clientHeight,
marginL = -2 * itemWidth,
marginT = Math.floor((Math.random() * domHeight) + 1);
component.position.marginTop = marginT;
setInterval(function() {
marginL = marginL + timer * 5;
timer++;
// console.log(marginL);
component.position.marginLeft = marginL;
}, 1000); // time interval in milliseconds
}
}
Upvotes: 2