With the following component, I am getting an Error: [vuex] do not mutate vuex store state outside mutation handlers.
error:
JavaScript
x
66
66
1
<template>
2
<div>
3
<v-data-table
4
:headers="headers"
5
:items="items"
6
:search="search"
7
:key="tableKey"
8
:pagination.sync="pagination"
9
disable-initial-sort
10
rowKey
11
>
12
<template slot="items" slot-scope="props">
13
<tr @click="clicked(props.item)" :class="{'secondary': props.item[rowKey]===selectedCode}">
14
<td v-for="header in headers" :key="header.value">
15
<BaseTableColumn
16
:item="props.item"
17
:index="header.value"
18
:format="header.format"
19
/>
20
</td>
21
</tr>
22
</template>
23
</v-data-table>
24
</div>
25
</template>
26
27
<script>
28
export default {
29
name: 'BaseTable',
30
props: {
31
headers: Array,
32
items: Array,
33
search: String,
34
tableKey: String,
35
rowKey: String,
36
},
37
data: () => ({
38
pagination: {
39
rowsPerPage: 10,
40
totalItems: -1,
41
},
42
selectedCode: -1,
43
}),
44
components: {
45
BaseTableColumn: () => import('@/components/base/BaseTableColumn'),
46
},
47
methods: {
48
clicked(row) {
49
window.scrollTo(0, 0);
50
this.selectedCode = row[this.rowKey];
51
this.$set(row, 'selected', true);
52
this.$emit('rowClick', row);
53
},
54
highlightFirst(items) {
55
this.selectedCode = this.items[0][this.rowKey];
56
this.$set(this.items[0], 'selected', true);
57
},
58
},
59
updated() {
60
if (this.selectedCode === -1 && (typeof this.items === 'object') && this.items.length > 0) {
61
this.highlightFirst(this.items);
62
}
63
},
64
};
65
</script>
66
For reference, here is headers.js
:
JavaScript
1
13
13
1
const headers = [
2
{
3
text: 'Tenant Code',
4
value: 'code',
5
},
6
{
7
text: 'Tenant ID',
8
value: 'name',
9
},
10
];
11
12
export default headers;
13
and BaseTableColumn.vue
:
JavaScript
1
22
22
1
<script>
2
export default {
3
name: 'BaseTableColumn',
4
props: {
5
format: Function,
6
item: Object,
7
index: String,
8
},
9
methods: {
10
getText() {
11
return this.item[this.index];
12
},
13
},
14
render(createElement) {
15
if (this.$props.format) {
16
return this.$props.format(this.item, this.index, createElement);
17
}
18
return createElement('div', this.getText());
19
},
20
};
21
</script>
22
The issue happens here:
JavaScript
1
2
1
this.$set(this.items[0], 'selected', true);
2
However, if I follow the docs like so:
JavaScript
1
47
47
1
<template>
2
<div>
3
<v-data-table
4
:headers="headers"
5
:items="tableRows"
6
:search="search"
7
:key="tableKey"
8
:pagination.sync="pagination"
9
disable-initial-sort
10
rowKey
11
>
12
13
</template>
14
15
<script>
16
export default {
17
name: 'BaseTable',
18
props: {
19
headers: Array,
20
items: Array,
21
search: String,
22
tableKey: String,
23
rowKey: String,
24
},
25
26
computed: {
27
tableRows() {
28
const rows = [this.items];
29
return rows;
30
},
31
},
32
33
methods: {
34
35
highlightFirst(items) {
36
this.selectedCode = this.items[0][this.rowKey];
37
this.$set(this.tableRows[0], 'selected', true);
38
},
39
},
40
updated() {
41
if (this.selectedCode === -1 && (typeof this.tableRows === 'object') && this.tableRows.length > 0) {
42
this.highlightFirst(this.tableRows);
43
}
44
},
45
};
46
</script>
47
I still get the errors, specifically in the updated()
hook and the highlightFirst()
method, even though I’m not referencing or mutating a prop. What else do I need to change to get rid of this error?
Advertisement
Answer
The way I eventually solved this problem was to emit an event and use the row
value in the parent component:
JavaScript
1
6
1
clicked(row) {
2
window.scrollTo(0, 0);
3
this.selectedCode = row[this.rowKey];
4
this.$emit('rowClick', row);
5
},
6
However, to @Jesper’s point above, since then, I have been using Object.assign()
in cases like this where I need to break the link to Vuex.