vuejs-br / forum

Fórum sobre a tecnologia Vue.js, totalmente em português!
MIT License
222 stars 3 forks source link

mudar valor do props de um componente #21

Open crodrigor opened 5 years ago

crodrigor commented 5 years ago

Boa tarde, estou com a seguinte dúvida tenho um componente paginacao( de um curso que fiz)

As duas propriedades :texto e campo eu criei e adicionei no componente pai e consigo enviar as informações atraves da chamada do componente, tipo(:text="nome" e campo="titulo") coloquei um filtro de busca que funciona,porem a paginação nao funciona de acordo com a busca, minha duvida e a seguinte como faço para realizar a busca e alterar o valor de :texto do componente? ja tentei de tudo, Grato

wilcorrea commented 5 years ago

Consegue criar um demo do que está tentando fazer no jsfiddle ou codesandbox?

crodrigor commented 5 years ago

Boa tarde, desculpe não consigo por que ele busca de uma API restful os dados, e por enquanto ta local, acho que daria muito trabalho para isolar, mas vou colocar o codigo do componente que uso

pagination.js

import Vue from 'vue'
export default {
    state: {
        getList: []
    },
    mutations: {
        updateList (state, data) {
            state.getList = data
        }
    },
    actions: {
        clearRegistries(context, config){
            context.commit('updateList', [])
        },
        getRegistries (context, config) {
            if(!config.page){
                config.page=1
            }
            if(!config.limit){
                config.limit=200
            }
            if(config.like) {
              Vue.http.get('api/' + config.resource + '?limite=' + config.limit + '&page=' + config.page+ '&like=' + config.like).then(response => {
                context.commit('updateList', response.data)
              })
            }else{
              Vue.http.get('api/' + config.resource + '?limite=' + config.limit + '&page=' + config.page).then(response => {
              context.commit('updateList', response.data)
              })
            }
        }
    }
}

Pagination.vue

<template lang="html">
<center>
  <nav aria-label="Page navigation example">
  <ul class="pagination">
    <li class="page-item" :class="{disabled: active == 1}" ><a class="page-link" href="" @click.prevent="navigate(1)"><<</a></li>
    <li class="page-item" :class="{active: n == active}" v-for="n in parseInt(total)">
      <a class="page-link" href="" @click.prevent="navigate(n)"> {{ n }}</a>
    </li>
    <li class="page-item" :class="{disabled: active == total}"><a class="page-link" href="" @click.prevent="navigate(total)">>></a></li>
  </ul>
  <p>Exibindo página {{ active }} de {{ total }}, total de {{ totalRegistries }} registros.</p>
  </nav>

</center>

</template>
<script>
    export default{
        name: 'pagination',
        props: [
            'totalPerPage',
            'resource',
            'texto',
            'campo'
        ],
        data: function (){
            return {
                active: 1
            }
        },
        computed: {
            registries () {
                return this.$store.state.pagination.getList
            },
            total(){
                return this.registries.last_page || 0
            },
            totalRegistries(){
                return this.registries.total || 0
            }
        },

        methods: {
            navigate: function(n) {
                let loader = this.$loading.show()
                this.active = n
                let config = {
                    resource: this.resource,
                    limit: this.totalPerPage,
                    like: this.campo+','+this.texto,
                    page: n
                }
                this.$store.dispatch('getRegistries', config)
                setTimeout(()=>{
                  loader.hide()
                },200)
            }
        },
        created (){
          if(!this.campo) {
            this.$store.dispatch('getRegistries', {resource: this.resource, limit: this.totalPerPage})
          }else {
            this.$store.dispatch('getRegistries', {
              resource: this.resource,
              limit: this.totalPerPage,
              like: this.campo+','+this.texto
            })
          }
        }
    }
</script>
<style>

</style>

Tela

<template lang="html">
  <div class="row">

    <div class="col-md-12">
      <h1></h1>
    </div>

    <div class="card col-md-12">
      <div class="pull-right">
        <div class="btn btn-default btn-success btn-md" data-toggle="modal" data-target="#panel-customer" >
          <i class="icon icon-plus"></i>  New</div>
      </div>

      <div class="card-content col-lg-12">
        <br>

        <input v-model="search" class="form-control" placeholder="Busca">

        <table ref="table" class="vuetable table table-hover">
          <thead class="border-0">
          <tr class="border-0">
            <th width="50">Id</th>
            <th>Banners</th>
            <th align="center">Ações</th>
          </tr>
          </thead>
          <tbody>
          <tr v-for="banners in banners" >
            <td>{{banners.id}}</td>
            <td class="valign-wrapper">{{banners.titulo}}</td>
            <td>
              <div class="btn btn-sm btn-info"><i class="fa fa-eye-slash text-white"></i></div>
              <div class="btn btn-sm btn-success" ><i class="fa fa-edit text-white"></i></div>
              <a href="" @click.prevent="deletar(banners.id)" class="btn btn-sm btn-danger"><i class="fa fa-trash-o text-white"></i></a>
            </td>
          </tr>
          </tbody>
        </table>

        <pagination totalPerPage="2" resource="banner" : texto="" campo="titulo" ></pagination>
      </div>

    </div>
  </div>
