Customização de Tabelas iView com Render Functions: Implementando Switches e Botões Dinâmicos

O componente Table do iView (View UI) oferece uma flexibilidade poderosa através da propriedade render. Essa função permite enjetar componentes personalizados, como seletores de alternância (switches) e botões de ação, diretamente nas células da tabela, permitindo um controlle refinado sobre o comportamento e os eventos da enterface.

Estrutura do Template

No componente Vue, a tabela é declarada de forma simples, vinculando as colunas e os dados a propriedades reativas ou computadas.

<template>
  <Table 
    border 
    :columns="configuracaoColunas" 
    :data="listaRegistros" 
    :loading="carregandoDados">
  </Table>
</template>

Definição de Colunas com Render Functions

Ao definir as colunas, utilizamos a função h (createElement). No exemplo abaixo, o switch de status é configurado como disabled para que a alteração real ocorra apenas após a confirmação do usuário via evento nativeOn.

computed: {
  configuracaoColunas() {
    return [
      {
        title: 'Status de Publicação',
        key: 'statusAtivo',
        width: 140,
        align: 'center',
        render: (h, params) => {
          return h('i-switch', {
            props: {
              size: 'large',
              value: params.row.statusPublicacao === 1,
              disabled: true // Impede a troca automática antes da confirmação
            },
            nativeOn: {
              click: () => {
                this.confirmarTrocaStatus(params.row);
              }
            }
          }, [
            h('span', { slot: 'open' }, 'Ativo'),
            h('span', { slot: 'close' }, 'Inativo')
          ]);
        }
      },
      {
        title: 'Ações',
        key: 'operacoes',
        width: 160,
        fixed: 'right',
        align: 'center',
        render: (h, params) => {
          return h('div', [
            h('Button', {
              props: { type: 'text', size: 'small' },
              on: {
                click: () => this.visualizarDetalhes(params.row)
              }
            }, 'Detalhes'),
            h('Button', {
              props: { type: 'text', size: 'small' },
              on: {
                click: () => this.removerRegistro(params.row)
              }
            }, 'Excluir')
          ]);
        }
      }
    ];
  }
}

Lógica de Manipulação de Dados

Para garantir a integridade dos dados, é comum exibir um modal de confirmação antes de disparar uma requisição de atualização para o servidor.

methods: {
  confirmarTrocaStatus(item) {
    const novoStatus = item.statusPublicacao === 1 ? 0 : 1;
    const mensagem = item.statusPublicacao === 1 
      ? 'Deseja realmente desativar este item?' 
      : 'Deseja ativar este item para publicação?';

    this.$Modal.confirm({
      title: 'Confirmação de Alteração',
      content: `<p style="text-align:center">${mensagem}</p>`,
      onOk: () => {
        this.$axios.put(`/api/status/${item.id}`, { status: novoStatus })
          .then(res => {
            if (res.data.success) {
              this.$Notice.success({ title: 'Sucesso', desc: 'Status atualizado.' });
            } else {
              this.$Notice.error({ title: 'Erro', desc: res.data.message });
            }
            this.atualizarTabela();
          })
          .catch(err => {
            console.error('Erro na requisição:', err);
          });
      },
      onCancel: () => {
        this.atualizarTabela(); // Reseta o estado visual se necessário
      }
    });
  },
  atualizarTabela() {
    this.listaRegistros = [];
    // Lógica para recarregar dados do backend
  }
}

Customização Visual (CSS)

Para ajustar o alinhamento e garantir que o cursor do mouse indique interatividade mesmo em componentes marcados como desabilitados (para fins de controle de fluxo), podemos aplicar os seguintes estilos:

<style scoped>
/deep/ .ivu-table-cell {
  text-align: center;
}

/deep/ .ivu-switch {
  opacity: 1; /* Mantém a visibilidade clara mesmo disabled */
  cursor: pointer;
}

/deep/ .ivu-switch:after {
  cursor: pointer;
}
</style>

Tags: iView Vue.js RenderFunction WebDevelopment javascript

Publicado em 7-23 22:40