注意啦!!!!学习本例demo的前提是你已经熟悉了vue语法
该demo用到了vue中的组件思想和各种指令,比如v-for、v-bind、v-on等等
该demo需要注意的地方有:
①任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域,为了把迭代数据传递到组件里,我们要用 props选项
②对于Vue2.2.0+的版本,当在组件中使用 v-for 时,必须同时使用key 属性。
③关联组件时可以使用 is="todo-item" 属性,这种做法在使用 DOM 模板时是十分必要的,虽然实现的效果与 使用 <todo-item> 相同,但是可以避开一些潜在的浏览器解析错误。
④不自动将 todo.title 注入到组件里的原因是,这会使得组件与 v-for 的运作紧密耦合
下面就是 todo-list 的完整代码:
index.html文件:
<html>
<head>
<title>vue demo</title>
<!-- 引入vue,这样Vue就被声明为全局变量 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<!-- 引入外部css文件 -->
<link href="index.css" rel="stylesheet">
</head>
<body>
<div id="v-for-component">
<!-- form表单提交时其本身的默认行为被阻止,而是去执行addNewTodo()函数 -->
<form @submit.prevent="addNewTodo">
<label for="new-todo">add new todo</label>
<!-- 表单输入绑定newTodoText数据 -->
<input type="text" id="new-todo" v-model="newTodoText" placeholder="eg.water the flower">
<button>Add</button>
</form>
<ul>
<!-- 列表项使用"todo-list"组件,同时绑定唯一标识节点的key属性、自定义属性title、remove事件移除当前节点 -->
<li is="todo-list"
v-for="(todo,index) in todos"
:key="todo.id"
:title="todo.title"
@remove="todos.splice(index,1)">
</li>
</ul>
</div>
<!-- 引入的外部js文件必须放在页面最后,否则会报错 -->
<script src="index.js"></script>
</body>
</html>
index.js文件:
//创建一个组件,包括组件名称、HTML模板、自定义属性
Vue.component("todo-list",{//将 Remove按钮 用实例方法$emit()绑定 remove事件
template:`<li> {{ title }} <button @click="$emit('remove')">Remove</button></li>`,
//用props字段将绑定数据传递到组件中,因为组件有自己的作用域
props: ["title"]
});
// 创建一个Vue实例
var vm = new Vue({
el: "#v-for-component",
data: {
newTodoText:"",
todos:[
{id:1,title:"sweep the floor"},
{id:2,title:"do the dishes"},
{id:3,title:"read the book"}
],
nextTodoId:4
},
methods:{
// 在todos数组中追加新的元素,同时依赖该数组的DOM列表也会自动响应添加新的项
addNewTodo: function(){
this.todos.push({
id:this.nextTodoId++, //让序号自动递增
title:this.newTodoText
});
this.newTodoText=""; //将文本框输入的文本清空
}
}
});
初始渲染效果:
在文本框中输入新的todo项,点击“Add”按钮后就会被添加到无序列表中
然后单击第一项的“Remove”按钮,就可以将第一项删除,如下图所示