Search code examples
typescriptvuejs3vue-composition-api

Add push array with vuejs composition api with typescript - I want to be able to add multiple invoices in your form


I have a form and I have a field invoice field, in this field I can have 1 or more invoices, if it is more than one invoice, it will generate an array of values, follow an image below trying to pass the values, and it returns an object inside of an array.

I'm using vuejs with composition api and typescript., can you help me, please?.

Image

SCRIPT VUEJS

<template>
    <div class="panel-body">
        <button type="button" class="btn btn-danger btn-sm" @click="addRow">+</button>
        <button type="button" class="btn btn-danger btn-sm" @click="removeRow">-</button>
        <div v-for="item in formNotaFiscal" :key="item">
            <div class="mb-3">
                <label class="form-label" for="key_number">Chave </label>
                <input class="form-control" type="text" id="key_number" maxlength="44" placeholder="Chave"
                    v-model="formNotaFiscal" required />
                <br>
            </div>
        </div>
    </div>
</template>

<script lang="ts">
import { defineComponent, onMounted, reactive, watch, ref } from 'vue'
import useDocument from '@/composables/documents';
import Multiselect from '@vueform/multiselect/src/Multiselect';
import ModalPersonCreate from '@/components/Modal/ModalPersonCreate.vue';

export default defineComponent({
    name: 'MovimentCreate',
    components: {
        Multiselect,
        ModalPersonCreate
    },
    setup(){

        const { documents, getDocuments, fetchDocuments, storeDocument}                      = useDocument();
        const { storeCartMoviment}                                                           = useCartMoviments();
        const { errors, currentDate, storeMoviment}                                          = useMoviment();
      
        const formNotaFiscal  = reactive({
            key_number: []
        });
        
        const addRow = () => {
            formNotaFiscal.key_number.push()
        }

         const removeRow = (index) => {
             if(formNotaFiscal.length > 1)
                 formNotaFiscal.splice(index,1)
         }

        watch(() => formDocumentType.document_type_id, (valueAtual) => {
            formMoviment.document_type_id = valueAtual
        })

        const salvarMoviment = async () => {
            await storeMoviment({...formMoviment});
            await storeCartMoviment({...formCartMoviment});
            await storeDocument({...formNotaFiscal, key_number: [] });
        }
        
        onMounted(() => {
            getDocuments();
        })

        return{
            formMoviment,
            formCartMoviment,
            formDocumentType,
            formNotaFiscal,
            addRow,
            id,
            // key_number,
            // listItems,
            // removeRow,
            vehicles,
            companies,
            persons,
            documents,
            departments,
            documentTypes,
            salvarMoviment,
            currentDate,
            fetchVehicles,
            fetchCompany,
            fetchPerson,
            fetchDocuments,
            errors
        }
    }
});
</script>


Solution

  • This is how you can make form with array.

    <template>
        <div class="panel-body">
            <button type="button" class="btn btn-danger btn-sm" @click="addRow">+</button>
            <button type="button" class="btn btn-danger btn-sm" @click="showArray">Show Array</button>
            <div v-for="(item, index) in formNotaFiscal.key_number" :key="index">
                <div class="mb-3 flex gap-2">
                    <label class="form-label" for="key_number">Chave </label>
                    <input class="form-control" type="text" id="key_number" maxlength="44" placeholder="Chave"
                        v-model="item.title" required />
                    <br>
                    <button type="button" class="btn btn-danger btn-sm" @click="removeRow(index)">-</button>
                </div>
            </div>
        </div>
    </template>
    
    <script setup lang="ts">
    
    const formNotaFiscal = reactive({ key_number: [] });
    
    const addRow = () => {
        formNotaFiscal.key_number.push({ title: 'New title'})
    }
    
    const showArray = () => {
        console.log(formNotaFiscal.key_number)
    }
    
    const removeRow = (index) => {
        formNotaFiscal.key_number.splice(index,1)
    }
    </script>
    

    With setup out of <script>.

    setup(){
       const formNotaFiscal = reactive({ key_number: [] });
    
       const addRow = () => {
          formNotaFiscal.key_number.push({ title: 'New title'})
       }
    
       const showArray = () => {
          console.log(formNotaFiscal.key_number)
       }
    
       const removeRow = (index) => {
          formNotaFiscal.key_number.splice(index,1)
       }
       return {formNotaFiscal, removeRow, showArray, addRow}
    }
    
    

    Edit

    const formNotaFiscal = reactive<{key_number: any[]}>({ key_number: [] });
    

    You can assign type as above or configure tsconfig.json file.