如何在vue-status-indicator中动态更改道具?

时间:2019-06-11 13:59:13

标签: vue.js vue-component

我是VueJS的新手,在阅读this doc section和此question之后,我无法弄清楚如何动态更改以下组件的道具active|positive|intermediary|negativepulse (可能是另一个)vue-status-indicator

例如:带有user.status = positive和以下错误代码:

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

设置道具类型的正确语法是什么?

1 个答案:

答案 0 :(得分:1)

您可以执行以下操作。.我必须为其编写一个包装程序以使其起作用。

[CodePen Mirror]

编辑 要清楚-您不能在属性内插。。这与boolean中的Vue个属性有关。.< / p>

此:

<status-indicator active pulse />

...与此完全相同:

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

我编写的“包装器”组件允许您提供一个字符串来设置状态(就像您想做的那样):

<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>

这里是.vue格式的完整“包装”组件:(添加了“状态”道具的验证器)

<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>

代码段:

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>