javascript - Vue 计算进度条的百分比

标签 javascript vue.js

我创建了一个函数来计算表行中的每个值(卡路里、脂肪等)。 我制作了进度条,但我不知道如何计算宽度,以便当我在表中添加新行时它会动态变化。我已经声明了最大值(这是 100%)。

示例: 3464 kcal 是 5000 kcal 的 69.28% (~69.3)

<div class="progress" style="width: {{ kcalPercentage }}%"></div>

演示代码 here

HTML:

<div id="app">
  <v-app id="inspire">
    <v-row class="bars">
      <v-col
        cols="12"
        md="4"
      >
        <p>Calories</p>
        <p><strong>{{ sum('calories') }}</strong> / {{ kcalMax }}</p>
        <div class="bar">
          <div class="progress" style="width: 69%"></div>
        </div>
      </v-col>
      <v-col
        cols="12"
        md="4"
      >
        <p>Fat</p>
        <p><strong>{{ sum('fat') }}</strong> / {{ fatMax }}</p>
        <div class="bar">
          <div class="progress" style="width: 52%"></div>
        </div>
      </v-col>
      <v-col
        cols="12"
        md="4"
      >
        <p>Carbs</p>
        <p><strong>{{ sum('carbs') }}</strong> / {{ carbsMax }}</p>
        <div class="bar">
          <div class="progress" style="width: 149%"></div>
        </div>
      </v-col>
    </v-row>
    <v-row>
      <v-col
        cols="12"
      >
        <v-data-table
          :headers="headers"
          :items="desserts"
          :items-per-page="5"
          class="elevation-1"
        ></v-data-table>
      </v-col>
    </v-row>
  </v-app>
</div>

JS:

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      // maximum values
      kcalMax: 5000,
      fatMax: 200,
      carbsMax: 400,
      
      headers: [
        {
          text: 'Dessert (100g serving)',
          align: 'start',
          sortable: false,
          value: 'name',
        },
        { text: 'Calories', value: 'calories' },
        { text: 'Fat (g)', value: 'fat' },
        { text: 'Carbs (g)', value: 'carbs' },
        { text: 'Protein (g)', value: 'protein' },
        { text: 'Iron (%)', value: 'iron' },
      ],
      desserts: [
        {
          name: 'Frozen Yogurt',
          calories: 159,
          fat: 6.0,
          carbs: 24,
          protein: 4.0,
          iron: '1%',
        },
        {
          name: 'Ice cream sandwich',
          calories: 237,
          fat: 9.0,
          carbs: 37,
          protein: 4.3,
          iron: '1%',
        },
        {
          name: 'Eclair',
          calories: 262,
          fat: 16.0,
          carbs: 23,
          protein: 6.0,
          iron: '7%',
        },
        {
          name: 'Cupcake',
          calories: 305,
          fat: 3.7,
          carbs: 67,
          protein: 4.3,
          iron: '8%',
        },
        {
          name: 'Gingerbread',
          calories: 356,
          fat: 16,
          carbs: 49,
          protein: 3.9,
          iron: '16%',
        },
        {
          name: 'Jelly bean',
          calories: 375,
          fat: 0,
          carbs: 94,
          protein: 0.0,
          iron: '0%',
        },
        {
          name: 'Lollipop',
          calories: 392,
          fat: 1,
          carbs: 98,
          protein: 0,
          iron: '2%',
        },
        {
          name: 'Honeycomb',
          calories: 408,
          fat: 3,
          carbs: 87,
          protein: 6.5,
          iron: '45%',
        },
        {
          name: 'Donut',
          calories: 452,
          fat: 25,
          carbs: 51,
          protein: 4.9,
          iron: '22%',
        },
        {
          name: 'KitKat',
          calories: 518,
          fat: 26.0,
          carbs: 65,
          protein: 7,
          iron: '6%',
        },
      ],
    }
  },
  methods: {
    sum(key) {
      return this.desserts.reduce((a, b) => a + (b[key] || 0), 0)
    },
  },
  computed: {
        /*calculateKcal: function() {
      return ((sum('carbs') / kcalMax) * 100).toFixed(0)
    },*/
  }
})

最佳答案

您可以使用 Vuetify 的 v-progress-linear 组件和通过百分比。文档链接 https://vuetifyjs.com/en/components/progress-linear/

请检查这是否有帮助 https://codepen.io/manojkmishra/pen/JjEPYqw

HTML:

