[Vuejs]-Why is my watch method didn't work in Vue

1👍

You will need to use EventBus.$on within the created lifecycle method, to “register” receiving the events.

You can also skip the EventBus and just use ‘built in’ event handlers..

Using Event Bus:

const EventBus = new Vue();

const LogRegModal = {
  template: `
    <div><input v-model="username" placeholder="Username" />
         <input v-model="password" placeholder="Password" /></div>
  `,
  data: () => ({ username: "", password: "" }),
  watch: {
    username: function() { EventBus.$emit("changed_username", this.username) },
    password: function() { EventBus.$emit("changed_password", this.password) },
  }
};

new Vue({
  el: "#app",
  components: { LogRegModal },
  data: () => ({ username: "", password: "" }),
  created() {
    EventBus.$on("changed_username", val => this.username = val);
    EventBus.$on("changed_password", val => this.password = val);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>

<div id="app">
  <Log-Reg-Modal></Log-Reg-Modal>
  <p v-if="username || password"><i>These values were received from the EventBus:</i></p>
  <ul v-if="username || password">
    <li v-if="username"><b>Username:</b> {{username}}</li>
    <li v-if="password"><b>Password:</b> {{password}}</li>
  </ul>
</div>

Using ‘built-in’ this.$emit(..., ...):

const LogRegModal = {
  template: `
    <div><input v-model="username" placeholder="Username" />
         <input v-model="password" placeholder="Password" /></div>
  `,
  data: () => ({ username: "", password: "" }),
  watch: {
    username: function() { this.$emit("changed_username", this.username) },
    password: function() { this.$emit("changed_password", this.password) },
  }
};

new Vue({
  el: "#app",
  components: { LogRegModal },
  data: () => ({ username: "", password: "" }),
  methods: {
    handleUsernameChange(val) { this.username = val },
    handlePasswordChange(val) { this.password = val }
  },
});
code {
  color: red;
}
p {
  margin-bottom: 2px;
}
.second-p {
  margin-top: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>

<div id="app">
  <!-- ******************************************** -->
  <!--  Notice we are now handling events as props  -->
  <!-- ******************************************** -->
  <Log-Reg-Modal 
    @changed_username="handleUsernameChange"
    @changed_password="handlePasswordChange"
  ></Log-Reg-Modal>
  <div v-if="username || password">
    <p><i>These values were received via </i><code>this.$emit</code> as 'props' on our component using <code>v-on:event_name</code></p>
    <p class="second-p">(using <code>@event_name</code> is shorthand for <code>v-on:event_name</code>):</p>
    <ul>
      <li v-if="username"><b>Username:</b> {{username}}</li>
      <li v-if="password"><b>Password:</b> {{password}}</li>
    </ul>
  </div>
</div>

0👍

  1. Handlers that are indicated in EventBus.$on should be functions and not props themself.
  2. Did you call register method before starting the use of the log-reg-modal component?

0👍

EventBus.$on methods should be in created() functions in according to Vue lifecycle

created (){
        EventBus.$on('changed_username', (data) => {
            this.username = data;
          });
        EventBus.$on('changed_password', (data) => {
            this.password = data;
          });
}

Leave a comment