Vue 的双向绑定原理与用法揭秘

2020-06-16 06:51:30易采站长站整理
props
中的属性,不能直接赋值,所以采用了官方推荐的第一种方法,定义一个数据
isDone
,初始化为
this.done
,并在组件内使用
isDone
来控制是否完成这一状态。

相应的 App 部分的模板和代码精减了不少:


<div id="app">
<h2>Todos:</h2>
<ol>
<li v-for="todo in todos">
<todo :text="todo.text" :done="todo.done"></todo>
</li>
</ol>
</div>


new Vue({
el: "#app",
data: {
todos: [
{ text: "Learn JavaScript", done: false },
{ text: "Learn Vue", done: false },
{ text: "Play around in JSFiddle", done: true },
{ text: "Build something awesome", done: true }
] }
});

不过到此为止,数据仍然是单向的。从效果上来看,点击复选框可以反馈出删除线线效果,但这些动态变化都是在

todo
组件内部完成的,不存在数据绑定的问题。

为 Todo List 添加计数

为了让

todo
组件内部的状态变化能在 Todo List 中呈现出来,我们在 Todo List 中添加计数,展示已经完成的 Todo 数量。因为这个数量受
todo
组件内部状态(数据)的影响,这就需要将
todo
内部数据变化反应到其父组件中,这才有
v-model
的用武之地。

这个数量我们在标题中以

n/m
的形式呈现,比如
2/4
表示一共 4 条 Todo,已经完成 2 条。这需要对 Todo List 的模板和代码部分进行修改,添加
countDone
count
两个计算属性:


<div id="app">
<h2>Todos ({{ countDone }}/{{ count }}):</h2>
<!-- ... -->
</div>


new Vue({
// ...
computed: {
count() {
return this.todos.length;
},
countDone() {
return this.todos.filter(todo => todo.done).length;
}
}
});

现在计数呈现出来了,但是现在改变任务状态并不会对这个计数产生影响。我们要让子组件的变动对父组件的数据产生影响。

v-model
待会儿再说,先用最常见的方法,事件: