Vue js and fabric js logic
I am using Vue.js and one of my components is 2D canvas editor (by using fabric.js library).
The thing is, that the code for this editor and for the operations that I am making in it is getting pretty verbose to be part of the component script tag.
I tried using mixins and divided the code into separate mixins like canvasMoving
, copyPaste
, grouping
.
Now while this works, I feel like this is still not the way to go, that maybe I should use specialized classes. Also I belive mixin is when you have a functionality to share between multiple components.
Because for example the copyPaste
mixin, sometimes needs methods, that are contained in the mixin grouping
. This then feels really wrong to me, that since the component includes both of those mixins, it works ok, but if I would remove one of them, it would stop working.
More over all of these mixins works with the canvas, but the canvas is initialized only in one of them and again, they can access it, because the component includes all the mixins, but if I remove the mixin that initializes the canvas, they all stop working because this.canvas
will be undefined.
What is the correct approach here? I was thinking about classes with dependency injection, like having master class lets say Editor
and it would have its dependencies (grouping, copyPaste, drawing) or something like that.
Then the only thing I do not know is how to connect my separate classes with the Vue.js component. Put the master class in the data
object of my component?
javascript vue.js dependency-injection es6-class
add a comment |
I am using Vue.js and one of my components is 2D canvas editor (by using fabric.js library).
The thing is, that the code for this editor and for the operations that I am making in it is getting pretty verbose to be part of the component script tag.
I tried using mixins and divided the code into separate mixins like canvasMoving
, copyPaste
, grouping
.
Now while this works, I feel like this is still not the way to go, that maybe I should use specialized classes. Also I belive mixin is when you have a functionality to share between multiple components.
Because for example the copyPaste
mixin, sometimes needs methods, that are contained in the mixin grouping
. This then feels really wrong to me, that since the component includes both of those mixins, it works ok, but if I would remove one of them, it would stop working.
More over all of these mixins works with the canvas, but the canvas is initialized only in one of them and again, they can access it, because the component includes all the mixins, but if I remove the mixin that initializes the canvas, they all stop working because this.canvas
will be undefined.
What is the correct approach here? I was thinking about classes with dependency injection, like having master class lets say Editor
and it would have its dependencies (grouping, copyPaste, drawing) or something like that.
Then the only thing I do not know is how to connect my separate classes with the Vue.js component. Put the master class in the data
object of my component?
javascript vue.js dependency-injection es6-class
add a comment |
I am using Vue.js and one of my components is 2D canvas editor (by using fabric.js library).
The thing is, that the code for this editor and for the operations that I am making in it is getting pretty verbose to be part of the component script tag.
I tried using mixins and divided the code into separate mixins like canvasMoving
, copyPaste
, grouping
.
Now while this works, I feel like this is still not the way to go, that maybe I should use specialized classes. Also I belive mixin is when you have a functionality to share between multiple components.
Because for example the copyPaste
mixin, sometimes needs methods, that are contained in the mixin grouping
. This then feels really wrong to me, that since the component includes both of those mixins, it works ok, but if I would remove one of them, it would stop working.
More over all of these mixins works with the canvas, but the canvas is initialized only in one of them and again, they can access it, because the component includes all the mixins, but if I remove the mixin that initializes the canvas, they all stop working because this.canvas
will be undefined.
What is the correct approach here? I was thinking about classes with dependency injection, like having master class lets say Editor
and it would have its dependencies (grouping, copyPaste, drawing) or something like that.
Then the only thing I do not know is how to connect my separate classes with the Vue.js component. Put the master class in the data
object of my component?
javascript vue.js dependency-injection es6-class
I am using Vue.js and one of my components is 2D canvas editor (by using fabric.js library).
The thing is, that the code for this editor and for the operations that I am making in it is getting pretty verbose to be part of the component script tag.
I tried using mixins and divided the code into separate mixins like canvasMoving
, copyPaste
, grouping
.
Now while this works, I feel like this is still not the way to go, that maybe I should use specialized classes. Also I belive mixin is when you have a functionality to share between multiple components.
Because for example the copyPaste
mixin, sometimes needs methods, that are contained in the mixin grouping
. This then feels really wrong to me, that since the component includes both of those mixins, it works ok, but if I would remove one of them, it would stop working.
More over all of these mixins works with the canvas, but the canvas is initialized only in one of them and again, they can access it, because the component includes all the mixins, but if I remove the mixin that initializes the canvas, they all stop working because this.canvas
will be undefined.
What is the correct approach here? I was thinking about classes with dependency injection, like having master class lets say Editor
and it would have its dependencies (grouping, copyPaste, drawing) or something like that.
Then the only thing I do not know is how to connect my separate classes with the Vue.js component. Put the master class in the data
object of my component?
javascript vue.js dependency-injection es6-class
javascript vue.js dependency-injection es6-class
asked Nov 21 '18 at 12:05
Zdeněk BraunZdeněk Braun
93210
93210
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
So in the end I solved this by using normal classes instead of mixins. I also used bottlejs for dependency injection.
Now each class in its constructor specifies other classes, that it needs to use, so it is immediately clear which classes it is dependent on.
Also before when one mixin needed to call other mixin's method, it was a simple this.methodName()
call with no knowledge about where this method is located, whereas now it is clearly stated by this._otherClass.methodName()
Since I needed access to canvas, store and also to emit events, I created class Editor, that has a method init(canvas, store, eventBus)
, because I can only create the Fabric canvas, after the HTML canvas is displayed. Bottle creates this class with empty fields and I call the init function with the parameters in mounted stage of my component.
All of my classes are then ancestors of EditorProvider class, which only has one getter for this Editor class (that it gets in a constructor and stores in a field), from where I can get any of the specified fields. So the call to store in any of my classes looks like:
this.editor.store.commit('anything')
Call to canvas:
this.editor.canvas.renderAll()
Call to eventbus:
this.editor.eventBus.emit('eventName')
My component now just imports the bottlejs and has access to all the classes by their names. The interaction is mainly by the canvas and window events, so I event created an EventHandler class, that moves all these event listeners from the component to separate class. So in the end in the component I only have HTML template and a few lines of imports and the script tag, which is now much more readable and the dependencies are clearly visible.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53411659%2fvue-js-and-fabric-js-logic%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
So in the end I solved this by using normal classes instead of mixins. I also used bottlejs for dependency injection.
Now each class in its constructor specifies other classes, that it needs to use, so it is immediately clear which classes it is dependent on.
Also before when one mixin needed to call other mixin's method, it was a simple this.methodName()
call with no knowledge about where this method is located, whereas now it is clearly stated by this._otherClass.methodName()
Since I needed access to canvas, store and also to emit events, I created class Editor, that has a method init(canvas, store, eventBus)
, because I can only create the Fabric canvas, after the HTML canvas is displayed. Bottle creates this class with empty fields and I call the init function with the parameters in mounted stage of my component.
All of my classes are then ancestors of EditorProvider class, which only has one getter for this Editor class (that it gets in a constructor and stores in a field), from where I can get any of the specified fields. So the call to store in any of my classes looks like:
this.editor.store.commit('anything')
Call to canvas:
this.editor.canvas.renderAll()
Call to eventbus:
this.editor.eventBus.emit('eventName')
My component now just imports the bottlejs and has access to all the classes by their names. The interaction is mainly by the canvas and window events, so I event created an EventHandler class, that moves all these event listeners from the component to separate class. So in the end in the component I only have HTML template and a few lines of imports and the script tag, which is now much more readable and the dependencies are clearly visible.
add a comment |
So in the end I solved this by using normal classes instead of mixins. I also used bottlejs for dependency injection.
Now each class in its constructor specifies other classes, that it needs to use, so it is immediately clear which classes it is dependent on.
Also before when one mixin needed to call other mixin's method, it was a simple this.methodName()
call with no knowledge about where this method is located, whereas now it is clearly stated by this._otherClass.methodName()
Since I needed access to canvas, store and also to emit events, I created class Editor, that has a method init(canvas, store, eventBus)
, because I can only create the Fabric canvas, after the HTML canvas is displayed. Bottle creates this class with empty fields and I call the init function with the parameters in mounted stage of my component.
All of my classes are then ancestors of EditorProvider class, which only has one getter for this Editor class (that it gets in a constructor and stores in a field), from where I can get any of the specified fields. So the call to store in any of my classes looks like:
this.editor.store.commit('anything')
Call to canvas:
this.editor.canvas.renderAll()
Call to eventbus:
this.editor.eventBus.emit('eventName')
My component now just imports the bottlejs and has access to all the classes by their names. The interaction is mainly by the canvas and window events, so I event created an EventHandler class, that moves all these event listeners from the component to separate class. So in the end in the component I only have HTML template and a few lines of imports and the script tag, which is now much more readable and the dependencies are clearly visible.
add a comment |
So in the end I solved this by using normal classes instead of mixins. I also used bottlejs for dependency injection.
Now each class in its constructor specifies other classes, that it needs to use, so it is immediately clear which classes it is dependent on.
Also before when one mixin needed to call other mixin's method, it was a simple this.methodName()
call with no knowledge about where this method is located, whereas now it is clearly stated by this._otherClass.methodName()
Since I needed access to canvas, store and also to emit events, I created class Editor, that has a method init(canvas, store, eventBus)
, because I can only create the Fabric canvas, after the HTML canvas is displayed. Bottle creates this class with empty fields and I call the init function with the parameters in mounted stage of my component.
All of my classes are then ancestors of EditorProvider class, which only has one getter for this Editor class (that it gets in a constructor and stores in a field), from where I can get any of the specified fields. So the call to store in any of my classes looks like:
this.editor.store.commit('anything')
Call to canvas:
this.editor.canvas.renderAll()
Call to eventbus:
this.editor.eventBus.emit('eventName')
My component now just imports the bottlejs and has access to all the classes by their names. The interaction is mainly by the canvas and window events, so I event created an EventHandler class, that moves all these event listeners from the component to separate class. So in the end in the component I only have HTML template and a few lines of imports and the script tag, which is now much more readable and the dependencies are clearly visible.
So in the end I solved this by using normal classes instead of mixins. I also used bottlejs for dependency injection.
Now each class in its constructor specifies other classes, that it needs to use, so it is immediately clear which classes it is dependent on.
Also before when one mixin needed to call other mixin's method, it was a simple this.methodName()
call with no knowledge about where this method is located, whereas now it is clearly stated by this._otherClass.methodName()
Since I needed access to canvas, store and also to emit events, I created class Editor, that has a method init(canvas, store, eventBus)
, because I can only create the Fabric canvas, after the HTML canvas is displayed. Bottle creates this class with empty fields and I call the init function with the parameters in mounted stage of my component.
All of my classes are then ancestors of EditorProvider class, which only has one getter for this Editor class (that it gets in a constructor and stores in a field), from where I can get any of the specified fields. So the call to store in any of my classes looks like:
this.editor.store.commit('anything')
Call to canvas:
this.editor.canvas.renderAll()
Call to eventbus:
this.editor.eventBus.emit('eventName')
My component now just imports the bottlejs and has access to all the classes by their names. The interaction is mainly by the canvas and window events, so I event created an EventHandler class, that moves all these event listeners from the component to separate class. So in the end in the component I only have HTML template and a few lines of imports and the script tag, which is now much more readable and the dependencies are clearly visible.
edited Dec 12 '18 at 10:04
answered Dec 12 '18 at 9:46
Zdeněk BraunZdeněk Braun
93210
93210
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53411659%2fvue-js-and-fabric-js-logic%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown