Share code with composition Api in Vue (defineProps, defineEmits and defineExpose) - javascript

I'm migrating a midlevel app from Vue 2 to Vue 3.
For this task, I'm rewrittig all code to make use of Composition Api. I like Composition Api, however, I don't see a good advantage when simplifying code. With Composition Api, somethings looks more complex or verbose than before. I hope be wrong.
This becomes specially noticiable when refactoring mixings. When using mixins, you just have to use them and that's enought to get all desired functionality, while when using composables, you have to be aware of what is inside the composable to extract/use specific functionality from composable...
My main problem arises when I want to reuse defineProps(), defineEmits() and defineExpose().
In some parte of my app, I got all posible inputs defined in different components, for example:
InputText: Just text
InputNumber: Reusing InputText, limiting to only numbers
InputMoney: Reusing InputNumber, adding some money formatting
InputNumberRange: Reusing two InputNumbers
etc
As you can imagine, all that inputs are almost the same. The needed code for those components are very small, just a InputMixin and a couple of overwrites if needed.
However, when using Composition Api, I don't know how to get it so simple because I don't know how to 'share' the code between these components. How could I reuse defineProps(), defineEmits() and defineExpose() between them?
Is it possible to use some kind of inheritance? (like extends: MyComponent)

Related

React - Components to create and update db model, inheritance or composition?

I'm relatively new to React. My use case implies a create page for a database model and an update page. I have a lot of duplicate code in those and coming from regular OOP design I would create a base class for it and let the two component inherit.
However, after reading several forums, I saw that you should mostly prefer composition over inheritance with React. Would that also apply in this use case? It seems odd to model this via composition.
I think composition also applies to your use case. From what I understand you will have almost the same page for update and create, all your model files will be the same in both cases. So you can make a reusable component, some form. And use it in create and update page, just perform the right action for each of them.

Creating Cycle.js reusable modules

Let's imagine, in a OO world, I want to build a Torrent object which listens to the network and lets me interact with it. It would inherit an EventEmitter and would look something like this:
var torrent = new Torrent(opts)
torrent.on('ready', cb) // add torrent to the UI
torrent.on('metadata', cb) // update data in the UI
and I can also make it do things:
torrent.stop()
torrent.resume()
Then of course if I want to do delete the torrent from memory I can call torrent.destroy().
The cool thing about this OO approach is that I can easily package this functionality in its own npm module, test the hell out of, and give users a nice clean reusable API.
My question is, how do I achieve this with Cycle.js apps?
If I create a driver it's unclear how I would go about creating many torrents and having their own independent listeners. Also consider I'd like to package functionality in a way that others get to easily reuse it in other Cycle.js apps.
It seems to me that you are trying to solve a problem thinking about it as you would write "imperative code".
I think creating Torrent instances with their own listeners is not something you should be using in cycle components.
I would go about it differently - creating Torrent module and figuring out what would be its sources and sinks. If this module should be reusable and published, you can create it as a function that would receive streams as arguments. Maybe something similar to TodoMVC Task component (which is then used in its parent component).
Since this module can be created as a pure function, testing it should be at least just as easy.
This implementation of course depends on your requirements but communication with the module would then be done only with streams and since it would be declarative there would be no need for methods like stop() and destroyed() which you would call from elsewhere.
How do I test it?
In cycle.js you'd write a component with intent model and view functions.
You'd test intent(), for given input Streams, produces Streams of actions that you want. For models, you'd test that given http and action streams, you get the state you want, and for view, you test that given a state you get the VDom you want.
One tricky bit with cycle.js is that since it passes functions around, normal JavaScript objects that use the 'this' keyword are not worth the trouble due to 'this' context problems. If you are working with cycle.js and you think you might write a JS class for use with Isolate, Onionify, or Collections most likely, you are going in the wrong direction. See MDN docs about 'this'
how I would go about creating many torrents
The Cycle.js people have several ways to deal with groups of things like this.
This ticket describes some things that might work for that:
Wrap subapp in Web Component
Stanga and similars.
Cycle Collections
Cycle Onionify

Usage of mutable objects inside React Native + Redux app

