Two components binding Vuejs - javascript

How would be perfect to organize data and interaction between two vuejs components? For example:
1) i have one component
item(v-for="item in items)
a {{item.name}}
2) and the second
card(v-for="item in items")
div.content
img {{item.photo}}
div {{item.desc}}
button Details
The main idea is when i click on list item i want to toggle the card with the same id, as list has. I use one file conponent management from vue webpack template.

A lot of folk seem to be trying to use Vue without a store. Could you be one of them? Perhaps because the store is not strictly part of Vue? Perhaps because the docs spend more time on parent-child communication, events etc (complicated) than on state management (simple)? Perhaps because OO has rotted our brains?
Vue wants to talk to a store. The whole point of bidirectional binding is to separate state from markup. The whole reason why this is such a genius idea is that many (most?) items of state have more than one representation on screen, like your items array. Your store, which can be as simple as a js object in window scope, should contain all your page state at a given moment. You should be able to copy-paste the store between pages, and be looking at the same thing on screen. The important qualities of a store are...
that there's only one of them.
that you 'normalize' your store so that an item of state is only stored once, and there are minimal dependencies between items of state.
Your items array should be in the store, and both components refer to this 'single source of truth'. If you're using other people's components, then you'll need to feed them some properties, but properties are for creating tunnels through Vue components to link leaf components with your store. Your items are your state, and state shouldn't generally live in Vue stuff. Does that help?

Related

Prevent Vue.js re-rendering child components

