DOM manipulation with Vuejs and Jquery

Asked

Viewed 1,113 times

2

I am using the pure materialize together with pure Vue to make my own admin template, that is, I managed the project by Vue init and put in index.html the links to the css and js of materialize. The problem is that the events called by the materialize js do not work on the pages without first updating them. An example is the dropdown menu, it only works if I refresh the page (F5), if I access the page through the router-link, these events do not work.

I tried to start the functions in the Komponent Mounted but they still don’t work. How to resolve these conflicts between jquery and the vuejs gift?

  • Related, perhaps duplicate: https://answall.com/questions/305028/

  • William, unfortunately, doesn’t solve my question. I need to make vuejs recognize the javascript events of materialize with each page change without the need to update (F5). I tried to insert the javascript call in the updated() of the Component but no tbm effect.

1 answer

2


For cases where you need to run an external Javascript, especially those that manipulate the DOM, it is recommended to encapsulate it in a component.

Another important point is that the properties and options passed to the component should be reactive, in this case you should study the component to study the best approach.

And finally, as important when starting the external component or assembling the Vue component, is to destroy the external component by destroying the Vue component.

Below is an example of how to make a Component for Editing and Creating a Record within a Modal.

Vue.component('edit-or-create', {
  template: '#edit-or-create',
  props: ['show', 'nome', 'email', 'titulo'],
  data () {
    return {
      inner: {
        nome: '',
        email: ''
      }     
    }
  },
  mounted () {
    this.modal = M.Modal.init(this.$refs.modal);
    this.checkShow();
  },
  beforeDestroy () {
    this.modal.destroy()
  },
  watch: {
    show () {
      this.checkShow();
    }
  },
  methods: {
    checkShow () {
      if (this.show) {
        this.inner.nome = this.nome
        this.inner.email = this.email
        this.modal.open()
      } else {
        this.modal.close()
      }
    },
    cancelar () {
      this.$emit('update:show', false);
    },
    salvar () {
      this.$emit('update:nome', this.inner.nome);
      this.$emit('update:email', this.inner.email);
      this.$emit('update:show', false);
      this.$emit('salvar')
    }
  }
});

new Vue({
  el: '#app',
  data () {
    return {
      create: { show: false, nome: '', email: '' },
      contatos: [{
        edit: false, nome: 'Tobias Mesquita', email: '[email protected]'
      }]
    }
  },
  methods: {
    created () {
      this.contatos.push({ edit: false, nome: this.create.nome, email: this.create.email })
    },
    apagar (contato) {
      var index = this.contatos.indexOf(contato)
      this.contatos.splice(index, 1)
    }
  }
})
body {
  padding: 5px;
}
<link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/css/materialize.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/js/materialize.js"></script>

<div id="app">
  <button class="waves-effect waves-light btn-small" @click="create.show = true">
    <i class="material-icons left">note_add</i>Novo
  </button>
  <edit-or-create 
    titulo="Novo Contato"
    :show.sync="create.show" 
    :nome.sync="create.nome" 
    :email.sync="create.email"
    @salvar="created">
  </edit-or-create>
  <table>
    <thead>
      <tr>
          <th>Name</th>
          <th>Email</th>
          <th>Editar</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(contato, indice) in contatos">
        <td>{{contato.nome}}</td>
        <td>{{contato.email}}</td>
        <td>
          <button class="btn waves-effect waves-light btn-small" @click="contato.edit = true">
            <i class="material-icons left">edit</i>Editar
          </button>
          <button class="btn waves-effect waves-light btn-small" @click="apagar(contato)">
            <i class="material-icons left">delete</i>Delete
          </button>
          <edit-or-create 
            :titulo="'Editar ' + indice"
            :show.sync="contato.edit" 
            :nome.sync="contato.nome" 
            :email.sync="contato.email">
          </edit-or-create>
        </td>
      </tr>
    </tbody>
  </table>
</div>

<script type="text/x-template" id="edit-or-create">
  <div ref="modal" class="modal">
    <div class="modal-content">
      <h4>{{titulo}}</h4>
      <div>
        <div class="row">
          <div class="input-field col s12">
            <input id="first_name" type="text" v-model="inner.nome">
            <label for="first_name">Nome</label>
          </div>
          <div class="input-field col s12">
            <input id="last_name" type="text" v-model="inner.email">
            <label for="last_name">Email</label>
          </div>
        </div>
      </div>
    </div>
    <div class="modal-footer">
      <button class="btn waves-effect waves-light btn-small" @click="cancelar">
        Cancelar
      </button>
      <button class="btn waves-effect waves-light btn-small" @click="salvar">
        Salvar
      </button>
    </div>
  </div>
</script>

However, the most recommended would be to implement a component unique to the modal, and to use a slot for the content of the same.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.