我的一个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')
),并希望利用它......我只是陷入困境,哪种方法可以最有效地重构。建议?
答案 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>