Tengo un formulario con dos selectores de fecha y un botón para borrar cada uno de ellos de la siguiente manera:
<template> <form> <div> <datetime id="someDate" v-model="fields.some_date"></datetime> <button @click.prevent="clearSomeDate()">X</button> </div> <div> <datetime id="anotherDate" v-model="fields.another_date"></datetime> <button @click.prevent="clearAnotherDate()">X</button> </div> </form> </template> <script> export default { data() { return { fields: { some_date: null, another_date: null }, }; }, methods: { clearSomeDate() { this.fields.some_date = null; }, clearAnotherDate() { this.fields.another_date = null; }, }, } </script>Y funciona bastante bien, pero no es tan reutilizable.
¿Hay alguna manera de lograr esto con una sola función clearField() y pasar el modelo como parámetro o algo así? ¿Debo hacer mi propio componente personalizado para que funcione?
Puede pasar el nombre de la propiedad del campo como parámetro
clearField(name) { this.fields[name] = null; }y llamarlo con argumento
<button @click.prevent="clearField('some_date')">X</button> Aunque un enfoque más limpio sería construir otro componente reutilizable y vincularlo con v-model
<div> <datetime :value="value" @change="$emit('input', $event)"></datetime> <button @click.prevent="$emit('input', null)">X</button> </div>Podrías deshacerte por completo de los métodos simplemente haciendo la tarea directamente en la plantilla:
<div> <datetime id="someDate" v-model="fields.some_date"></datetime> <button @click.prevent="fields.some_date = null">X</button> </div>De esa manera, tiene la lógica de compensación directamente al lado del modelo.
Si desea que sea reutilizable, también puede extraerlo en un componente separado:
<template> <div> <datetime v-bind="$attrs" :value="value" v-on="eventHandlers"></datetime> <button @click.prevent="$emit('input', null)">X</button> </div> </template> <script> export default { name: "datetime-with-x", model: { prop: "value", event: "input" }, props: ["value"], inheritAttrs: false, computed: { eventHandlers() { return { ...this.$listeners, input: ev => this.$emit('input', ev) }; } } }; </script>y luego utilícelo en su componente de esta manera:
<template> <form> <datetime-with-x id="someDate" v-model="fields.some_date" /> <datetime-with-x id="anotherDate" v-model="fields.another_date" /> </form> </template> <script> import DatetimeWithX from "./datetime-with-x"; export default { name: "your-form", components: { DatetimeWithX }, data() { return { fields: { some_date: null, another_date: null } }; } }; </script>