微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何自动显示行之间的值差异Vue.js 数据表

如何解决如何自动显示行之间的值差异Vue.js 数据表

如何自动计算当前行和上一行之间的值差异。我在 Vue 和 Vuetify 中使用“数据表”。 在我的代码中,我添加了静态值来说明我想要做什么(“卡路里变化”列)。此列不应可用于添加和编辑。

示例:

example image

如果以前的值大于当前值 - 我想显示具有差异值的“-”。

如果以前的值小于当前值 - 我想显示带有差异值的“+”。

如果值相同 - 我想显示“0”。

在这个例子中,重点是我想知道接下来几天我吃了多少(更多、更少或相同)卡路里。

有人可以帮忙处理这个案子吗?

演示: Codepen

HTML:

<div id="app">
  <v-app id="inspire">
    <v-data-table
      :headers="headers"
      :items="results"
      sort-by="date"
      sort-desc
      class="elevation-1"
    >
      <template v-slot:top>
        <v-toolbar
          flat
        >
          <v-toolbar-title>Data</v-toolbar-title>
          <v-divider
            class="mx-4"
            inset
            vertical
          ></v-divider>
          <v-spacer></v-spacer>
          <v-dialog
            v-model="dialog"
            max-width="500px"
          >
            <template v-slot:activator="{ on,attrs }">
              <v-btn
                color="primary"
                dark
                class="mb-2"
                v-bind="attrs"
                v-on="on"
              >
                Add new
              </v-btn>
            </template>
            <v-card>
              <v-card-title>
                <span class="headline">{{ formTitle }}</span>
              </v-card-title>
  
              <v-card-text>
                <v-container>
                  <v-row>
                    <v-col
                      cols="12"
                      sm="6"
                      md="6"
                    >
                      <v-menu
                        ref="dateMenu"
                        v-model="dateMenu"
                        :close-on-content-click="false"
                        :return-value.sync="editedItem.date"
                        transition="scale-transition"
                        offset-y
                        min-width="auto"
                      >
                        <template v-slot:activator="{ on,attrs }">
                          <v-text-field
                            v-model="editedItem.date"
                            label="Select date"
                            prepend-icon="mdi-calendar"
                            readonly
                            v-bind="attrs"
                            v-on="on"
                          ></v-text-field>
                        </template>
                        <v-date-picker
                          v-model="editedItem.date"
                          no-title
                          scrollable
                        >
                          <v-spacer></v-spacer>
                          <v-btn
                            text
                            color="primary"
                            @click="dateMenu = false"
                          >
                            Cancel
                          </v-btn>
                          <v-btn
                            text
                            color="primary"
                            @click="$refs.dateMenu.save(editedItem.date)"
                          >
                            OK
                          </v-btn>
                        </v-date-picker>
                      </v-menu>
                    </v-col>
                    <v-col
                      cols="12"
                      sm="6"
                      md="6"
                    >
                      <v-text-field
                        v-model="editedItem.calories"
                        label="Calories"
                      ></v-text-field>
                    </v-col>
                  </v-row>
                </v-container>
              </v-card-text>
  
              <v-card-actions>
                <v-spacer></v-spacer>
                <v-btn
                  color="blue darken-1"
                  text
                  @click="close"
                >
                  Cancel
                </v-btn>
                <v-btn
                  color="blue darken-1"
                  text
                  @click="save"
                >
                  Save
                </v-btn>
              </v-card-actions>
            </v-card>
          </v-dialog>
          <v-dialog v-model="dialogDelete" max-width="500px">
            <v-card>
              <v-card-title class="headline">Are you sure you want to delete this item?</v-card-title>
              <v-card-actions>
                <v-spacer></v-spacer>
                <v-btn color="blue darken-1" text @click="closeDelete">Cancel</v-btn>
                <v-btn color="blue darken-1" text @click="deleteItemConfirm">OK</v-btn>
                <v-spacer></v-spacer>
              </v-card-actions>
            </v-card>
          </v-dialog>
        </v-toolbar>
      </template>
      <template v-slot:item.actions="{ item }">
        <v-icon
          small
          class="mr-2"
          @click="editItem(item)"
        >
          mdi-pencil
        </v-icon>
        <v-icon
          small
          @click="deleteItem(item)"
        >
          mdi-delete
        </v-icon>
      </template>
      <template v-slot:no-data>
        No results
      </template>
    </v-data-table>
  </v-app>
