关于vue.js:从子组件更改事件中v-data-table行的背景

Change background of v-data-table row on event from child component

我在父组件中有一个扩展数据表,在带有按钮的扩展行中有一个子组件。当我单击子组件内的按钮时,我想更改关联行的背景颜色。我不确定如何将行定为事件添加css类。

ScanGrid(父级):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
    <template>
      <v-flex v-if="items.length === 0">
        <ScanAdd @selectBatch="showScan" />
      </v-flex>
      <v-card v-else class="ma-5">
        <v-card-text>
          <v-layout align-center>
            <v-data-table
              :headers="headers"
              :items="items"
              item-key="StorageName"
              show-expand
              single-expand
              :expanded="expanded"
              hide-default-footer
              @click:row="clickedRow"
            >
              <template
                @isDeleted="deleteRow"
                v-if="groupBy === 'barCode'"
                v-slot:expanded-item="{ item }"
              >
                <td :colspan="12">
                  <ScanGridCode :item="item" />
                </td>
              </template>
              <template v-else v-slot:expanded-item="{ item }">
                <td :colspan="12">
                  <ScanGridDef :item="item" />
                </td>
              </template>
            </v-data-table>
          </v-layout>
        </v-card-text>
      </v-card>
    </template>

   
    import { API } from"@/api";
    import ScanAdd from"./ScanAdd";
    import ScanGridCode from"./ScanGridCode";
    import ScanGridDef from"./ScanGridDef";
    export default {
      name:"ScanGrid",
      props: {
        items: {
          type: Array,
          required: true
        }
      },
      components: {
        ScanGridCode,
        ScanGridDef,
        ScanAdd
      },
      methods: {
        deleteRow(value) {
          this.isDeleted = value;
        },
        showScan(value) {
          this.selectedId = value;
          this.addScanBatch(value);
          this.$emit("processingBatch", true);
          this.processingBatch = true;
        },
        async addScanBatch(Id) {
          const selectedItems = await API.getPhysicalInventoryBatch(Id);
          if (selectedItems.data.Id === this.selectedId) {
            this.items = selectedItems.data.Locations;
          }
        },
        clickedRow(value) {
          if (
            this.expanded.length &&
            this.expanded[0].StorageName == value.StorageName
          ) {
            this.expanded = [];
          } else {
            this.expanded = [];
            this.expanded.push(value);
          }
        }
      },
      data: () => ({
        isDeleted: false,
        groupBy:"barCode",
        expanded: [],
        items: [],
        toDelete:"",
        totalResults: 0,
        loading: true,
        headers: [
          {
            text:"Localisation",
            sortable: true,
            value:"StorageName",
            class:"large-column font-weight"
          },
          {
            text:"Paquets scann??s",
            sortable: true,
            value:"ScannedProduct",
            class:"large-column font-weight"
          },
          {
            text:"Paquets entrants",
            sortable: true,
            value:"Incoming",
            class:"large-column font-weight"
          },
          {
            text:"Paquets sortants",
            sortable: true,
            value:"Outgoing",
            class:"large-column font-weight"
          },
          {
            text:"Paquets inconnus",
            sortable: true,
            value:"Unknown",
            class:"large-column font-weight"
          }
        ]
      })
    };

ScanGridCode(子级):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
    <template>
     
       
          <v-flex class="justify-center">
            <v-btn class="ma-5" large color="lowerCase" tile  @click="deleteLocation"
              >Annuler le d??p?′t de cette localisation</v-btn
            >
          </v-flex>
       
     
    </template>

   
    export default {
      name:"ScanGridCode",
      props: {
        item: {
          type: Object,
          required: true
        }
      },
      methods: {
        deleteLocation() {
          this.item.IsDeleted = true;
          this.$emit("IsDeleted", true);
        }
      },
      data: () => ({
        IsDeleted: false,
        groupBy: 0,
        headersGroupCode: [
          {
            text:"Code barre",
            sortable: true,
            value:"SerialNumber",
            class:"large-column font-weight-light"
          },
          {
            text:"De",
            sortable: true,
            value:"FromLocation",
            class:"large-column font-weight-light"
          },
          {
            text:"Vers",
            sortable: true,
            value:"ToLocation",
            class:"large-column font-weight-light"
          }
        ]
      })
    };

我使用Vuetify 2.1.7和Vue 2.6.10。当我单击按钮时,我调用deleteLocation函数。我假设我需要给父母$ emit一个值,但是在那之后我不知道如何以tr为目标来更改其样式。


由于您正在使用Vuex,因此建议您使用诸如store.state.selectedRow之类的变量来跟踪是否已选择某行(或者在有多行的情况下,选择哪一行已选中)。然后,您可以在Vue组件中具有一个计算属性myProperty = this.$store.state.selectedRow,该属性将自动反映真相的单个来源,并且您的条件类可以绑定到此myProperty。这意味着您不必担心会发生事件。


发出事件的方法是应该做的。所以我假设您将从deleteLocation函数发出。
由于您需要在行上使用自定义样式,因此需要添加项目插槽并在其中添加逻辑

1
2
3
4
5
6
7
8
9
10
<template v-slot:item="{ item, select}">
 <tr :class="key === coloredRow ? 'custom-highlight-row' : ''">

     <td :colspan="12">
    <ScanGridCode @changeColor="changeColor(key)" :item="item" />
    </td>
 //add this method to your script element
 changeColor(idx) {
      this.coloredRow = idx;
    }