What is the best way to share the same NavHostController between composables - kotlin

I have multiple composable separated in diffrents files. What i need is how i can share de NavHostController between each composables without passing it as argument.

Related

Vue - Is it better to keep all props in one large mixin

I have a component library where i would like to standardize the props, component etc.
Thoughts on combining them props/methods/other mixins/etx into one larger mixin
All property names would be the same
Remove duplicated code on refactoring to adjust components from local props/methods/computed/ to "global"
Not all components would have need for every piece of data contained within the mixin - point 4
Would tree shaking remove the unused code on Rollup?
Is this a good idea?
If your component library is not constrained to using Vue 2 you might want to take a look at Vue Composition API to share functionality (methods + reactive state) between different components.
Mixins might not be what you really want to be using because you kind of lose information as to what features/props/methods really will be put inside your component without re-checking the mixin code. You also might run into issues when component options get merged by Vue at runtime. Check out these posts for more information:
https://css-tricks.com/how-the-vue-composition-api-replaces-vue-mixins/
https://reactjs.org/blog/2016/07/13/mixins-considered-harmful.html
As for sharing props: What I've seen just yesterday (but not yet tried!) in a talk by John Leider - creator of Vuetify - is create a function that returns the props you want to reuse between components. Then you just call said function inside your props definition and use the spread operator.

Pass entire data item vs just id as Prop in Vue list when using VueX

I have a VueX state that contains a list of items. E.g.:
{
operations: Operation[]
}
We need to display each Operation as an item in a list. So we have an OperationList component and an OperationItem component.
When it comes to rendering the list (v-for), would it be recommended to pass the entire item as a prop or just the id and have the OperationItem read the data from VueX?
Basically:
<operation-item v-for="operationId in operationIds" :id="operationId" :key="operationId"/>
vs
<operation-item v-for="operation in operations" :operation="operation" :key="operation.id"/>
I think it might be a preference choice but in my projects I usually pass all the prop of the components that way :
<operation-item
v-for="operation in operations"
:key="operation.id"
:prop1="operation.prop1"
:prop2="operation.prop2"
:prop3="operation.prop3"
/>
I'm not sure if that's a good practice or not but in this case, it's more flexible, you don't need to give a structured object for it to render, you just have to give it all it's properties.
A bit like for a class constructor, I would pass all the necessary parameters separately instead of passing them in an $option array or Settings class.
For some components, it also doesn't make sense for them to be aware of the store, they should juste be "stupid" rendered components.
I hope it's clear enough that you get my point !
I'd say pass the entire item. That way your component doesn't need to know where the data came from and you would be able to reuse the component in situations where the data didn't come from Vuex.

Best practice to dynamically choose view model based on dynamic variable using the same Aurelia route?

I know that Aurelia route modules can be specified dynamically using navigationStrategy but that does not work for my purposes because the toggle value resides in the RouterConfiguration that only runs once. I need a way to route to different views where the toggle value can change multiple times during one session. Additionally, not all routes have multiple views.
What is the best practice for routing to different views on the same route based on a dynamic value?
I've come up with a few different strategies but I'm not sure which one is the most acceptable way to do this.
Using viewPorts where the route will have a static moduleId to a view that injects the name into an instance of <router-view name="view1_index"></router-view> using a global string, e.g. 'view1' may be passed down as 'view2', etc.
Using 2 or more instances of <compose> where the route will again have a static moduleId to a view that will use a global variable to toggle an if.bind in the <compose> instances
Using canActivate in the route module and redirecting to the secondary viewport if conditions are met
Using a pipeline step in the router config to evaluate whether it should direct to a different module (if this is possible)
Which of these strategies, if any, is most accepted? If all of these are odd ways of routing to different views per route, what should be done?
What is the best practice for routing to different views on the same
route based on a dynamic value?
Compose is your best bet. It is common to pass a parameter to the route, capture the parameter in the activate(params) callback, set a variable on your view model using the params, and then use that variable to set the view-model attribute of <compose>.
Using a pipeline step in the router config to evaluate whether it
should direct to a different module (if this is possible)
This is very possible. A common use case is authentication, where you use the AuthorizeStep to check whether a user is authorized and redirect him away if he is not. See http://foreverframe.net/exploring-aurelia-pipelines/. This can be activated in the PreactivateStep as well.
Using viewPorts where the route will have a static moduleId to a view
that injects the name into an instance of using a global string, e.g. 'view1'
may be passed down as 'view2', etc.
I recommend against using viewports for anything other than associating routes to views on a certain section of the screen.
Edit:
A third option you might be interested in is returning a Redirect from your canActivate() function.
import { Redirect } from 'aurelia-router';
canActivate(params) {
let thing = this.thing = await this.service.getById(params.id);
if (!thing) {
return new Redirect('somewhere');
}
return true;
}

Editing information across separate Vue components

I've been learning Vue, and one thing that I'm struggling to understand is how can I edit information across two separate components.
I have a background in PHP, so setting a global variable would be one way to accomplish this in that. But with Vue, I'm not entirely sure.
For example:
Say that Component1 creates a text box that shows a value of "dog" somewhere on the page. And from Component1 you can update and change that value through input fields.
Later, say that Component5 also has an input field that needs to change that text box's value to "cat."
If these two components are separate, and Component1 is controlling that original value, then how can Component5 access that value, update it or manipulate it?
Essentially, what's the best way to handle a piece of information that needs to be accessed/changed from multiple different components or pieces of the Vue application?
Probably the best way will be to use Vuex. It provides a store, where you can add all data which you need in multiple components.
https://vuex.vuejs.org/en/intro.html

Vuejs have multiple components sharing variables and functions

Right this is more about practice, I haven't really got a working scenario but I can provide an example. Imagine Facebook messenger, you have a chat widget in the header where you can quickly view and respond to messages. You can also click view all to take you off to the messages page.
So to me I can see myself having two Vue components, they're more sibling than parent and child as one would be used on all pages and the other simply on the messages page.
<chat></chat> and <chat-widget></chat-widget>
Now from what I can see, across the widget and the chat window itself is functions that would operate in the same way, maybe they'll have slightly different templates because of where they are loaded but somethings straight of the bat would be:
messages() {}
compose() {}
validate() {}
These are just some examples as I use Laravel as my backend I would be using axios to send requests between my Vue frontend and my backend (database).
Ideally, I wouldn't want these components to duplicate it's functions, so should I simply duplicate them or is there a way where i can store some sort of parent functions?
One problem is because of async ajax requests I can't simply call a function that returns say the messages for me to bind, at least, I don't think I can.
Just looking for some guidance on how I can best do this with Vue so that I'm not duplicating identical functionality within my components.
You can use composition to create a "base/abstract" component from which other components can extend:
https://v2.vuejs.org/v2/api/#extends
var CompA = { ... }
// extend CompA without having to call `Vue.extend` on either
var CompB = {
extends: CompA,
...
}
You can inherit the functionality from the "base/abstract" class or override parts of the functionality of the parent.
Another thing you could do is to create mixins:
https://v2.vuejs.org/v2/guide/mixins.html#ad
This is helpful if your components need to share functionality but are not largely the same. If you were to use extend in those cases you would likely override the majority of base functionality to these are a better in that case.
Of course nothing would stop you from simply extracting commonly used methods into a separate file and importing them in your components directly.