使用Lodash重构Vue方法?

时间:2018-03-05 22:33:01

标签: javascript vue.js refactoring lodash

我的一个Vue组件中的watch prop中有一些逻辑,按下向下箭头键(键代码40)后按顺序在元素之间切换。它不是完全混乱,但是长期它会变得非常低效。继承人的结构:

data () {
 return {
  firstElActive: true,
  secondElActive: false,
  thirdElActive: false
  ...
 }

},

props: {
 nextEl: {
  type: Boolean,
  default: false,
  required: true
 }
},

watch: {
 nextEl: function (value) {
  if (this.nextEl) {
   if (this.firstElActive) {
    this.firstElActive = !this.firstElActive;
    this.secondElActive = !this.secondElActive;
    ... // other specific logic
   }
   else if (this.secondElActive) {
    this.secondElActive = !this.secondElActive;
    this.thirdElActive = !this.thirdElActive;
    ... // other specific logic
   }
   ... // so forth
  }
 }
}

正如你可能会评估的那样,这将非常糟糕,非常快。我有 Lodash 全局引导(window._ = require('lodash')),并希望利用它......我只是陷入困境,哪种方法可以最有效地重构。建议?

1 个答案:

答案 0 :(得分:1)

使用活动索引而不是使用许多布尔数据属性。在上升或下降时递增或递减此活动索引。

new Vue({
  name: 'example',

  data() {
    return {
      items: [
        { id: 0, value: 'item 1'}, 
        { id: 1, value: 'item 2'}, 
        { id: 2, value: 'item 3'},
      ],
      activeIndex: 0,
      arrowUpKeyCode: 38,
      arrowDownKeyCode: 40,
    };
  },

  computed: {
    currentItem() {
      return this.items[this.activeIndex];
    },
  },

  methods: {
    bindEvents() {
      document.addEventListener('keydown', this.onKeyDown);
    },

    unbindEvents() {
      document.removeEventListener('keydown', this.onKeyDown);
    },

    onPrev() {
      console.log(`on prev (key code ${this.arrowUpKeyCode}) ${this.currentItem.value}`);
    },

    onNext() {
      console.log(`on next (key code ${this.arrowDownKeyCode}) ${this.currentItem.value}`);
    },

    goPrev() {
      if (this.activeIndex > 0) {
        this.activeIndex -= 1;
        this.onPrev();
      }
    },

    goNext() {
      if (this.activeIndex < this.items.length - 1) {
        this.activeIndex += 1;
        this.onNext();
      }
    },

    onKeyDown(ev) {
      if (this.arrowUpKeyCode === ev.keyCode) this.goPrev();
      else if (this.arrowDownKeyCode === ev.keyCode) this.goNext();
    },
  },

  mounted() {
    this.bindEvents();
  },

  beforeDestroy() {
    this.unbindEvents();
  },
}).$mount('#example');
.active { background-color: dodgerblue; }
<script src="https://unpkg.com/vue@2.5.13/dist/vue.js"></script>

<div id="example">
  <ul>
    <li v-for="(item, index) in items" 
        :key="item.id" 
        :class="{ active: index === activeIndex }">
      {{ item.value }}
    </li>
  </ul>
</div>