У меня есть следующий набор компонентов для создания таблицы
table - использует заголовок (передаваемые столбцы) и список строк, содержащий rowData и столбцы
header - использует переданные столбцы и использует headerCell, передавая свойство столбца
Моя проблема заключается в следующем: я хочу, чтобы щелчок (скажем, видимость) в заголовке обновлял columnDefinition с visible true | false, и за ним следят строки для соответствующего обновления видимости. Однако, что бы я ни пробовал, наблюдатель все еще не запускается. Что я делаю неправильно?
/**** Table ***/
<template>
<table>
<HeaderRow :columns=computedColumns :groups=columnGroups v-
on:column:change=onColumnChange></HeaderRow>
<tbody>
<Row v-for = "(row, index) in computedData" :key=index :data=row
:columns=computedColumns :rowIndex=index ></Row>
</tbody>
</table>
</template>
<script>
import Row from "./Row.vue";
import HeaderRow from "./HeaderRow.vue";
export default {
computed: {
/* If this.columns is set (columns is a prop) than map it to a new array, otherwise
try to identify the columns from the row data */
computedColumns: function() {
if (this.columns && this.columns.length) {
return this.columns.map(col => {
return Object.assign({
title: '',
name: '',
description: undefined,
className: '',
style: '',
visible: true,
sort: false,
group: undefined,
defaultValue: undefined,
}, col)
});
} else {
return (
this.data &&
this.data
.map(function(row) {
return Object.keys(row);
})
.reduce(function(arr, row) {
return arr.concat(
row.filter(function(value, index) {
return arr.indexOf(value) == -1;
})
);
}, [])
.map(function(column) {
return {
title: column,
name: column
};
})
);
}
},
}
/*** HeaderCell ***/
<th @click=toggleColumn :class=className><span>{{column.title}}</span></th>
...
...
toggleColumn: function(e) {
this.visible = !this.visible;
this.column.visible = this.visible;
this.$emit("column:change", {
column: this.column,
columnIndex: this.columnIndex
});
}
/*** Row ****/
<template>
<tr>
<td v-for = "(cell, index) in cells" :key=index :class=cell.className
:style=cell.style v-html=cell.value ></td>
</tr>
</template>
<script>
export default {
props: {
data: {
default: []
},
columns: {
default: "",
type: Array
},
rowIndex: {
default: -1
}
},
watch: {
columns: {
handler: function () {
console.info('change occurred')
},
deep: true
}
},
Не могли бы вы показать нам, что такое метод computedColumns
?
Я заметил, что ваша опора столбцов использует computedColumns
.
Было бы хорошо увидеть, что это, потому что вероятно, что он теряет реактивность, когда вы возвращаете значение из этого вычисленного свойства.
например, если в вашем родителе есть следующее:
computed: {
computedColumns() {
// return new set of columns
return [
{id: 1, visible: false},
{id: 2, visible: false},
{id: 3, visible: false}
]
}
}
Тогда свойство computedColumns
не будет иметь никакой реактивности. Поэтому вы не сможете его смотреть.
Однако, если у вас есть в качестве примера:
data() {
return {
columns: [
{id: 1, visible: false},
{id: 2, visible: false},
{id: 3, visible: false}
]
}
},
computed: {
computedColumns() {
// return reactive data attribute
return this.columns
}
}
Поскольку вы ссылаетесь на исходный атрибут данных, вы сохраните реактивность.
Поэтому вам, возможно, придется переосмыслить, как вы устанавливаете свойство columns для поддержания реактивности.
Вот рабочий пример, который описывает этот пример.
Я обновил исходный фрагмент кода, чтобы показать вычисленный. В основном у меня есть второй сценарий, но он использует функцию карты, которая, вероятно, останавливает реактивность.
Как было предложено выше, с вычисленными столбцами теряется реактивность. Вместо этого я добавил часы в опору столбцов и назначил computedColumns (теперь под данными) с соответствующим преобразованием, что сделало его реактивным.
Отлично, рад, что у вас все получилось. Не стесняйтесь голосовать за ответ, если считаете, что оно того стоит. Ваше здоровье
какой формат данных у вашего реквизита =
columns
?