这一点以前可能已经回答过,但我一直无法找到在这种具体情况下有效的答案。
我是Vue的新手,我尝试构建一个Todo列表,在这个列表中,我可以在列表项完成时单击它,更改或添加一个将改变项目样式的类。
我想我并不完全理解主Vue和组件之间的作用域是如何一起工作的。我现在的代码什么也没做。我尝试过在主组件和组件之间移动方法,但是它总是给我带来一些错误。
我想我只是在寻求一些关于该如何做的指导。
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.id + 1 }}. {{ todo.text }}</li>'
})
var app = new Vue({
el: '#app',
data: {
isDone: false,
todos: [
{ id: 0, text: 'This is an item to do today' },
{ id: 1, text: 'This is an item to do today' },
{ id: 2, text: 'This is an item to do today' },
{ id: 3, text: 'This is an item to do today' },
{ id: 4, text: 'This is an item to do today' },
{ id: 5, text: 'This is an item to do today' }
]
},
methods: {
markDone: function(todo) {
console.log(todo)
this.isDone = true
}
}
})<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<div class="content">
<ul class="flex">
<todo-item
v-for="todo in todos"
:todo="todo"
:key="todo.id"
@click="markDone"
:class="{'done': isDone}"
></todo-item>
</ul>
</div>
</div>
谢谢你的帮助伙计们。
发布于 2018-07-25 04:43:17
你离我太近了!你只是把你的:class="{'done': isDone}" @click="markDone"放错地方了!
使用组件时要记住的重要一点是,每个组件都必须有自己的数据。在您的示例中,您将所有的todo绑定到您的根Vue实例的done变量,您希望将每个done变量绑定到它们自己的数据中的done变量。
这样做的方法是创建一个函数版本的data,该版本返回每个组件的单个数据。看起来是这样的:
data () {
return {
isDone: false,
}
},然后将:class="{'done': isDone}从todo移动到li内部:
<li :class="{'done': isDone}">{{ todo.id + 1 }}. {{ todo.text }}</li>现在我们有了“完成”类,这取决于每个todo元素的单个数据块。我们现在所要做的就是能够把它标记成完整的。因此,我们还希望每个todo组件都有自己的方法。将methods:对象添加到todo组件中,并将markDone方法移到那里:
methods: {
markDone() {
this.isDone = true;
},
}现在,将@click="markDone"移动到li:
<li :class="{'done': isDone}" @click="markDone">{{ todo.id + 1 }}. {{ todo.text }}</li>你就这样吧!现在,您应该能够创建任意数量的todo,并标记它们全部完成!
奖金:
考虑将您的函数更改为toggleDone() { this.isDone = !this.isDone; },这样您就可以在已完成和未完成之间来回切换它们!
(完整代码如下:)
Vue.component('todo-item', {
props: ['todo'],
template: `<li :class="{'done': isDone}" @click="toggleDone">{{ todo.id + 1 }}. {{ todo.text }}</li>`,
data () {
return {
isDone: false,
}
},
methods: {
toggleDone() {
this.isDone = !this.isDone;
},
}
})
var app = new Vue({
el: '#app',
data: {
isDone: false,
todos: [
{ id: 0, text: 'This is an item to do today' },
{ id: 1, text: 'This is an item to do today' },
{ id: 2, text: 'This is an item to do today' },
{ id: 3, text: 'This is an item to do today' },
{ id: 4, text: 'This is an item to do today' },
{ id: 5, text: 'This is an item to do today' }
]
},
methods: {
markDone: function(todo) {
console.log(todo)
this.isDone = true
}
}
}).done {
text-decoration: line-through;
}<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<div class="content">
<ul class="flex">
<todo-item
v-for="todo in todos"
:todo="todo"
:key="todo.id"
></todo-item>
</ul>
</div>
</div>
发布于 2018-07-25 00:13:51
在您的代码中,处理单击事件的是<li>元素,但是您试图在组件的根目录中处理它,有几种方法可以解决这个问题
使用本机修饰符
<todo-item
v-for="todo in todos"
:todo="todo"
:key="todo.id"
@click.native="markDone"
:class="{'done': isDone}"
>
</todo-item>您可以在这里找到更多信息,https://v2.vuejs.org/v2/guide/migration.html#Listening-for-Native-Events-on-Components-with-v-on-changed。
从组件发出单击事件
Vue.component('todo-item', {
props: ['todo'],
template: '<li @click="click()">{{ todo.id + 1 }}. {{ todo.text }}</li>',
methods: {
click () {
this.$emit('click')
}
}
})顺便说一句,在您当前的代码中,一旦您单击一个todo,所有todo都将被“标记为已完成”,因为您只对它们使用了一个变量。
发布于 2018-07-25 04:31:47
首先,当您将一个项目标记为已完成时,当前实现将影响列表中的所有项,因为您要将单个isDone属性关联到所有项,并且当该属性变为真时,它将应用于列表中的所有项。
因此,要解决这个问题,您需要找到一种将done与每个项相关联的方法。因为您的项是object,所以只需动态分配一个新属性done并将值设置为true,这意味着它被标记为已完成。仅仅解释它将非常混乱,所以我使用您现有的代码提供了一个完整的示例。
参见这个JS Fiddle:https://jsfiddle.net/eywraw8t/205021/
https://stackoverflow.com/questions/51508485
复制相似问题