<div id="app">
<v-app id="inspire">
<v-row class="bars">
  <v-col cols="12" md="4">
    <p>Calories</p>
    <p><strong>{{ sum('calories') }}</strong> / {{ kcalMax }}</p>
    <v-progress-linear :value="percentage('calories',kcalMax)"  height="20" background-color="grey lighten-2" color="red lighten-3" >
      <div class="text-center">{{ percentage('calories',kcalMax)}}%</div>
    </v-progress-linear>
  </v-col>
  <v-col cols="12" md="4">
    <p>Fat</p>
    <p><strong>{{ sum('fat') }}</strong> / {{ fatMax }}</p>
    <v-progress-linear :value="percentage('fat',fatMax)"  height="20" background-color="grey lighten-2" color="red lighten-3" >
      <div class="text-center">{{ percentage('fat',fatMax)}}%</div>
    </v-progress-linear>
  </v-col>
  <v-col cols="12" md="4">
    <p>Carbs</p>
    <p><strong>{{ sum('carbs') }}</strong> / {{ carbsMax }}</p>
    <v-progress-linear :value="percentage('carbs',carbsMax)"  height="20" background-color="grey lighten-2" color="red lighten-3" >
      <div class="text-center">{{ percentage('carbs',carbsMax)}}%</div>
    </v-progress-linear>
  </v-col>
</v-row>
<v-row>
  <v-col cols="12">
    <v-data-table :headers="headers" :items="desserts" :items-per-page="5" class="elevation-1"></v-data-table>
  </v-col>
</v-row>
</v-app>
</div>

JS:

new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
  // maximum values
  kcalMax: 5000,
  fatMax: 200,
  carbsMax: 400,
  
  headers: [
    {
      text: 'Dessert (100g serving)',
      align: 'start',
      sortable: false,
      value: 'name',
    },
    { text: 'Calories', value: 'calories' },
    { text: 'Fat (g)', value: 'fat' },
    { text: 'Carbs (g)', value: 'carbs' },
    { text: 'Protein (g)', value: 'protein' },
    { text: 'Iron (%)', value: 'iron' },
  ],
  desserts: [
    {
      name: 'Frozen Yogurt',
      calories: 159,
      fat: 6.0,
      carbs: 24,
      protein: 4.0,
      iron: '1%',
    },
    {
      name: 'Ice cream sandwich',
      calories: 237,
      fat: 9.0,
      carbs: 37,
      protein: 4.3,
      iron: '1%',
    },
    {
      name: 'Eclair',
      calories: 262,
      fat: 16.0,
      carbs: 23,
      protein: 6.0,
      iron: '7%',
    },
    {
      name: 'Cupcake',
      calories: 305,
      fat: 3.7,
      carbs: 67,
      protein: 4.3,
      iron: '8%',
    },
    {
      name: 'Gingerbread',
      calories: 356,
      fat: 16,
      carbs: 49,
      protein: 3.9,
      iron: '16%',
    },
    {
      name: 'Jelly bean',
      calories: 375,
      fat: 0,
      carbs: 94,
      protein: 0.0,
      iron: '0%',
    },
    {
      name: 'Lollipop',
      calories: 392,
      fat: 1,
      carbs: 98,
      protein: 0,
      iron: '2%',
    },
    {
      name: 'Honeycomb',
      calories: 408,
      fat: 3,
      carbs: 87,
      protein: 6.5,
      iron: '45%',
    },
    {
      name: 'Donut',
      calories: 452,
      fat: 25,
      carbs: 51,
      protein: 4.9,
      iron: '22%',
    },
    {
      name: 'KitKat',
      calories: 518,
      fat: 26.0,
      carbs: 65,
      protein: 7,
      iron: '6%',
    },
  ],
}
},
methods: {
sum(key) {
  return this.desserts.reduce((a, b) => a + (b[key] || 0), 0)
},
percentage( key,maxValue) {
  let total=this.desserts.reduce((a, b) => a + (b[key] || 0), 0);
  return (100 * total) / maxValue;
}
},
})

关于javascript - Vue 计算进度条的百分比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66717631/

相关文章:

vue.js - 视觉 : Error in created hook: "TypeError: Cannot convert undefined or null to object"

javascript - 原型(prototype)继承的属性在 vue.js 中不是 react 性的?

html - 将 session 中的数据插入到 vue-component

javascript - 是否可以在特定目录中使用 javascript 保存 .swf、.mp3、.txt 等文件而没有 "save as"提示?

javascript - 我应该如何使用 bacon.js 保存多个值的运行总计?

javascript - 使用 map 函数时减少 javascript 代码

vue.js - Yarn add raise error 缺少要添加到项目中的包列表

javascript - 在每个轮盘事件上更改页面

javascript - 如何读取nodejs中的pem文件?

javascript - 在 Json 中搜索过滤器