我创建了一个用于学习音乐笔记的应用。
实时示例:https://tymekb.github.io/NoteTrainer/
代码:https://github.com/TymekB/NoteTrainer
我想重构显示注释。前三个音符在第一行中,最后四个音符在第二行中。我正在用flex来做。
重构前的代码。
<template>
<div class="notes">
<div class="row">
<button :disabled="disabled" class="note-btn" v-for="note in notes.slice(0,3)" :key="note"
v-on:click="checkNote($event, note)">{{note}}
</button>
</div>
<div class="row">
<button :disabled="disabled" class="note-btn" v-for="note in notes.slice(3,notes.length)" :key="note"
v-on:click="checkNote($event, note)">{{note}}
</button>
</div>
</div>
</template>
<style scoped>
.row {
display: flex;
justify-content: space-between;
}
</style>
之后。我尝试过这样的事情。由于索引从1开始,因此每次都会递减。你怎么看?有没有更有效的方法来做这种事情?
<template>
<div class="notes">
<div class="row" v-for="i in 2" :key="i">
<button class="note-btn note-btn-default"
v-for="note in notes.slice((i-1)*3, Math.floor(notes.length / (2-(i-1))))" :key="note"
v-on:click="checkNote($event, note)">{{note}}
</button>
</div>
</div>
</template>
<style scoped>
.row {
display: flex;
justify-content: space-between;
}
</style>
答案 0 :(得分:1)
如果您想重构,我想您可以将行写入这样的组件中
<template>
<div>
<button class="note-btn note-btn-default" v-for="note in notes" >{{note}}</button>
</div>
</template>
<script>
export default{
props:['notes']
}
</script>
然后像在html中一样使用该组件。
<note-btn :notes="notes"></note-btn>
答案 1 :(得分:1)
尝试使用CSS网格作为行的显示,然后使用grid-row-start
根据注释索引:class="
$ {index <3?' ':'second-row'} "
let app = new Vue({
el: '#app',
data: {
notes: ['A', 'B', 'C', 'D', 'E', 'F', 'G']
}
})
.row {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: auto auto;
}
.first-row {
grid-row-start: 1;
}
.second-row {
grid-row-start: 2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="row">
<button v-for="(note,index) in notes" :class="`${index<3?'first-row':'second-row'}`" :key="note">{{note}}
</button>
</div>
</div>
答案 2 :(得分:1)
通过CSS和flex
,您可以使用justify-content
并在第二个按键笔记按钮上增加或设置更大的margin
,然后包装按键。
想法演示:
body {
margin: 0;
}
article {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
div {
box-sizing: border-box;
border: solid;
padding: 1em;
margin: 1em 1vw 0;
width: 20%;
}
div:nth-child(2) {
margin: 1em 10% 0;
}
/* demo purpose */
div {
text-align: center;
}
div:nth-child(1) {
counter-reset: div 2;
}
div {
counter-increment: div;
}
div:nth-child(6) {
counter-reset: div;
}
div::before {
content: counters(div, ".", upper-alpha);
}
<article>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</article>
答案 3 :(得分:1)
在考虑代码质量时,有几个标准在起作用,并且根据代码的预期目的,它们的重要性可能有所不同:
如您所见,许多度量标准相互重叠,并且大多数收敛于同一点。
尽管在现代团队中,模块化和可测试性通常被视为较高的值,但很少对程序员的代码质量进行实际测试,并且只有在考虑将其视为公司职位时才会发生这种情况。有趣的是,在这样的审查中,代码的可读性通常是最高的优点,因为它使代码审查更加容易。
就您的特定代码段而言,这里唯一真正的问题是,是否将所有按钮都作为同一父级的子级,还是将它们分成两个父级行。考虑到彼此的位置(您希望它们在所有响应间隔中都处于相同的位置),理想的结果应该是将它们分配给两个父母。
该选择的另一个论点是,为了在它们是同一父代的子代时按需要显示它们,必须将显示逻辑从JavaScript移到CSS,并且因为您拥有大量精通JavaScript的开发人员比那些精通CSS的人更应该使用JavaScript逻辑。
以上所述,下面是一个示例,该示例如何编写上面的代码片段以通过高级编码公司中最严格的代码审查:
Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: () => ({
notes: ['A', 'B', 'C', 'D', 'E', 'F', 'G']
}),
computed: {
noteRows() {
return [
[2, 3, 4],
[5, 6, 0, 1]
].map(row => row.map(i => this.notes[i]))
}
},
methods: {
checkNote(note) {
console.log(note);
}
}
})
.row {
display: flex;
justify-content: space-between;
}
/* button styling, not really part of the solution */
.row button {
background-color: white;
border: 1px solid #CCC;
padding: .75em;
margin: .75em;
min-width: 16.67%;
border-radius: .25em;
cursor: pointer
}
.row button:hover {
border-color: #888;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="row" v-for="(row, key) in noteRows" :key="key">
<button v-for="note in row"
:key="note"
v-text="note"
@click="checkNote(note)" />
</div>
</div>
明显的优点是:
noteRows
移动到帮助文件或mixin中,然后将其导入多个组件中)如果不清楚如何在多个组件之间重用以上代码,请按照以下步骤操作:
Vue.config.devtools = false;
Vue.config.productionTip = false;
Vue.use({
install(Vue) {
Vue.prototype.$notes = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
}
});
const noteRows = {
computed: {
noteRows() {
return [
[2, 3, 4],
[5, 6, 0, 1]
].map(row => row.map(i => this.$notes[i]))
}
}
};
// now $notes exists in any component
// and noteRows needs to be (imported and) specified as mixin
new Vue({
el: '#app',
mixins: [noteRows],
methods: {
checkNote(note) {
console.log(note);
}
}
})
.row {
display: flex;
justify-content: space-between;
}
/* button styling, not really part of the solution */
.row button {
background-color: white;
border: 1px solid #CCC;
padding: .75em;
margin: .75em;
min-width: 16.67%;
border-radius: .25em;
cursor: pointer
}
.row button:hover {
border-color: #888;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="row" v-for="(row, key) in noteRows" :key="key">
<button v-for="note in row" :key="note" v-text="note" @click="checkNote(note)" />
</div>
</div>
如果除了$notes
之外,不需要原型上的noteRows
,我将其移入mixin。不是作为data()
,而是作为computed
(它不需要是被动的),因此那里的性能有较小的提高。强调未成年人。