简体   繁体   中英

How to change prop dynamically in vue-status-indicator?

I am new to VueJS and after reading this doc section and this question , I can't figure how to change dynamically the prop active|positive|intermediary|negative and pulse of the following component (it could be another) : vue-status-indicator

eg: with user.status = positive and the following wrong code :

<span v-for="user in users" :key="user.id">
  <status-indicator {{ user.status }}></status-indicator>
</span> 

What is the correct syntax to set theses type of props ?

You could do something like this.. I had to write a wrapper for it to make it functional..

[CodePen Mirror]

Edit To be clear - you cannot interpolate inside an attribute.. This has to do with boolean attributes in Vue ..

This:

<status-indicator active pulse />

...is the same exact thing as doing this:

<status-indicator :active="true" :pulse="true" />

The "wrapper" component I wrote allows you to supply a string to set the status (like you are wanting to do):

<v-indicator status="active" pulse></v-indicator>
<!-- OR -->
<v-indicator status="positive" pulse></v-indicator>
<!-- OR -->
<v-indicator status="intermediary" pulse></v-indicator>
<!-- OR -->
<v-indicator status="negative" pulse></v-indicator>

Here is the full "wrapper" component, in .vue format: (added a validator for the 'status' prop)

<template>
  <status-indicator 
    :active="indicatorStatus.active" 
    :positive="indicatorStatus.positive"
    :intermediary="indicatorStatus.intermediary"
    :negative="indicatorStatus.negative"
    :pulse="pulse"
  ></status-indicator>
</template>

<script>
export default {
props: {
    status: {
      type: String,
      required: true,
      validator: (prop) => [
        'active',
        'positive',
        'intermediary',
        'negative',
      ].includes(prop)      
    },    
    pulse: {
      type: Boolean,
      required: false,
      default: false,
    },
  },
  data() {
    return { 
      indicatorStatus: {
        active: false,
        positive: false,
        intermediary: false,
        negative: false,
      }
    }
  },
  watch: {
    status() {
      this.handleStatusChange(this.status);
    }
  },
  methods: {
    handleStatusChange(newStatus) {
      Object.keys(this.indicatorStatus).forEach(v => this.indicatorStatus[v] = false);
      this.indicatorStatus[newStatus] = true;
    }
  },
  mounted() {
    this.handleStatusChange(this.status);    
  }    
}
</script>

Snippet:

 const vIndicator = { template: "#v-indicator", props: { status: { type: String, required: true, validator: (prop) => [ 'active', 'positive', 'intermediary', 'negative', ].includes(prop) }, pulse: { type: Boolean, required: false, }, }, data() { return { indicatorStatus: { active: false, positive: false, intermediary: false, negative: false, } } }, watch: { status() { this.handleStatusChange(this.status); } }, methods: { handleStatusChange(newStatus) { Object.keys(this.indicatorStatus).forEach(v => this.indicatorStatus[v] = false); this.indicatorStatus[newStatus] = true; } }, mounted() { this.handleStatusChange(this.status); } } new Vue({ el: '#app', components: { vIndicator }, data: { currentStatus: '', isPulse: '', }, computed: { currentJson() { let cj = { currentStatus: this.currentStatus, isPulse: this.isPulse, }; return JSON.stringify(cj, null, 2); } }, mounted() { let statuses = ["active", "positive", "intermediary","negative"]; let c = 0; let t = 0; this.currentStatus = statuses[c]; this.isPulse = true; setInterval(() => { t = c + 1 > 3 ? t + 1 : t; c = c + 1 > 3 ? 0 : c + 1; this.currentStatus = statuses[c]; this.isPulse = (t % 2 == 0) ? true : false; }, 2000) } })
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script> <script src="https://unpkg.com/vue-status-indicator@latest/dist/vue-status-indicator.min.js"></script> <link href="https://unpkg.com/vue-status-indicator@latest/styles.css" rel="stylesheet"/> <div id="app"> <p>Will alternate status as well as pulsing (pulse changes after each full loop)</p> <!-- [status]active|positive|intermediary|negative [pulse]true|false --> <v-indicator :status="currentStatus" :pulse="isPulse"></v-indicator> <pre>{{ currentJson }}</pre> </div> <!-- WRAPPER COMPONENT --> <script type="text/x-template" id="v-indicator"> <status-indicator :active="indicatorStatus.active" :positive="indicatorStatus.positive" :intermediary="indicatorStatus.intermediary" :negative="indicatorStatus.negative" :pulse="pulse" ></status-indicator> </script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM