use vueJS’s Watch() method to track changes in the values of a variable

Asked

Viewed 1,413 times

2

<template>
    <div>
        <span class="badge" :class="styleStatus" > {{tipoStatus}}</span>
    </div>
</template>

<script>
export default {
    props:{
        status:{
            type:String
        }
    },
    data: function () {
        return {
            tipoStatus: '',
            styleStatus: '',
        }
    },
    methods:{
        alterarStatusAtivo() {
            this.tipoStatus = 'Ativo'
            this.styleStatus = 'badge-secondary'
        },
        alterarStatusInativo() {
            this.tipoStatus = 'Inativo'
            this.styleStatus = 'badge-danger'
        }
    },
    watch:{
        status(){
            if (status == 'a'){
                this.alterarStatusAtivo()
            }
            if(status == 'i'){
                this.alterarStatusInativo()
            }
        }
    }
}

My goal was every time the parent variable inherited by the props method was changed I did something in the template. I read that the watch method it keeps following the variable for each change of it. however unsuccessful. Would you have any solution for this code? i needed every time the status change to trigger some function.

code of the "father":

<template>
    <div id="app">
        Digite o status:
        <input type="text" v-model="status" >
        <showStatus :status="this.status"/>
    </div>
</template>

<script>
import showStatus from "./components/show-status-ativo-inativo.vue"

export default {
    name: "app",
    components: { showStatus },
    data(){
        return{
            status: ''
        }
    }
}
</script>

1 answer

2


Several problems in your code... here are fixes:

  • on Watcher you’re using if (status == 'a') { but this status is not part of the function’s arguments... or you use status(status) { in the function statement (as I did) or else if (this.status == 'a') {
  • within the template don’t use this, uses directly :status="status"
  • within the template don’t use camelCase, uses kebab-case, because it should validate as HTML, even if it is a component.

const showStatus = {
  template: `
  <div>
    <span :class="'badge ' + styleStatus">
      O status é: {{tipoStatus}}
    </span>
  </div>
`,
  props: {
    status: {
      type: String
    }
  },
  data: function() {
    return {
      tipoStatus: '',
      styleStatus: '',
    }
  },
  methods: {
    alterarStatusAtivo() {
      this.tipoStatus = 'Ativo'
      this.styleStatus = 'badge-secondary'
    },
    alterarStatusInativo() {
      this.tipoStatus = 'Inativo'
      this.styleStatus = 'badge-danger'
    }
  },
  watch: {
    status(status) {
      if (status == 'a') {
        this.alterarStatusAtivo()
      }
      if (status == 'i') {
        this.alterarStatusInativo()
      }
    }
  }
};

const app = new Vue({
  name: "app",
  components: {
    showStatus
  },
  data() {
    return {
      status: ''
    }
  }
}).$mount('#app');
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>


<div id="app">
  Digite o status:
  <input type="text" v-model="status">
  <show-status :status="status"></show-status>
</div>

However, to take advantage of Vue I did not do this with watch and methods... I would do with computed properties... so:

const showStatus = {
  template: `
      <div>
        <span :class="'badge ' + styleStatus">
          O status é: {{tipoStatus}}
        </span>
      </div>
    `,
  props: {
    status: {
      type: String
    }
  },
  computed: {
    tipoStatus() {
      if (this.status === 'a') return 'Ativo';
      else if (this.status === 'i') return 'Inativo';
      else return 'desconhecido...';
    },
    styleStatus() {
      if (this.status === 'a') return 'badge-secondary';
      else if (this.status === 'i') return 'badge-danger';
      else return '';
    },
  },

};

const app = new Vue({
  name: "app",
  components: {
    showStatus
  },
  data() {
    return {
      status: ''
    }
  }
}).$mount('#app');
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>


<div id="app">
  Digite o status:
  <input type="text" v-model="status">
  <show-status :status="status"></show-status>
</div>

Browser other questions tagged

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