I'm new to React (and React Native in particular), and I'm trying to come up with the right application design.
I have a separate JavaScript module, unrelated to React; the module contains some objects with methods, some of them mutate objects, some have side effects (like, subscribe/unsubscribe to/from the server events, or add/remove listeners to local object's events), etc.
I'd like to reuse this JavaScript module inside my React Native app, but it seems that it won't play well together. In Redux (and some other state managers as well), state needs to be represented as a plain immutable JS object, and instead of mutating existing objects, we create new objects instead. So I can't use my existing JS objects as a state directly.
I probably could use some wrappers around my existing JS code (mutating, and full of side effects), but it doesn't seem a nice solution: a lot of repetition, and the end result is unlikely to be elegant.
On the other hand, I'm not quite happy reimplementing the whole thing to fit into React's world, to make it idiomatic.
And on the one more other hand, I could just forget about Redux, and use plain state of React's components, but I feel it'll be a mess.
I'd like to get some suggestions from experiensed React + Redux people. What would you recommend?
It's hard to say exactly without seeing what the mystery module does or exposes. But consider converting the module into one or more reducers and then use Redux's combineReducers to target pieces of the overall store that will be contained exclusively in your module.
Then you will need to add reducer methods that always return new objects as required by Redux, but you won't need to modify every function in the existing code.
This article by Dan Abramov helped me understand reducer composition.
See also Handling Actions in the docs for help on how to write good reducer methods that only modify a small piece of the store.

When should I use KnockoutJS Components vs. Templates?

So trying to get my hands dirty with KnockoutJS 3.2. I've read the docs and I've successfully implemented components within my current project. I don't use an AMD, so I'm just using script elements to hold the views.
My question is: If i'm not using the asynchronous loading features, is there any real practical difference to using components rather than templates?
General description of both
As stated in the other answer, a template is only a piece of HTML which can be bound to a viewmodel, or viewmodel section. And a component is composed of a template, and its corresponding viewmodel. Besides, this viewmodel, apart from observables can include some simple business logic, and functionality to communicate with the server.
Coupling and encapsulation
Another important difference is the coupling. A template it's bound to the main viewmodel, and its bound to the main viewmodel's observables, so it's highly coupled to the viewmodel: a change in the viewmodel will break the template, and viceversa. So, if you're reusing a template in several places, and you change it, you have to correct the corresponding viewmodels.
A component is bound to its own viewmodel. It's only coupled to the main viewmodel if there are parameters provided from it. This means that you can easily change the component template as well as the component viewmodel, and, if there are no parameters, or you don't change them, nothing will be broken.
So using components helps in decoupling and modularizing.
Communication between main viewmodel and component
The last section is a double edged sword: if there is a high interaction between the main viewmodel and the template or component, it's much easier to use a template, because all the logic and properties are held in the main viewmodel and the interactions are easily implemented. If you used a component you'd need to provide complex parameters, or even make something to allow the component to expose functionality to the main viewmodel.
Polymorphism
It's not strange to have some parts of an application that require different behaviors and visualization to solve the same kind of task. For example, let's imagine you have to implement a payment system in your application: if you accept for example paypal and credit card payment you have two different visualization and functionalities. If you used templates, you'd need to have the particular implementation of each payment system in the main viewmodel. If you used components, they'd share a common interface (parameters) but each of them would have its own implementation. If tomorrow you had to include a new payment system, it would be easy to implement a new component with the common interface.
NOTE: pay attention to the last paragraph
Binding
In the case of a template the binding it's not done at the template level, but inside it. I.e. each element inside the template must be bound to observables of the main viewmodel. In the case of a component the binding is much simpler: at most, it requires the component name and the parameters, if they exist.
Component registration and custom tags
If you register the component you can use custom tags. This makes the views more easyly readable and understandable: instead of specifying the component name in a binding, you use a tag with the component name, and parameters are passed as attributes.
Dynamic loading
If you use templates you have to dynamically load them by yourself, and, as this is an asynchronous task, you'll have to take care of using the template only when it's already available. That's way in most occasions you'll use inline templates. This is not good if they must be reused in several places.
If you have used some AMD implementation, like require.js, and you understand the benefits of this technology, you'll be happy to know that you can easily use AMD to load component templates and viewmodels. One of the advantages is that you don't have to worry about the template or component being available when you need to use them.
Testability
No matter if you do manual or automated tests, it's much easier to test a bunch of independent components, one by one, that to test a complex viewmodel with or without templates.
My choice
So far, I've exposed facts about templates, and components, and I've tried not to show my personal preferences. However, in this last section, I must say that in most situations I prefer to use components for their advantages:
modularity
low coupling
easy reuse
testability
binding syntax
(optional) dynamic loading
However, templates are also a better fit on some occasions
The last paragraph have to do with big applications. If you're dealing with small applications or simply enhancements of interfaces rendered by another technology (like ASP.NET MVC), you'll probably get none of the advantages of using components. So, you don't need them.
There are other cases when it's not worth using components. For example, if you have to show a list (JavaScript array) of items which have different properties which must be shown in a different way, it's easier to use templates. Note that the choice in this case is because each of the instances doesn't have a complex viewmodel with a lot of functionality, but a simple bunch of properties. In this particular case it's not only not worth, but it can also be counterproductive to use components.
You can understand this last example as polymorphism. But, in this case it's nearly "visual" polymorphism. I.e. each kind of item must be shown in a different way, but there is no need to implement any special logic in each of the components.
However, even in this case, if the templates are complex enough, or must be used in many different places, it's also much better to use a simple component that includes the template as well as a parameter that receives the whole item. So, even in this case, it's not a bad idea to use components.
If you'd read this far, thank you, and I hope you have some criteria to help you choosing the best option.
They aren't completely different. Components are made up of templates (html) and data/logic (view model i.e. JavaScript). When you have a modular view you want to attach a view model to you can utilize components. Here's a link discussing components a bit more: http://www.knockmeout.net/2014/06/knockout-3-2-preview-components.html

On using mixins in a CoffeeScript game engine

I am working on a CoffeeScript game engine for Html5 canvas. I came up with the "cool" idea to utilize mixins after I checked a very neat CoffeeScript implementation. I thought, it may be a very cool idea to reduce the various hierarchy of objects that game objects usually provide, by developing a set of mixin-based components, each of which has a very specific functionality. Then, when developing an actual game, one could build unique game objects on the fly by basically starting from one component and mixing it with a bunch of other components. This reduces the hierarchies and allows for frequent changes.
Then I thought about the possible collisions that might come up, for example having a few components define a method with the same signature. Now, I am not as excited as before.
What should I do? Is this a good way? I still like it, especially because of JS' underlying prototype mechanism, which allows for such an easy way to combine stuff on the fly.
You're talking about an entity component system. There are a couple written in JS; the most popular is Crafty, which is big but worth looking at. I recently wrote one in CoffeeScript (just for funsies; will probably never release it).
A few notes about collisions:
So first, the problem may be worse than you think: collisions will happen if two methods have the same name; JS doesn't differentiate function signatures. It also might not be so bad: why don't you just create a namespacing convention, where each behavior (meaning method) is named after the component it belongs to, like burnable_burn?
To take a step back though, mixins aren't the only way to build this - behaviors (i.e. things a component can do) don't have to be methods at all. The motivating question I ask is, how do you trigger a behavior? For example, you might do:
if entity.hasComponent "burnable" #hasComponent provided by your framework
entity.burn()
But that doesn't sound right to me; it creates a weird coupling between what's happening in your game and what components you have, and it's awkward to check if your entities implement the relevant component. Instead, I'd like behaviors to be listeners on events:
entity.send("applySeriousHeat") #triggers whatever behaviors are there
And then have your component do whatever it needs to do. So when you add a component to an entity, it registers listeners to events. Maybe it looks like (just sketching):
register: (entity) -> #called when you add a component to an entity
entity.listen "applySeriousHeat", -> #thing I do when this event is sent to me
#do burnination here
To bring that point home, if you do that, you don't care about collisions, because your behaviors don't have names. In fact, you want "collisions"; you want the ability to have more than one component respond to the same event. Maybe it burns and melts at the same time?
In practice, I used both setups together. I made entity.addComponent mix in the component's functions, since it's occasionally convenient to just call a behavior as a method. But mostly, the components declare listeners that call those methods, which helped with decoupling and reduced the awkwardness of having to use scoped names, since I don't call them directly in most cases.

Categories

Resources