Правило vue.js & airbnb no-param-reassign lint - Как изменить свойства в массиве объектов?

Я использую Vue-Cli и принял правила ESLint по умолчанию, включая no-param-reassign который я никогда не использовал раньше.

У меня есть метод, который должен:

  1. принять массив columnDefinition объекты

  2. Перебирайте объекты и присваивайте каждому columnDefinition.originalOrder число

  3. Изменить порядок и вернуть массив.

no-param-reassign продолжает ошибаться, если я не использую lodash, чтобы создать новый массив новых объектов и вернуть его.

Так, например, я прохожу в

                [
                    {
                        label: 'Number of Siblings',
                        searchEnabled: false,
                        sortEnabled: false,
                        newOrder: 3,
                        lotsOfNestedData: {
                            moreNesting: 'etc',
                        },
                    },
                    {
                        label: 'Pet Name',
                        searchEnabled: false,
                        sortEnabled: false,
                        newOrder: 1,
                        lotsOfNestedData: {
                            moreNesting: 'etc',
                        },
                    },
                    {
                        label: 'Favorite Hobby',
                        searchEnabled: false,
                        sortEnabled: false,
                        newOrder: 4,
                        lotsOfNestedData: {
                            moreNesting: 'etc',
                        },
                    },
                    {
                        label: 'Favorite Outfit',
                        searchEnabled: false,
                        sortEnabled: false,
                        newOrder: 2,
                        lotsOfNestedData: {
                            moreNesting: 'etc',
                        },
                    },
                ]

Без этого правила я бы .each через массив и мутировать объекты с item.originalOrder = idx имущество. Затем измените массив с помощью .sort основанный на newOrder,

С правилом no mutating params лучшее, что я могу придумать, - это создать новый массив (чтобы я мог его отсортировать), а затем создать клоны каждого объекта, которые я затем смогу добавить .originalOrder собственность на.

const newSrcArray = _.map(srcArray, (item, idx) => {
    const newItem = _.cloneDeep(item);
    newItem.originalOrder = idx;
    return newItem;
});

//sort newSrcArray

return newSrcArray;

Это похоже на дополнительный код и память, но я что-то упустил полностью?

Является ли этот шаблон / память предпочтительным способом сделать это?

Или лучше всего просто отключить правило?

2 ответа

Решение

На форуме vue.js есть официальный ответ

"У самого проекта Vue нет мнения по этому поводу".

Таким образом, ответ на первоначальный вопрос - вариант 2: не рекомендуется оставлять правило Vue включенным.

Вы можете сделать это, используя чистый код JavaScript, используя преимущества map, sort и функции стрелок, я реализую это внутри computed свойство, чтобы показать вам, как это работает, но вы можете использовать эту функцию, как:

addItemSortArr(arr) {

  let a = arr.map((item, i) => {
    let n = item;
    n.originalOrder = i;
    return n;
  });

  return a.sort((a, b) => parseFloat(a.newOrder) - parseFloat(b.newOrder));

}

запустите этот код, чтобы увидеть эффект:

Vue.config.devtools = false;
Vue.config.productionTip = false;

new Vue({
  el: '#app',

  data() {
    return {
      arr: [{
          label: 'Number of Siblings',
          searchEnabled: false,
          sortEnabled: false,
          newOrder: 3,
          lotsOfNestedData: {
            moreNesting: 'etc',
          },
        }

        ,
        {
          label: 'Pet Name',
          searchEnabled: false,
          sortEnabled: false,
          newOrder: 1,
          lotsOfNestedData: {
            moreNesting: 'etc',
          },
        }

        ,
        {
          label: 'Favorite Hobby',
          searchEnabled: false,
          sortEnabled: false,
          newOrder: 4,
          lotsOfNestedData: {
            moreNesting: 'etc',
          },
        }

        ,
        {
          label: 'Favorite Outfit',
          searchEnabled: false,
          sortEnabled: false,
          newOrder: 2,
          lotsOfNestedData: {
            moreNesting: 'etc',
          },
        }


      ]

    }
  },
  computed: {
    sortedArr() {
      let a = this.arr.map((item, i) => {
        let n = {
          label: item.label,
          searchEnabled: item.searchEnabled,
          sortEnabled: item.sortEnabled,
          newOrder: item.newOrder,
          lotsOfNestedData: item.lotsOfNestedData,
          originalOrder: i
        }


        return n;
      });

      return a.sort((a, b) => parseFloat(a.newOrder) - parseFloat(b.newOrder));

    }
  }

});
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>

<div id="app">
  <h3>Original array</h3>
  <table class="table-bordered">
    <thead>
      <th v-for="h in Object.keys(arr[0])">{{h}}</th>
    </thead>
    <tbody>
      <tr v-for="item in arr">
        <td v-for="c in item">{{c}}</td>
      </tr>
    </tbody>

  </table>
  <h3>New sorted array</h3>
  <table class="table-bordered">
    <thead>
      <th v-for="h in Object.keys(sortedArr[0])">{{h}}</th>
    </thead>
    <tbody>
      <tr v-for="item in sortedArr">
        <td v-for="c in item">{{c}}</td>
      </tr>
    </tbody>

  </table>

</div>

Другие вопросы по тегам