I want to implement draggable line using mousedown
, mousemove
and mouseup
events.
In my first attempt I was trying to use arrow-functions-class-properties: https://codesandbox.io/s/example-1-15psm?fontsize=14&hidenavigation=1&theme=dark
But the property position
in Test.vue
seems to be non-reactive. Not sure, but my guess is it's because of this Vue restriction:
Don’t use arrow functions on an options property or callback, such as
created: () => console.log(this.a)
orvm.$watch('a', newValue => this.myMethod())
. Since an arrow function doesn’t have athis
,this
will be treated as any other variable and lexically looked up through parent scopes until found, often resulting in errors such as UncaughtTypeError: Cannot read property of undefined
orUncaught TypeError: this.myMethod is not a function
.
In my second attempt I've tryed to use standart class methods: https://codesandbox.io/s/example-2-t7beu?fontsize=14&hidenavigation=1&theme=dark
It works, except since binded functions onMouseMove
and onMouseUp
in Test.vue
are anonymous I can't unbind them with removeEventListener
.
So, what's the proper way of using addEventListener
and removeEventListener
in Vue class components?
I've overengineered my code.
There is no need to use arrow-functions-class-properties
, or defining context by using method.bind(this)
. The following code should work:
import { Vue, Component } from "vue-property-decorator";
@Component
export default class Test extends Vue {
position = 0;
onMouseMove(e) {
let position = this.position;
position += e.movementY;
this.position = position;
console.log("onMouseMove", this.position);
}
onMouseUp() {
console.log("onMouseUp", this.position);
document.removeEventListener("mousemove", this.onMouseMove);
document.removeEventListener("mouseup", this.onMouseUp);
}
onMouseDown() {
console.log("onMouseDown", this.position);
document.addEventListener("mousemove", this.onMouseMove);
document.addEventListener("mouseup", this.onMouseUp);
}
}
Working example: https://codesandbox.io/s/example-2-t7beu?fontsize=14&hidenavigation=1&theme=dark