</div>

JS:

new Vue({
  el: '#app',vuetify: new Vuetify(),data: () => ({
    dateMenu: false,dialog: false,dialogDelete: false,headers: [
      {
        text: 'Date',align: 'start',sortable: true,value: 'date',},{ text: 'Calories (kcal)',value: 'calories' },{ text: 'Calories difference',value: 'caloriesChange',sortable: false },{ text: 'Actions',value: 'actions',],results: [],editedindex: -1,editedItem: {
      date: new Date().toISOString().substr(0,10),calories: 0,// this should calculate automatically
      caloriesChange: 0,defaultItem: {
      date: new Date().toISOString().substr(0,}),computed: {
    formTitle () {
      return this.editedindex === -1 ? 'New Item' : 'Edit Item'
    },watch: {
    dialog (val) {
      val || this.close()
    },dialogDelete (val) {
      val || this.closeDelete()
    },created () {
    this.initialize()
  },methods: {
    initialize () {
      this.results = [
        {
          date: '2021-01-09',calories: 2905,// this should calculate automatically
          caloriesChange: '+ ' + 55 + ' kcal',{
          date: '2021-01-08',calories: 2850,// this should calculate automatically
          caloriesChange: '+ ' + 150 + ' kcal',{
          date: '2021-01-07',calories: 2700,// this should calculate automatically
          caloriesChange: '- ' + 800 + ' kcal',{
          date: '2021-01-06',calories: 3500,// this should calculate automatically
          caloriesChange: '+ ' + 300 + ' kcal',{
          date: '2021-01-05',calories: 3200,{
          date: '2021-01-04',calories: 2900,// this should calculate automatically
          caloriesChange: '' + 0 + ' kcal',{
          date: '2021-01-03',// this should calculate automatically
          caloriesChange: '- ' + 100 + ' kcal',{
          date: '2021-01-02',calories: 3000,// this should calculate automatically
          caloriesChange: '- ' + 10 + ' kcal',{
          date: '2021-01-01',calories: 3010,// this should calculate automatically
          caloriesChange: '+ ' + 10 + ' kcal',{
          date: '2020-12-31',// this must be empty (first result)
          caloriesChange: '',]
    },editItem (item) {
      this.editedindex = this.results.indexOf(item)
      this.editedItem = Object.assign({},item)
      this.dialog = true
    },deleteItem (item) {
      this.editedindex = this.results.indexOf(item)
      this.editedItem = Object.assign({},item)
      this.dialogDelete = true
    },deleteItemConfirm () {
      this.results.splice(this.editedindex,1)
      this.closeDelete()
    },close () {
      this.dialog = false
      this.$nextTick(() => {
        this.editedItem = Object.assign({},this.defaultItem)
        this.editedindex = -1
      })
    },closeDelete () {
      this.dialogDelete = false
      this.$nextTick(() => {
        this.editedItem = Object.assign({},save () {
      if (this.editedindex > -1) {
        Object.assign(this.results[this.editedindex],this.editedItem)
      } else {
        this.results.push(this.editedItem)
      }
      this.close()
    },})

解决方法

如何使用计算得到的 getter 根据结果映射一个新数组?

类似于:

  computed: {
    ...,calcResults () {
      let sortedResults = this.results.sort(function(a,b){
        return new Date(b.date) - new Date(a.date);
       }).reverse();
      return sortedResults.map((result,index,results) => {
        let caloriesChange = index > 0 ? results[index].calories - results[index - 1].calories + ' kCal': '';
        return {
          date: result.date,calories: result.calories,caloriesChange: caloriesChange
        }
      });
    }
  },

在你的 HTML 中:

    <v-data-table
      :headers="headers"
      :items="calcResults"
      sort-by="date"
      sort-desc
      class="elevation-1"
    >

enter image description here

,

您可以在 computed 字段中创建方法:

computedResults() {
  return this.results.map((e,i,arr) => {
  let caloriesChange = i < arr.length - 1 ? arr[i + 1].calories - e.calories : '';
  if(caloriesChange > 0) {
    caloriesChange = `+${caloriesChange}`;
  }
  return {
    ...e,caloriesChange
   }
 });
}

而不是传递 results,而是在 computedResults 中传递 <v-data-table />

<v-data-table
  :headers="headers"
  :items="computedResults"
  sort-by="date"
  sort-desc
  class="elevation-1"
>

检查 codepen

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。