</template>

<script>

  import Pagination from '../../componentes/SharedComponents/Pagination'
  import Vue from 'vue'
  import Vuex from 'vuex'
  Vue.use(Vuex)

  var self = this
  export default{
    name: 'banner',
    props: ['texto'],
    data: function () {
      return {
        search: '',
        valor:'',
        banneres:[]
      }
    },
    filters: {
      lowercase(val) {
        return val.toLowerCase();
      }
    },
    components:{
      'pagination': Pagination
    },
    beforeMount(){
      this.procurar()
    },
    mounted() {

    },
    computed: {
      dadoTexto: function () {
        if ( this.texto != null ) {
          return this.texto
        }

        return '';
      },
      banners() {
      //this.$store.state.banner.bannerList
        this.banneres = this.$store.state.pagination.getList.data
        let app = this
        //app.texto=app.search

        if(this.search.length > 0){
          return this.banneres.filter(function (item) {

            return item.titulo.toLowerCase().indexOf(app.search.toLowerCase()) > -1

          })

        }
          return this.banneres
        }
      },
      created () {
        this.$store.dispatch('getBanners')
      },
      methods: {

      procurar(texto){
      if(texto=='')
        return ''
      else
        this.$emit('chamou');
      },
      goTo: function(id){
        this.$router.push('/banners/' + id);
      },
      teste: function(id){
        console.log(id)
      },
      deletar: function (id) {
        let _this = this
        this.$msgbox({
          title: 'Responda',
          message: 'Deseja remover o registro?',
          type: 'success',
          confirmButtonText:'Sim',
          cancelButtonText:'Não',
          showCancelButton: true
        }).then(function(action) {
          let loader = Vue.$loading.show()
          _this.$store.dispatch('removeBanner', id)
            .then(() => {
              //_this.$router.push('/formularios/banner')
              //console.log(_this.$store.state.pagination.getList)
              _this.$parent.refresh()
              _this.$router.push('/formularios/banner/')
           })
          setTimeout(()=>{loader.hide()},200)
          //router.push('./pages/login')
        })

      }
    }
  }
</script>

<style scoped>

  html {
    font-family: Lato, 'Helvetica Neue', Arial, Helvetica, sans-serif;
    font-size: 14px;
  }

  .table {
    border: none;
  }

  .table-definition thead th:first-child {
    pointer-events: none;
    background: white;
    border: none;
  }

  .table td {
    vertical-align: middle;
  }

</style>

Inclusive estava tentando entender o $emit, mas não consegui usar os exemplos nesse ambiente que estou usando. Grato

crodrigor commented 5 years ago

Estou quase conseguindo, usei o $emit e $on mesmo e consegui enviar informação para o componente pagination, porem quando recebo a informação pelo $on no componente é como se tivesse em um loop e fica chamando a função $on e a paginação acaba não funcionando, o que pode ser?

crodrigor commented 5 years ago

Resolvi com o $emit e $on mesmo (não sei se é a forma mais correta) criei um watch para o input v-model="search"

no main
export const vm = new Vue()

no formulario de visualizacao
import { vm } from '../../main';
watch: {
  search: function (val) {
    vm.$emit('inputSearch',val)
  }
}   

no computed apenas retorno os dados pois o filter não estava retornando os registros com acentuação, no laravel ele descrimina os acentos

  banners() {
    return this.$store.state.pagination.getList.data
  }

no meu componente de paginacao

import { vm } from '../../main';

        created (){
          var self = this
          vm.$on('inputSearch', function (obj) {
              self.$refs.primeiro.click()
              self.campoTexto = obj
              if(obj==""){
                self.$refs.primeiro.click()
              }
              self.$store.dispatch('getRegistries', {
                  resource: self.resource,
                  limit: self.totalPerPage,
                  like: self.campo+','+self.campoTexto
                })
            })

            this.$store.dispatch('getRegistries', {
              resource: this.resource,
              limit: this.totalPerPage,
              like: this.campo+','+this.campoTexto
            })
        }

aqui funcionou perfeitamente. Grato

FelipePTO commented 5 years ago

Deixa eu ver se entendi, você está pegando dados de uma API e populando numa tabela e quer fazer paginação e busca? Por que não usou o Datatable?

crodrigor commented 5 years ago

Ainda estou engatinhando no vue então prefiro ver como as coisa funcionam mesmo que gere um pouco de dificuldade, mas o importante é que funcionou, depois vou fazer mais testes eu ate usei o Datatable no início mas não consegui ignorar os acentos na busca.