问题描述
我是Vue.JS的新手。我试图实现两个书籍列表(已读和未读),书籍列表是一个共享对象(处于全局数据状态)。
这是我的解决方案-working demo(有效!,但我想问自己这是一个好习惯吗,我有一些问题,也许您可以帮忙澄清一下)
HTML:
<div id="root">
<h2>Books pending to read</h2>
<ul>
<book-li
v-for="book of notReadedBooks"
:key="book.id"
:book="book.title"
:status="book.readed"
@changeit="changeStatus(book.id)">
</book-li>
</ul>
<h2>Readed books</h2>
<ul>
<book-li
v-for="book of readedBooks"
:key="book.id"
:book="book.title"
:status="book.readed"
@changeit="changeStatus(book.id)">
</book-li>
</ul>
</div>
javascript:
Vue.component('book-li',{
props: [ 'book','status' ],template: `
<li>
{{ book }} – <button @click="$emit('changeit')"> {{status ? 'will reread' : 'readed'}} </button>
</li>
`
})
const App = new Vue({
el: '#root',data: {
allBooks: [
{ title: 'El Aleph',id: 101,readed: true },{ title: 'Ficciones',id: 102,readed: false },{ title: 'La torre de Babel',id: 103,]
},computed: {
readedBooks: function() { return this.allBooks.filter( singleBook => singleBook.readed )},notReadedBooks: function() { return this.allBooks.filter( singleBook => ! singleBook.readed )},},methods: {
changeStatus(idCurrentBook) {
let bookIndex = this.allBooks.findIndex(book => book.id === idCurrentBook)
this.allBooks[bookIndex].readed = ! this.allBooks[bookIndex].readed
}
}
})
如您所见,我遍历了2个计算出的列表(已读和未读),但是我试图以一种更好的方式呈现它。例如:
1-我无法将整个已读/未读列表传递给组件,然后使用内部v-for
循环定义一个组件。
类似<book-list :list="readedBooks"></book-list>
然后在该组件内部使用v-for
道具做一个list
。在Vue上可能发生这种情况,还是应该在组件外部进行循环?
2-我发现的另一个问题是,如果我将:book
属性绑定重命名为:book-title
,则Vue告诉我我需要定义一个:book
属性,即使我不使用(?)。
在此先感谢您的帮助!
编辑:
感谢@ luca-faggianelli给我一些见识。
我设法在内部创建一个v-for
循环,因此可以大大简化代码:
<div id="root">
<h2>Books pending to read</h2>
<books :list="notReadedBooks"></books>
<h2>Readed books</h2>
<books :list="readedBooks"></books>
</div>
Vue.component('books',{
props: [ 'list' ],template: `
<ul>
<li v-for="book in list">
{{ book.title }} - <button @click="book.readed = !book.readed">{{ book.readed ? 'read again' : 'readed' }}</button>
</li>
</ul>
`
})
const App = new Vue({
el: '#root',}
})
解决方法
我建议您开始阅读有关Vue组件https://vuejs.org/v2/guide/components.html
的内容然后回答您的问题:
-
它可以创建一个
<book-list>
组件,并确保在组件内部可以有for循环 -
必须在组件声明中重命名
book
属性,即在以下位置:
Vue.component('book-li',{
props: [ 'bookTitle','status' ],
然后您可以使用:book-title
,请注意Vue希望在HTML中使用kebab-case道具,而在JS中希望使用camelCase