列表功能举例
步骤 1:列表功能
完整的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .table { width: 800px; margin: 20px auto; border-collapse: collapse; }
.table th { background: #0094ff; color: white; font-size: 16px; border: 1px solid black; padding: 5px;
}
.table tr td { text-align: center; font-size: 16px; padding: 5px; border: 1px solid black; } </style>
<script src="vue2.5.16.js"></script> </head>
<body>
<div id="app">
<table class="table"> <th>编号</th> <th>名称</th> <th>创建时间</th> <th>操作</th> <tr v-for="item in list"> <td>{{item.id}}</td> <td>{{item.name}}</td> <td>{{item.ctime}}</td> <td><a href="#">删除</a></td> </tr> </table> </div>
</body>
<script> var vm = new Vue({ el: '#app', data: { list: [{id: 1, name: '奔驰', ctime: new Date}, {id: 2, name: '大众', ctime: new Date}] } })
</script>
</html>
|
代码分析:数据是存放在data的list中的,将data中的数据通过v-for
遍历给表格。
上方代码运行的效果:
步骤 2:无数据时,增加提示
如果list中没有数据,那么表格中就会只显示表头<th>
,这样显然不太好看。
为此,我们需要增加一个v-if
判断:当数据为空时,显示提示。如下:
1 2 3
| <tr v-show="list.length == 0"> <td colspan="4">列表无数据</td> </tr>
|
代码解释:colspan="4"
指的是让当前这个<td>
横跨4个单元格的位置。如下:
步骤 3:item的添加
具体实现步骤如下:
(1)用户填写的数据单独存放在data属性里,并采用v-model
进行双向绑定。
(2)用户把数据填好后,点击add按钮。此时需要增加一个点击事件的方法,将data中的数据放到list中(同时,清空文本框中的内容)。
(3)将数据展示出来。v-for
有个特点:当list数组发生改变后,vue.js就会自动调用v-for
重新将数据生成,这样的话,就实现了数据的自动刷新。
完整的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .table { width: 800px; margin: 20px auto; border-collapse: collapse; }
.table th { background: #0094ff; color: white; font-size: 16px; border: 1px solid black; padding: 5px; }
.table tr td { text-align: center; font-size: 16px; padding: 5px; border: 1px solid black; }
.form { width: 800px; margin: 20px auto; }
.form button { margin-left: 10px; } </style>
<script src="vue2.5.16.js"></script> </head>
<body>
<div id="app">
<div class="form">
编号:<input type="text" v-model="formData.id"> 名称:<input type="text" v-model="formData.name">
<button v-on:click="addData">添加</button> </div>
<table class="table"> <th>编号</th> <th>名称</th> <th>创建时间</th> <th>操作</th> <tr v-show="list.length == 0"> <td colspan="4">列表无数据</td> </tr> <tr v-for="item in list"> <td>{{item.id}}</td> <td>{{item.name}}</td> <td>{{item.ctime}}</td> <td><a href="#">删除</a></td> </tr> </table> </div>
</body>
<script> var vm = new Vue({ el: '#app', data: { list: [{id: 1, name: '奔驰', ctime: new Date}, {id: 2, name: '大众', ctime: new Date}], formData: { id: 0, name: "" } },
methods: { addData: function () { var p = {id: this.formData.id, name: this.formData.name, ctime: new Date()}; this.list.push(p);
this.formData.id = 0; this.formData.name = ''; } } });
</script>
</html>
|
步骤 4:item的删除
html部分:
1 2
| <td><a href="#" v-on:click="delData(item.id)">删除</a></td>
|
js部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| delData: function (id) { if (!confirm('是否要删除数据?')) { return; }
var index = this.list.findIndex(function (item) { return item.id == id });
this.list.splice(index, 1); }
|
代码解释:find()
和findIndex()
是ES6中为数组新增的函数。详细解释如下:
1 2 3 4 5 6 7 8
|
var index = this.list.findIndex(function(item){
return item.id ==id; });
|
也就是说,我们是根据 item.id 找到这个 item 是属于list 数组中的哪个index索引。找到了index,就可以根据index来删除数组中的那个元素了。
当item被删除后,v-for会被自动调用,进而自动更新view。
完整版代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .table { width: 800px; margin: 20px auto; border-collapse: collapse; }
.table th { background: #0094ff; color: white; font-size: 16px; border: 1px solid black; padding: 5px; }
.table tr td { text-align: center; font-size: 16px; padding: 5px; border: 1px solid black; }
.form { width: 800px; margin: 20px auto; }
.form button { margin-left: 10px; } </style>
<script src="vue2.5.16.js"></script> </head>
<body>
<div id="app">
<div class="form">
编号: <input type="text" v-model="formData.id"> 名称: <input type="text" v-model="formData.name">
<button v-on:click="addData">添加</button> </div>
<table class="table"> <th>编号</th> <th>名称</th> <th>创建时间</th> <th>操作</th> <tr v-show="list.length == 0"> <td colspan="4">列表无数据</td> </tr> <tr v-for="item in list"> <td>{{item.id}}</td> <td>{{item.name}}</td> <td>{{item.ctime}}</td> <td> <a href="#" v-on:click="delData(item.id)">删除</a> </td> </tr> </table> </div>
</body>
<script> var vm = new Vue({ el: '#app', data: { list: [{ id: 1, name: '奔驰', ctime: new Date }, { id: 2, name: '大众', ctime: new Date }], formData: { id: 0, name: "" } },
methods: { addData: function () { var p = { id: this.formData.id, name: this.formData.name, ctime: new Date() }; this.list.push(p);
this.formData.id = 0; this.formData.name = ''; },
delData: function (id) { if (!confirm('是否要删除数据?')) { return; }
var index = this.list.findIndex(function (item) { return item.id == id });
this.list.splice(index, 1); }
} });
</script>
</html>
|
步骤 5:按条件筛选item
现在要求实现的效果是,在搜索框输入关键字 keywords,列表中仅显示匹配出来的内容。也就是说:
在 search(keywords) 方法中,为了获取 list 数组中匹配的item,我们可以有两种方式实现。如下。
方式一:采用forEach + indexOf()
1 2 3 4 5 6 7 8 9 10 11
| search(keywords) {
var newList = []; this.list.forEach(item => { if (item.name.indexOf(keywords) != -1) { newList.push(item) } }) return newList }
|
上方代码中, 我们要注意 indexOf(str) 的用法。举例如下:
1 2 3 4 5 6 7 8 9
| var str = 'smyhvae';
console.log(str.indexOf('s'));
console.log(str.indexOf(''));
console.log(str.indexOf('h'));
console.log(str.indexOf('x'));
|
上方代码中,也就是说,如果参数为空字符串,那么,每个item都能匹配到。
方式二: filter + includes()方法
1 2 3 4 5 6 7 8 9 10 11 12
| search(keywords) {
var newList = this.list.filter(item => { if (item.name.includes(keywords)) { return item } })
return newList }
|
注意:forEach some filter findIndex,这些都属于数组的新方法,都会对数组中的每一项,进行遍历,执行相关的操作。这里我们采用数组中的 filter 方法,
总的来说,方式二的写法更优雅,因为字符串的 includes()方法确实很实用。
完整版代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .table { width: 800px; margin: 20px auto; border-collapse: collapse; }
.table th { background: #0094ff; color: white; font-size: 16px; border: 1px solid black; padding: 5px; }
.table tr td { text-align: center; font-size: 16px; padding: 5px; border: 1px solid black; }
.form { width: 800px; margin: 20px auto; }
.form button { margin-left: 10px; } </style>
<script src="vue2.5.16.js"></script> </head>
<body>
<div id="app">
<div class="form">
编号: <input type="text" v-model="formData.id"> 名称: <input type="text" v-model="formData.name">
<button v-on:click="addData">添加</button> 搜索: <input type="text" v-model="keywords">
</div>
<table class="table"> <th>编号</th> <th>名称</th> <th>创建时间</th> <th>操作</th> <tr v-show="list.length == 0"> <td colspan="4">列表无数据</td> </tr> <tr v-for="item in search(keywords)"> <td>{{item.id}}</td> <td>{{item.name}}</td> <td>{{item.ctime}}</td> <td> <a href="#" v-on:click="delData(item.id)">删除</a> </td> </tr> </table> </div>
</body>
<script> var vm = new Vue({ el: '#app', data: { list: [{ id: 1, name: '奔驰', ctime: new Date }, { id: 2, name: '大众', ctime: new Date }], formData: { id: '', name: "" }, keywords: "" },
methods: { addData: function () { var p = { id: this.formData.id, name: this.formData.name, ctime: new Date() }; this.list.push(p);
this.formData.id = ''; this.formData.name = ''; },
delData: function (id) { if (!confirm('是否要删除数据?')) { return; }
var index = this.list.findIndex(function (item) { return item.id == id });
this.list.splice(index, 1); },
search(keywords) {
var newList = this.list.filter(item => { if (item.name.includes(keywords)) { return item } })
return newList } } });
</script>
</html>
|
备注:在1.x 版本中可以通过filterBy指令来实现过滤,但是在2.x中已经被废弃了。