使用Vue.js实现TodoList
1.实现通过input框向正在进行的列表值中增加列表项内容并完成提交功能
①在视图层实现简单的布局。(了解)
<div id="app">
<input type="text"/>
<button>提交</button>
<ul>
<li>first text</li>
<li>second text</li>
</ul>
</div>
②在逻辑层实现简单的布局。
<div>
...
<ul>
<li v-for="item in list">{{item}}</li>
</ul>
...
</div>
<script>
var app = new Vue({ //创建Vue的实例
el: '#app', //传一个对象选择接管dom的局域
data: { //指Vue里的具体数据
list: ['first text', 'second text']
}
})
</script>
tip:运行结果同上
知识点:v-for = “item in list”,即告诉Vue要去循环list的数据,且循环的每一项放入item中,所以使用{{item}}。
③在逻辑层实现在input输入数据,点击“提交”按钮可把数据送到下面的列表。
<!--实现数据获取的打印-->
<div>
<input type="text" v-model="inputValue"/>
<button v-on:click="handleBtnClick">提交</button>
...
</div>
<script>
var app = new Vue({ //创建Vue的实例
el: '#app', //传一个对象选择接管dom的局域
data: { //指Vue里的具体数据
list: [],
inputValue: ''
},
//在button标签中定义好函数后需要在方法中定义handleBtnClick方法(在Vue实例中)
methods: {
handleBtnClick: function(){
alert(this.inputValue) //自动寻找inputValue
}
}
})
</script>
<!--实现在input输入数据,点击“提交”按钮可把数据送到下面的列表-->
methods: {
handleBtnClick: function(){
this.list.push(this.inputValue) //往list里增加内容
}
}
通过运行结果可以发现数据传递后,input输入框没有置空,需要增加如下代码。
<!--实现input框在每次传送完数据后自动置空-->
methods: {
handleBtnClick: function(){
this.list.push(this.inputValue) //往list里增加内容
this.inputValue = '' //时input框置空
}
}
知识点:(1)v-on:click=“函数名”,等价于@click=“函数名”,即在button标签实现绑定点击事件。当点击button标签时,则触发method里相应的方法。(2) v-model="",指数据的双向传值/绑定,同时变化,即在input中输入数据时,Vue实例中的data里的inputValue就会发生变化;同样,当Vue实例中的inputValue这个变量发生变化时,页面也会跟着发生变化(在控制台输入app.$data.inputValue=“要修改的数据”)。
④小结:以上模式称为MVVM设计模式,其中M为Vue层,V和VM为dom层。
使用组件化修改TodoList
1.拆分组件
上面的 li 标签是通过循环显示,下面把 li 标签里的内容整体变成一个组件。步骤如下:
①在Vue中创建全局组件(子组件无需调用即可使用)。
<script>
//调用component方法,用Vue提供创建全局组件的方法
Vue.component("TodoItem", { //则dom层命名为todo-item(子组件)
template: "<li>todo item</li>" //运行时,无论输入什么,输出都是todo item
})
...
</script>
②在v-for="item in list"中list每次循环的值都先赋值给item,接着item通过v-bind:内的值传给(子组件),本例子通过content来传值。
<div>
...
<ul>
<todo-item v-bind:content="item"
v-for="item in list">
</todo-item>
</ul
</div>
③子组件接收内容:通过props把父组件接收到的内容传给子组件,实现子组件接收list的值,接着更改template里 li 标签的内容。
<script>
Vue.component("TodoItem", { //则dom层命名为todo-item(子组件)
props: ['content'],
template: "<li>{{content}}</li>" //使用插值表达式
})
...
</script>
知识点:(1)v-bind:简写“ : ",向子组件传入绑定值;(2)props:指从父组件接收的内容,然后传给子组件
④在Vue中创建局部组件。
<script>
//创建局部组件
var TodoItem = {
props: ['content'],
template: "<li>{{content}}</li>"
}
var app = new Vue({ //创建Vue的实例
el: '#app',
components: { //需要把局部组件注册(通过对象注册)到Vue实例里
TodoItem: TodoItem
},
...
</script>
tip:运行结果同上
2.简单的组件间传值
本例实现打印出来的列表,点击相应的列表数据可自动删除数据。
①尽可能不动dom,在Vue中给子组件的 li 标签绑定@click事件。
<script>
var TodoItem = {
props: ['content'],
template: "<li @click='handleItemClick'>{{content}}</li>",
methods: { //绑定好事件后需要定义该方法
handleItemClick: function() {
alert("click")
}
}
}
...
</script>
点击two/one,click输出,则说明绑定事件成功。
②子组件向父组件传值.$emit()向外触发事件,接着在子组件监听delete事件,最后在数据的方法中定义该事件的方法。
<div>
...
<todo-item v-bind:content="item"
v-for="item in list"
@delete="handleItemClick"> //绑定事件
</todo-item>
...
</div>
<script>
var TodoItem = {
props: ['content'],
template: "<li @click='handleItemClick'>{{content}}</li>",
methods: { //绑定好事件后需要定义该方法
handleItemClick: function() {
this.$emit("delete"); //向外触发事件
}
}
}
var app = new Vue({ //创建Vue的实例
el: '#app',
components: { //需要把局部组件注册(通过对象注册)到Vue实例里
TodoItem: TodoItem
},
...
methods:{
handleItemClick: function() { //定义handleItemClick方法
alert("delete");
}
}
})
</script>
③让父组件改变list,即等于空数组。
在Vue方法中的handleItemDelete点击事件方法中添加 “this.list = []”,运行后输入多个数据,任意点击某条数据,内容全部被清空。
④实现点击某条数据,只删除该数据,且下标号发生相应的变化。完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TodoList</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="inputValue"/>
<button v-on:click="handleBtnClick">提交</button>
<ul>
<todo-item :content="item"
:index="index" //绑定下标
v-for="(item, index) in list" //组合循环
@delete="handleItemDelete">
</todo-item>
</ul>
</div>
<script>
var TodoItem = {
props: ['content', 'index'], //接收子组件
template: "<li @click='handleItemClick'>{{content}}</li>",
methods: { //绑定好事件后需要定义该方法
handleItemClick: function() {
this.$emit("delete", this.index); //向外触发事件,子组件向父组件传值
}
}
}
var app = new Vue({ //创建Vue的实例
el: '#app',
components: { //需要把局部组件注册(通过对象注册)到Vue实例里
TodoItem: TodoItem
},
data: { //指Vue里的具体数据
list: [],
inputValue: ''
},
//在button标签中定义好函数后需要在方法中定义handleBtnClick方法(在Vue实例中)
methods: {
handleBtnClick: function(){
this.list.push(this.inputValue) //往list里增加内容
this.inputValue = '' //时input框置空
},
handleItemDelete: function(index) { //定义handleItemClick方法,接收index的值
//alert(index);
this.list.splice(index, 1) //删除一项数据
}
}
})
</script>
</body>
</html>
输入数据1~5:
删除数字3的内容:
删除数字4的内容:
拓展
1.v-for:绑定数组的数据来渲染一个项目列表。
<div id="app">
<ul>
<li v-for="item in list">
{{ item.text }}
</li>
</ul>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
list: [
{ text: '第一天学习' },
{ text: '第二天学习' },
{ text: '第三天学习' }
]
}
})
</script>
tip:学习内容来自慕课网