Aurelia vs Vue.js

I would be wary of editing config files in some cases since the structure seems to change over a short period of time so basic functionality does not work as some low level dependencies change. For example, HMR does work with some versions of myriad NPM packages but not others. Updating components such as the Aurelia router can have similar results. Sometimes very little change to a configuration file can break a working system. Webpack seems to be a common factor so perhaps it is not doing what we think it should.

1 Like

I was curious on how they differ so i created the todo app in both and wrote up some observations

if there is anything you think i missed let me know, i will see if i can update the observations.

7 Likes

For every person that sees a single file as an advantage there will be someone that sees it as a negative. I donā€™t want my html mixed with code personally.

5 Likes

Both Vue and Aurelia call themselves frameworks so this is pretty weird argument.

Vue has reactive binding too, and it applies to the official state management too. Iā€™m wondering why Aurelia decided to go with immutable state management, since there seems to go most of the reactivity. If you use aurelia store, it seems like every time you update anything in your state, every single component subscribing to state will be re-rendered. At this point, reactive binding is no help and not using virtual DOM is a downside as youā€™ll quickly run into performance problems if you donā€™t work around them. At this point you also have wrote more code to bind to the state than you would in Vue. Iā€™m not that experienced with Aurelia, so maybe thereā€™s some trivial way to work around this, but itā€™s not covered in the documentation.

I do know about pluck and distinctUntilChanged, but thatā€™s a lot manual work which isnā€™t needed at all with Vuex.

2 Likes

Your thought about re-rendering everything was my thought too. Can someone say if this is not the case. Iā€™ve found using the store is more trouble than it is worth in my application. I still have it in place, but Iā€™m kind of using it as a local repository and I feed a data adapter with it now.

1 Like

We were accidentally doing deep clone of the whole state every change, so I can confirm that we were doing something wrong :stuck_out_tongue:

2 Likes

The principle that Aurelia and probably any other lib/framework follow when employing reactive binding: only re-render when new value is not the same with existing value.

For Aurelia store, consider following examples:

<span>${store.state.userName}</span>
<span>${store.state.address.main}</span>
<span>${userName}</span>
@selector({`
  userName: store => store.state.userName
})
export class MyEl {}

With initial store state:

{
  userName: '',
  address: {
    main: ''
  }
}

Scenario 1: Store state is then changed, with something like this:

store.state = {
  userName: 'new-user-name',
  address: oldState.address
}

In this case, state object of the store has been changed, so binding will re-check their values. After evaluation:

  • <span>${store.state.userName}</span> needs to rerender because value '' at state.userName has been changed to 'new-user-name'
  • <span>${userName}</span> of (2) needs to rerender for the same reason.
  • <span>${store.state.address.main}</span> does not rerender because value '' at state.address.main has not been changed

Scenario 2: Store state is then changed, with something like this:

store.state = {
  userName: 'new-user-name',
  address: { ...address }
}
  • <span>${store.state.userName}</span> needs to rerender because value '' at state.userName has been changed to 'new-user-name'
  • <span>${userName}</span> of (2) needs to rerender for the same reason.
  • <span>${store.state.address.main}</span> does not rerender because value '' at state.address.main has not been changed

Bindings re-check values when view model value/property changes at some path. But they do not re-render unnecessarily.

So if you see it rerenders, then itā€™s definitely a bug. But I do not see those in my app, so if you are experiencing perf issue, maybe put together some repro and we can try to work it out what went wrong.

2 Likes

What kind of troubles is it causing for you?

Ultimately I donā€™t believe it belongs in every application. My application cannot rely on one state, i need to have multiple states for different components (pages). Maybe documentation still isnā€™t clear enough to me, but it was adding complexity to places it isnā€™t needed. My overall state model can be changing by external events (signalr), which affects one portion of the state and the user may do an update on something which also affects the state. I want to be history aware and because my state can constantly change, iā€™m not sure how to do that. External changes cannot be undone for instance.

There was a good article about when to use state management and not to, but i cantā€™ locate it. That article basically talked me out of fighting this battle with the store plugin. Iā€™m not in anyway saying the store plugin is bad, I just feel better having my own rolled ā€œstoreā€

Not directly related to the topic, but a question on your example:
The address spread operator here is just cloning the address properties (in this case ā€˜mainā€™) which is just a shortcut to what was used in the first example right? I am assuming its creating a new array, and was just showing that values are checked, not just references?

1 Like

I think you are on the right track. A single state store is just a design pattern collection which works great for a lot use cases but certainly not everyone. All your concerns mentioned are certainly doable with the plugin by properly structuring the state, using middlewares or Event subscriptions to handle external inputs like SignalR, or even create multiple Store instances and sync them via middlewares (remember its just a class). But then again a few classic services used together with event aggregation and a custom roled undo behavior can certainly be enough.

Personally I feel the right moment for single Store state management is when you get the feeling that to many event sources start to manipulate data and you keep adding all services to every component and debugging the flow or tracking down the root cause becomes very hard.

As an example, Iā€™m building a whole IDE where pretty much every Panel, setting or command can affect every part of the app. So this falls into above description and for me feels like a perfect candidate.

So to conclude, dont feel bad because not every tool fits your needs. Perhaps a simple screw driver is all you need and not a fully loaded workbench :wink:

3 Likes

It spreads the object, in that example, itā€™s quite similar to:

address = Object.assign({}, oldState.address)

In first example, it uses the old adress object object while it creates a new object in the 2nd one. Spread can be used with either object or array.

Ok, I think we are saying the same thing, just using different terminology. I looked it up on the Mozilla site before asking, just wanted to be sure I was understanding how it was being used clearly, and using spread does create a new reference object just as the Object.assign example does.

1 Like

If you have a property on your oldState that is an array of objects, The array objects are still references to the original at this point arenā€™t they? I donā€™t use object assign for extremely complex objects in any of my current code and Iā€™m not in a spot i can do my own quick research test.

1 Like

Yes, it should still be the original array. Unless you create new array based on elements of old array via spread, slice etc.

1 Like

Thanks, I think that is an important gotcha to know about. Often I just convert my object to a string and back to an object, Iā€™m not sure how bad performance is, but when Iā€™m doing it I generally donā€™t care. At least at this point i know my object is a real copy with no references to the original

1 Like

Perf wise not the best but definitely a reliable way to deepclone plus it strips off all methods.

1 Like

Is that second scenario description correct? It looks like the first scenarios description was just copy/pasted to the second scenario?

1 Like

The first scenario is about replacing a property of an object, the 2nd is about replacing the entire state object. Does this help? If not, please suggest changes Iā€™ll try to make it clearer