Vue Props vs Data, or Both!
One of the stumbling blocks I ran into while learning Vue was in deciding whether to store information as a prop or a data member when building a component. I had read that you should use a prop if you need to pass information from a parent component to a child component. And that you should use a data member for information that the component uses internally. But I quickly discovered that I had information that fit both use cases.
For example, assume that you have a component that allows you to edit a product, and that the product to edit is passed into the component from the parent. Your component might start out looking like this:
You want this component to allow a product to be edited, so you would include a form in the template that allows users to edit details of the product (such as the price, or the quantity in stock). One of the rules of Vue is that you should not mutate props. If you allow a component to edit a prop, you can run into some strange side-effects that can drive you crazy. If you want to edit information in a component, you should declare it as a data member like so:
So now you have a problem: you have information (in this case a product) that should behave as both a prop and a data member. Vue would not allow you to create a prop and a data member that have the same name.
I found that this scenario came up over and over as I was learning about Vue. Many of the solutions I found called for using Vuex to store all your information. But I was not ready to dive into Vuex because I was still just trying to wrap my brain around the fundamentals of Vue.
After digging for a bit, I found this example in the Vue documentation. It mentions that you should not ‘attempt to mutate a prop inside a child component’, and suggests that you create a prop for receiving the information from the parent, and a data member for editing it. Since they both can’t have the same name, the article suggests that you prefix the prop with ‘initial’. So the component might end up looking like this (make sure you read the final part of the article, because it discusses a very important detail on display in the code sample):
Notice how the product data member is being initialized. It’s making a copy of the initialProduct prop. Remember that the purpose of this component is to allow users to edit a product. And that in Vue you should never mutate (edit) a prop. So what we’ve done is copied the initial product and we are free to edit the copy, and leave the original untouched.
Now, this approach could have implications down the road depending on how you design your application. When a product is edited in this component, you may want to emit an event so that the parent can be aware of the changes. You would want to pass the data member along with the event, which is a copy of the original product. So the parent component might require some logic that replaces the original with the copy that was emitted from the child.
This was the scenario that tripped me up the most while learning Vue, and it’s difficult to find a solution that doesn’t call for using Vuex. So I hope this saves you some trouble. And I’d appreciate any insights from developers who have much more experience with Vue than I do.