Reputation: 4173
I have a small app that lets you add, remove and edit recipes to a list of recipes.
Adding has the route /add
and editing has the route /edit
. I am using a component called AddRecipe
for both routes.
The component simply behaves slightly differently if the route contains 'edit'
- i.e. the input fields are pre-populated with the values you are editing.
Here is AddRecipeForm.vue
, the shared component:
<template>
<div>
<form class="form">
<input v-model="recipe.name" placeholder="Recipe Name">
<textarea v-model="recipe.description" placeholder="Recipe Description..." rows="10"></textarea>
<button :disabled="nothingEntered()" @click.prevent="addRecipe">Submit</button>
</form>
</div>
</template>
<script>
export default {
name: 'AddRecipeForm',
data() {
return {
recipe: this.isEdit()
? this.$store.state.recipes[this.$route.params.id]
: {
name: '',
description: ''
}
}
},
methods: {
isEdit() {
return this.$route.path.includes('edit')
},
addRecipe() {
if (this.isEdit()) {
this.$store.dispatch('addRecipe', this.recipe)
} else {
this.$store.dispatch('addRecipe', {
id: Date.now(),
...this.recipe
})
}
this.$router.push('/')
},
nothingEntered() {
return !this.recipe.name || !this.recipe.description
}
},
}
</script>
I am thinking there are better solutions to this issue. For example what if there are more views that are required later in the project that also require the component? I can't keep checking the route in the component if I want a nice clean readable reusable component.
What is your preferred way of dealing with routes that require the same view?
Upvotes: 2
Views: 74
Reputation: 3522
One common technique when getting too many if
s is to use a configuration map (I made this phrase up), e.g.
data() {
return {
configMap: {
add: {
addRecipe: function () {},
inputDisabled: false
},
edit: {
addRecipe: function () {},
inputDisabled: false
},
view: {
addRecipe: function () {},
inputDisabled: true
}
}
}
}
here we map the condition, which is a segment of the route path, to options we can use directly in this component, so we can then write in template :disabled=configMap[routeType].inputDisabled
.
And in vue, we can place inputDisabled
in computed
, addRecipe
in methods
to declare them more clearly, just like you did above.
And if the type of add
, edit
go beyond routes, we can define the type as a prop
and pass it in (as a config option, just like we would any other reusable component)
Upvotes: 1
Reputation: 73649
If you look at it from single responsibility, which state if you have 2 reasons to change for a class(component in your case), you have to split the functionality in two classes. than it may seem like a overloaded component.
However, given current simpliciity of logic involved, It seems a nice solution till you can wrap the logic inside a function like isEdit
but if there are more different type of checks coming into picture, you can create two or multiple separate components like AddRecipeForm
/EditRecipeForm
etc each doing single thing.
Upvotes: 0