Vue.js 将v型与groupBy数组一起使用,返回平面数组

Vue.js 将v型与groupBy数组一起使用,返回平面数组,vue.js,vuejs2,v-model,Vue.js,Vuejs2,V Model,我正在尝试设置一个Vue组件,它获取数组中项目的平面列表,按属性对它们进行分组以在子组件中使用,并发出更新的平面数组 “我的截面”组件在其v型模型中使用这些分组项,并发出更新的列表。section组件是带有一些输入字段的拖放组件,因此在section组件下更改项目并发出更新的列表 以下是将平面列表作为道具的组件示例: {{section.name}} 从lodash导入{groupBy}; 从@/components/Section.vue导入ItemSection; 导出默认值{ 姓名:Ite

我正在尝试设置一个Vue组件,它获取数组中项目的平面列表,按属性对它们进行分组以在子组件中使用,并发出更新的平面数组

“我的截面”组件在其v型模型中使用这些分组项,并发出更新的列表。section组件是带有一些输入字段的拖放组件,因此在section组件下更改项目并发出更新的列表

以下是将平面列表作为道具的组件示例:

{{section.name}} 从lodash导入{groupBy}; 从@/components/Section.vue导入ItemSection; 导出默认值{ 姓名:ItemAssignment, 道具:{ //平面阵列中的所有项目 价值:{ 类型:数组, 要求:正确, 默认值:=>[ /** * { *id:null, *节id:null, *名称:空 * } */ ] }, //包含可用节的模板 模板:{ 类型:对象, 默认值:=>{ 返回{ 章节:[ /** * { *id:null, *名称:空 * } */ ] }; } } }, 组成部分:{ 项目组 }, 资料{ 返回{ 部分数据:[] }; }, 安装{}, 计算:{ 扁平数据{ 返回Object.values本节data.flat; } }, 方法:{}, 观察:{ //单位名单更新 价值:{ 立即:是的, 深:是的, 汉德尔瓦尔{ this.sectionData=groupByval,section\u id; } }, //-引起无限循环-- //平坦数据{ //这是一个输入值,val; // }, } }; 该组件的父级基本上如下所示:

<template>
    <div>
        <!-- List items should be updatable here or from within the assignment component -->
        <item-assignment v-model="listItems"></item-assignment>
    </div>
</template>

<script type="text/javascript">
import ItemAssignment from "@/components/ItemAssignment.vue";

export default {
    name: "ItemExample",
    props: {

    },
    components: {
        ItemAssignment
    },
    data() {
        return {
            listItems: []
        };
    },
    mounted() {},
    computed: {

    },
    methods: {
        // Coming from API...
        importExisting(list) {
            var newList = [];

            list.forEach(item => {
                const newItem = {
                    id: null, // New record, so don't inherit ID
                    section_id: item.section_id,
                    name: item.name
                };

                newList.push(newItem);
            });

            this.listItems = newList;
        }
    },
    watch: {

    }
};
</script>
当发出最终确定的平面阵列时,Vue进入无限循环,试图重新处理列表,浏览器选项卡冻结

我相信groupBy和/或Object.valuesarray.flat方法正在剥离反应性,因此Vue总是认为这是不同的数据,从而形成无限循环

我曾尝试手动循环这些项并将它们推送到临时数组,但也遇到了同样的问题


如果有人知道如何在保持反应性的同时将这些物品分组并展平,我将不胜感激。谢谢

所以发生这种情况是有道理的

groupBy函数创建一个新数组,由于您正在观察该数组,因此会触发输入事件,从而导致父级更新并传递在循环中再次触发的相同值

因为您已经在使用lodash,所以您可能能够包括可以比较数组的isEqual函数

从lodash进口{groupBy,isEqual}; 从@/components/Section.vue导入ItemSection; 导出默认值{ //…修订的代码。。。 观察:{ //单位名单更新 价值:{ 立即:是的, 深:是的, handlerval,oldVal{ 如果!是相等的,奥德瓦尔 this.sectionData=groupByval,section\u id; } }, 平坦数据{ 这是一个输入值,val; }, } }; 如果旧值和新值相同,则应防止this.sectionData更新


这也可以在FlattedData中完成,但需要另一个值来存储以前的状态。

您是否尝试过将v-model分解为值和@input?因为这就是v-model的基本组成部分。是的。尝试:value和@input到执行展平的方法,但在该组件中发出新的展平数组后出现相同的问题。你的意思是在这一个的父组件上尝试吗?所以我想你可以将item节的值绑定到一个computed属性,它是平面数组的分组版本。在输入item部分时,使用方法更新平面数组。通过这种方式,您可以删除平面阵列上的手表是导致循环的$emit还是父组件的侦听器?您能否分享父组件对ItemAssignment的使用?谢谢您的建议。如果我使用计算setter,它不会在更新时设置。我似乎需要一个深入的观察者来检测重新排序和项目值更新。每当我向这个组件传递一个新的列表时,我都会得到一个常量in/out循环。非常感谢!使用isEqual很有魅力!