I've got a complex component which does all its rendering in a render function. There are multiple parts to this, and different bits of the view get rendered - one of these things is a filter bar, showing the filters that have been applied.
What I'm noticing happening, is if I apply a filter which in turn presents this bar, it causes everything else to be fully re-rendered. This is causing a number of other issues and I need to try and stop it from happening.
I've never come across this issue when using normal templates as Vue seems to handle these very intelligently, but I have no idea how to tackle this. The only thing I can think of is setting a key on each thing I don't want re-rendered but not sure if this will a) solve the problem, and b) be possible for the content that is passed in through a slot
Has anyone else faced this issue, and if so how can it be solved?
I had a similar issue when using vuetify text inputs in a complex component which was causing the app to slow down drastically.
In my search I found this link which was specific to vuetify:
high performance impact when using a lot of v-text-field
then found out that this is actually a vue thing from this GitHub issue:
Component with slot re-renders even if the slot or component data has not changed
and there is plan to improve this in it is tracked here (vue 3 should resolve this issue):
Update slot content without re-rendering rest of component
so after reading through all these I found some workarounds that helped me a lot to boost the performance of my app, I hope these will help you as well:
divide that complex component into smaller ones specially when there is some bit of code that changes data that bounds to template causing re-rendering (put them in their own component)
I moved all data layer control to the vuex store, instead of using v-model every where and passing data as events and props, all the data is updating in the store through an action and read from the store through a getter. (from data I mean somethings that is being looped in the template in a v-for, API results, and so on... all of them is being set, updated and read through the store. my components still have the data object but only for the things related to the style and template control like a boolean to control a modal or an imported icon which is used in the template and alikes)
lastly I wrote a function called lazyCaller which its job is to update the values in the store with a delay (when immediate data update isn't necessary) to avoid rapid updates comping from something like a text input (with out this every key stroke trigger the value update action)

Should I use raw js or jquery to target DOM elements in a Vuejs 3 app?

 I'm creating an app using Nodejs and Vuejs 3. In this app I have made a sidebar that gets all links from a routes file and present them. This sidebar consists in a component that parents a list of other recursive link components.
 Since the links are recursive and many, I find it hard to deal with class toggling (active, showing, collapsed, etc.) on each of them and relate them to one another (if one is active the others shouldn't be) using only Vue. Should I use querySelector or any frameworks such as JQuery to handle them or should I try to stick with a pure Vuejs approach?
Edit:
 I don't want to gather the community's opinion on it. My aim is to understand pragmatically why I should or shouldn't manipulate the DOM "outside" of Vue.
If you're using Vue then let it be in control of the DOM; mucking around directly will only create conflicts and woe.
(The same applies to other SPA frameworks such as React and Angular.)
The main reason not to touch the DOM is that Vue works by modifying the DOM on its own, and expects to have complete control over it: when rendering components the framework is removing old DOM elements, adding new ones, updating event bindings, etc; and a lot of it is optimized to only update the DOM nodes that need to be updated.
If you go in there and start making direct changes that Vue doesn't know about, then it's likely that your own changes will get overwritten by Vue the next time it needs to render, or that your changes will overwrite bindings that Vue is depending on.
If you're very knowledgeable about Vue's lifecycle and know how to control when it does and does not render, it is possible to work with both together -- but even then it's still not a great idea. Vue and jQuery do very similar things, but in utterly different ways. In jQuery you build up the page and then use DOM traversals and event handlers to modify it; everything lives inside the DOM. In Vue you build up a bunch of components that manage their own state and rendering; the DOM is basically a side effect of the application state.
By trying to use both together you lose most of the advantages of each of them in isolation, and introduce a lot of complexity in having to manage two competing theories of state and render management (not to mention dealing with communicating data between them). Every time I've contemplated embedding a jQuery widget inside a Vue app, it's turned out to be much easier to just rewrite the widget in Vue directly.
This does mean changing a lot of habits about working with the DOM that you may have built up from past jQuery work. It sounds like you're trying to draw the whole DOM and then build your control structure into it afterwards, which is a natural way to think if you're used to jQuery; in Vue you'll want to build all of that logic into components so the framework can do the work for you. I'd suggest making one Vue component for a link that manages its own state for open / closed / active etc, that recurses to its children only when "open". Then just call that once with the top of your nav data instead of trying to manage the whole tree directly after the fact as you would in jQuery.

React Having Two classes with Two sets of state

I am new to React. I have a small app I'm designing with a schedule and with list of products. Please see my component diagram, below.
I propose that The Schedule Controller and Product Control each will be a class with state.
I brought all the Product modules (a listing component and its children, A new product form, a product detail module, and an edit product module) to be direct children of the Product Controller to prevent excess prop drilling, so they can all pull from the product control class state.
So, as I'm thinking about this, I'm mindful of a single source of truth and to concentrate a single state. However, I've always done that because the whole app has one class.
It seems to me that, to obey those laws (and without using a store as in Redux, which I'm not ready to work my way up to yet. This is a learning exercise and I want to get some proficiency with regular React before adding a whole new library to my learning) I should pick the highest parent component and make only one class with one state.
It seems to me that when I use setState(), its going to the use the state of the class it inherits from. Right? And that state isn't going to get confused about which state to use, because its going to the parent class (I'm totally out on a limb here). The product modules will be extended from the Product class and setState() will only go up the chain to the parent and the parent state.
Or is the correct approach to squash the schedule modules as children of the product controller?
I did a lot of looking around and the references I keep finding are much more complex than what I'm attempting here (involving two different classes with state that DO share information, that's not happening here). I may not be searching the correct terms. So I'm sorry if this is something well known.
So the question I have is, is this a bad idea or bad practice?
A setState call in a class Component only sets the state of itself.
There are two forms of class state
State-> This will be the local state of the class. It will be changed and maintained by the class which declares it.
Props-> These are states/properties which are passed from the parent to the child class. This value cannot the changed. Only the parent class which owns these props has the power to change it. The only way to change this would be through lifting the state. You are right here.
Refer https://reactjs.org/docs/lifting-state-up.html
marzelin had the answer in the comments above. Thanks!

How can I make my children components inherits a parent class method/state?

I am building a React application and I feel like I have a beginner question, but I can't seem to figure out an answer to it.
Basically, I am building a comparator for credit cards/savings accounts/etc. The pages are the same: I have an header, some filters, a sorting selection and finally "rows" to compare the result. I built this once but I need it 3 times. In this component, there are methods that I will reuse such as the call to get the financial institutions and I can reuse the call to get the differents options. However, I don't want to duplicate my code.
This brought me two options: I can either get these functions, put them in another file and import them or I can make other components inherit from one parent component.
The first option is great, but my methods change the state. If it is external to the component, it won't change the state. (and I don't want to do like var = x() for each call).
The second option would be perfect in other circumstances, but I heard that inheriting in React is bad. However, I feel like this is the only way I can reuse the methods to change the state.
Can you help me figure this out?
(I can give code since I am building this for a company and I can't reveal the code to everyone)

What is the use of track-by or key in v-for in Vue js?

I am new to the world of javascript and javascript-frameworks. What is the practical use of track-by or key in v-for in Vue JS?
I read the documentation, but did not really understand its use.
Generally I would recommend you use a key every single time that you are using v-for. The main reason for this is because Vue, for performance reasons, tries to be smart and and re-use existing components when it re-renders. This can cause you to run into problems, especially with components, because components have an internal state. If the component is not paying attention to changes in it's properties then it will render with it's previous internal state and it will appear as if the displayed information was not updated properly.
Here is a prime example from a question I answered a few weeks ago. The fiddle shows iteration over a component without using a key.
<li v-for="item in items">
<test-component :prop1="item"></test-component>
</li>
Notice when you click the change data button that the property values (the first list) change, but the internal state of the component (the second list) does not change. This would typically mean you would not see an update or would see something that did not appear to update in the Vue.
By adding a key to the components, however, you are telling Vue that each component has a specific ID that and Vue will only re-use that component if it has the same ID. This prevents a lot of odd behavior that typically shows up. Here is that same fiddle updated.
<li v-for="item in items" :key="item">
<test-component :prop1="item"></test-component>
</li>
Now when you click the change data button you will notice that the internal state always matches the property.
This is literally one of the most common fixes to issues that pop up here on StackOverflow. Keys are not just useful for list rendering. Generally if you see something funny going on in Vue where a something does not appear to be updating the way you expect, using a key will fix the issue.
Here are a few relevant bits of information about key from the documentation.
Using key with lists.
Key is mandatory when iterating components.
API documentation for key.

Categories