Performance improvements for groups within v-form (#14188)

* added explicit change check before updating the internal value

* bunch of attempted fixes

* Revert "bunch of attempted fixes"

This reverts commit 17b7a5340f.

* nested v-form performance improvements
preventing re-rendering of some groups

* tries to fix accordion always re-rendering

* abnstracted the fix to its own functions

* abstracted the fix to its own functions

* fixes bug with rendering and saving data in accordion groups

* removed unneeded if statement

Co-authored-by: ian <licitdev@gmail.com>
This commit is contained in:
Brainslug
2022-07-07 15:55:35 +02:00
committed by GitHub
parent c3a19c44cb
commit e3643a2c5d
4 changed files with 103 additions and 59 deletions

View File

@@ -106,19 +106,8 @@ export default defineComponent({
const fieldsInSection = computed(() => {
return props.fields
.filter((field) => {
if (field.meta?.group === props.group && field.meta?.id !== props.field.meta?.id) return false;
return true;
})
.map((field) => {
if (field.meta?.id === props.field.meta?.id) {
return merge({}, field, {
hideLabel: true,
});
}
return field;
});
.filter((field) => field.meta?.group === props.group && field.meta?.id === props.field.meta?.id)
.map((field) => merge({}, field, { hideLabel: true }));
});
const edited = computed(() => {

View File

@@ -1,11 +1,11 @@
<template>
<v-item-group v-model="selection" scope="group-accordion" class="group-accordion" :multiple="accordionMode === false">
<accordion-section
v-for="accordionField in rootFields"
v-for="accordionField in groupFields"
:key="accordionField.field"
:field="accordionField"
:fields="fields"
:values="values"
:fields="groupFields"
:values="groupValues"
:initial-values="initialValues"
:disabled="disabled"
:batch-mode="batchMode"
@@ -24,7 +24,7 @@
<script lang="ts">
import { Field } from '@directus/shared/types';
import { defineComponent, PropType, computed, ref, watch } from 'vue';
import { defineComponent, PropType, ref, watch } from 'vue';
import { ValidationError } from '@directus/shared/types';
import AccordionSection from './accordion-section.vue';
import { isEqual } from 'lodash';
@@ -77,7 +77,6 @@ export default defineComponent({
type: String,
default: null,
},
accordionMode: {
type: Boolean,
default: true,
@@ -90,21 +89,18 @@ export default defineComponent({
},
emits: ['apply'],
setup(props) {
const rootFields = computed(() => {
return props.fields.filter((field) => field.meta?.group === props.field.meta?.field);
});
const selection = ref<string[]>([]);
const { groupFields, groupValues } = useComputedGroup();
watch(
() => props.start,
(start) => {
if (start === 'opened') {
selection.value = rootFields.value.map((field) => field.field);
selection.value = groupFields.value.map((field) => field.field);
}
if (start === 'first') {
selection.value = [rootFields.value[0].field];
selection.value = [groupFields.value[0].field];
}
},
{ immediate: true }
@@ -116,21 +112,50 @@ export default defineComponent({
if (!props.validationErrors) return;
if (isEqual(newVal, oldVal)) return;
const includedFieldsWithErrors = props.validationErrors.filter((validationError) =>
rootFields.value.find((rootField) => rootField.field === validationError.field)
groupFields.value.find((rootField) => rootField.field === validationError.field)
);
if (includedFieldsWithErrors.length > 0) selection.value = [includedFieldsWithErrors[0].field];
}
);
return { rootFields, selection, toggleAll };
return { groupFields, groupValues, selection, toggleAll };
function toggleAll() {
if (props.accordionMode === true) return;
if (selection.value.length === rootFields.value.length) {
if (selection.value.length === groupFields.value.length) {
selection.value = [];
} else {
selection.value = rootFields.value.map((field) => field.field);
selection.value = groupFields.value.map((field) => field.field);
}
}
function useComputedGroup() {
const groupFields = ref<Field[]>(limitFields());
const groupValues = ref<Record<string, any>>({});
watch(
() => props.fields,
() => {
const newVal = limitFields();
if (!isEqual(groupFields.value, newVal)) {
groupFields.value = newVal;
}
}
);
watch(
() => props.values,
(newVal) => {
if (!isEqual(groupValues.value, newVal)) {
groupValues.value = newVal;
}
}
);
return { groupFields, groupValues };
function limitFields(): Field[] {
return props.fields.filter((field) => field.meta?.group === props.field.meta?.field);
}
}
},