1

I have this filter function (belongs a List component), then I need to pass the results to another component, (they are sibling) to fill my DataTable (parent component):

async filtroVariaveis () {
                try {
                    this.loading = true;

                    this.variaveis = await this.variaveisService.listVariables();

                    let idGrupos = null;
                    if (!this.grupos[0] && this.maquinaSelecionada[0]) {
                        idGrupos = this.gruposOpcoes.map(m => m.id);
                    }

                    if (!this.grupos[0] && !this.maquinaSelecionada[0] && this.areaSelecionada[0]) {
                        const idMaquinas = this.maquinasOpcoes.map(m => m.id);
                        const grupo = this.gruposOpcoes.filter(a => idMaquinas.includes(a.id_maquina));

                        idGrupos = grupo.map(a => a.id);
                    }

                    if (this.grupos[0]) {
                        idGrupos = this.grupos.map(g => g.id);
                    }

                    const tipos = this.tipoVariavel.map(t => t === "Analógica" ? t = "ANALOGICA" : "DIGITAL");
                    const tag = this.tagInput || this.variaveis.map(t => t.tag);
                    const descricao = this.descricaoInput || this.variaveis.map(d => d.descricao);

                    this.filtroAplicado = ((await this.variaveisService.listVariables(idGrupos, tipos, tag, descricao)) || []);
                } catch (err) {
                    console.log(err);
                }

this.variaveisService is my Axios services that communicates with my API.

My List component:

<template>
<two-cards>
        <template #header>
            <h4 class="card-title">Filtros</h4>
            <slot>
                <router-link
                    to="/variaveis/add"
                    class="btn btn-success text-white align-self-center"
                >
                Adicionar variável
                </router-link>
            </slot>
        </template>
        <template #one>
            <form class="mt-2" @submit.prevent="filtroVariaveis">
                <div class="form-row">
                    <div class="col form-group col-sm-6">
                        <label for="data-final">Tag: </label>
                        <b-form-input
                            v-model="tagInput"
                            id="data-final"
                            input-class="bg-white"
                        ></b-form-input>
                    </div>
                    <div class="col form-group col-sm-6">
                        <label for="data-inicial">Descrição: </label>
                        <b-form-input
                            v-model="descricaoInput"
                            id="data-inicial"
                            input-class="bg-white"
                        ></b-form-input>
                    </div>
                </div>
                <div class="form-row">
                    <div class="form-group col-sm-3">
                        <label class="mt-2">Área </label>
                            <vue-multi-select
                                class="multi-100"
                                v-model="areaSelecionada"
                                @input="checarArea"
                                search
                                historyButton
                                :options="{ multi: false, labelName: 'nome' }"
                                :selectOptions="areasOpcoes"
                                :btnLabel="() => areaSelecionada[0] ? areaSelecionada[0].nome : 'Selecione'"
                            />
                    </div>
                    <div class="form-group col-sm-3">
                        <label class="mt-2">Máquina </label>
                            <vue-multi-select
                                class="multi-100"
                                v-model="maquinaSelecionada"
                                :disabled="!areaSelecionada[0]"
                                @input="checarMaquina"
                                search
                                historyButton
                                :options="{ multi: true, labelName: 'nome' }"
                                :selectOptions="maquinasOpcoes"
                                :btnLabel="() => customLabel(maquinaSelecionada)"
                            />
                    </div>
                    <div class="form-group col-sm-3">
                        <label class="mt-2">Grupo </label>
                            <vue-multi-select
                                class="multi-100"
                                v-model="grupos"
                                search
                                historyButton
                                :options="{ multi: true }"
                                :selectOptions="gruposOpcoes"
                                :btnLabel="() => customLabel(grupos)"
                            />
                    </div>
                    <div class="form-group col-sm-3">
                        <label class="mt-2">Tipo</label>
                            <vue-multi-select
                                class="multi-100"
                                v-model="tipoVariavel"
                                search
                                historyButton
                                :options="{ multi: true }"
                                :selectOptions="tiposOpcoes"
                                :btnLabel="() => customLabel(tipoVariavel)"
                            />
                    </div>
                </div>
                <div class="d-flex justify-content-end tcs-card-footer-action">
                    <button
                        class="btn btn-success tcs-btn"
                        type="search"
                    >
                        <SearchIcon />
                    </button>
                </div>
            </form>
        </template>
        <template #two>
            <GenericList
                title="variáveis"
                :linhas="linhas"
                data-table-state-name="Variável"
                add-route="add_variavel"
                edit-route="edit_variavel"
                :cols="['#', 'Tag', 'Descrição', 'Tipo']"
                :cols-name="['id', 'tag', 'descricao', 'tipo']"
                :cols-map="i => [i.id, i.tag, i.descricao, i.tipo]"
            />
        </template>
    </two-cards>
</template>

computed: {
            linhas () {
                return this.lista.map((row) => ({
                    href: { name: this.editRoute, params: { id: row.id }},
                    cols: this.colsMap(row)
                }));
            }
        },

My GenericList component, where I need to put this datas:

<template>
    <div>
        <DataTable
            scroll
            :async="pagination"
            :loading="loading"
            :colunas="parsedCols"
            :linhas="linhas"
            :errMsg="errMsg"
            :state="dataTableState"
            @state-change="setStateDataTable"
        >
            <template #results-page v-if="pagination">
                <select
                    class="custom-select ml-1"
                    :value="results"
                    @input="changeResults"
                    data-cy="resultados-pagina"
                >
                    <option value="10">10 por página</option>
                    <option value="20">20 por página</option>
                    <option value="50">50 por página</option>
                    <option value="100">100 por página</option>
                    <option v-if="canShowAllResults" value="-1">
                        Mostrar todos
                    </option>
                </select>
            </template>
            <template v-for="col in cols" v-slot:[col]="{ value, item }">
                <slot :name="col" :value="value" :item="item">
                    <router-link
                        v-if="value && value.rota && value.nome && value.id"
                        :to="{ name: value.rota, params: { id: value.id } }"
                        title="Ir para a edição"
                        >
                        <edit-icon size="16" /> {{ value.nome }}</router-link
                    >
                </slot>
            </template>
        </DataTable>
        <Paginator
            :page="page"
            :pages="pages"
            :count="count"
            :disabled="loading"
            :first="first"
            :last="last"
            @paginate="paginate"
        />
    </div>
</template>

props: {
        loading: Boolean,

        title: {
            type: String,
            required: true
        },

        addRoute: {
            type: String,
            required: true
        },

        editRoute: {
            type: String,
            required: true
        },

        dataTableStateName: {
            type: String,
            required: true
        },

        lista: {
            type: Array
        },

        linhas: {
            type: Array
        },

        cols: {
            type: Array,
            required: true
        },

        colsMap: {
            type: Function,
            required: true
        },

        colsName: {
            type: Array,
            required: true
        },

        canShowAllResults: {
            type: Boolean,
            default: false
        },

        showInativos: {
            type: Boolean,
            default: false
        }
    },

data () {
    return {
        errMsg: "",

        pagination: false,
        page: 0,
        pages: 1,
        results: 20,
        first: 0,
        last: 0,
        count: 0
    };
},

computed: {
    dataTableState () {
        return this.$store.state.dataTables[
            "dataTable" + this.dataTableStateName
        ];
    },

    parsedCols () {
        return this.cols.map((c, idx) => this.colsName[idx] ? c : { value: c, sortable: false }
        );
    }
},

I dont know how to fill this DataTable, someone can helps me?

2
  • Depends on the position of the 2 components. are the components sibling ? or parent to child? Commented Oct 20, 2021 at 17:02
  • @ElsaKarami They are sibling.. Commented Oct 20, 2021 at 17:30

1 Answer 1

1

you can use $emit and $on for passing data between sibling components. please look at this example

when you pass data into another component you have to set this line:

this.$root.$emit('eventing', data);

and after that, you can receive data into the destination component like this example:

1)

mounted() {
  this.$root.$on('eventing',this.functionName);
}

OR

2)

mounted() {
    this.$root.$on('eventing', data => {
        console.log(data);
    });
}

please pay attention, you had better set $off into the destination component

1)

 beforeDestroy() {
    this.$root.$off("eventing", this.functionName);
  }

OR

2)

beforeDestroy() {
  this.$root.$off("eventing");
}

you can find data you need into arguments in the this.functionName

Sign up to request clarification or add additional context in comments.

31 Comments

this.$root.$emit('eventing', data); and inside GenericList page , you need to set $on like : mounted() { this.$root.$on('eventing', data => { console.log(data); }); }
This seems to work, thanks Elsa! The console is already showing me what I want, but I still don't know how to fill the table with this results, if you can help me with that I really really appreciate...
thank you. you need to set v-if inside table tag. because the table render before call emit
In my Generic List component: mounted () { this.$root.$on("filtroVariaveis", data => { this.pagination = true; console.log(data); }); }
you can set like this: beforeDestroy() { this.$root.$off("filtroVariaveis"); } after mounted part
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.