javascript - Vue.js - 全局共享状态和组件外的 for 循环 - 这是一个好习惯吗?
问题描述
我是 Vue.JS 的新手。我试图实现两个书籍列表(已阅读和未阅读),书籍列表是共享对象(在全局数据状态下)。
这是我的解决方案 -工作演示(它有效!但我问自己这是否被认为是一种好的做法,我有一些问题,也许你可以帮助澄清)
的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, readed: false },
]
},
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',
data: {
allBooks: [
{ title: 'El Aleph', id: 101, readed: true },
{ title: 'Ficciones', id: 102, readed: false },
{ title: 'La torre de Babel', id: 103, readed: false },
]
},
computed: {
readedBooks: function() { return this.allBooks.filter( singleBook => singleBook.readed )},
notReadedBooks: function() { return this.allBooks.filter( singleBook => ! singleBook.readed )},
}
})
解决方案
我建议您开始阅读有关 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
推荐阅读
- xamarin - 如何将特定于平台的文件添加到 NuGet 包?
- android - 导入 lint.xm 以在 Android Studio 中进行检查
- python - 如何在同一个包的方法中调用函数
- php - SQL 无法登录
- javascript - 制作多语言网站的最佳方式是什么?
- git - GIT 中的错误配置选项(AllowUsers)
- python - 返回 groupby pandas 之后的所有行(即不是减少的行数,即组键的唯一值)
- ruby - Ruby Yard 文档:如何添加“逐字”(生成类似
标签)
- node.js - Nodejs > Gulp > through2 > 限制为 16 个文件?
- angular - Angular - 在另一个组件中动态注入一个组件