Vue 学习总结笔记 (七)
<div class="operating">
<a class="href-article-edit slide-toggle">版权</a>
</div>
</div>
</div>
</div>
<div id="blogColumnPayAdvert">
<div class="column-group">
<div class="column-group-item column-group0 column-group-item-one">
<div class="item-l">
<a class="item-target" href="https://blog.csdn.net/it_holmes/category_11899711.html" target="_blank" title="Vue 全家桶" data-report-click="{"spm":"1001.2101.3001.6332"}">
<img class="item-target" src="https://img-blog.csdnimg.cn/b3f6cc316bf34861ba4e5d84c6f8f0ff.jpeg?x-oss-process=image/resize,m_fixed,h_224,w_224" alt="">
<span class="title item-target">
<span>
<span class="tit">Vue 全家桶</span>
<span class="dec">专栏收录该内容</span>
</span>
</span>
</a>
</div>
<div class="item-m">
<span>14 篇文章</span>
<span>5 订阅</span>
</div>
<div class="item-r">
<a class="item-target article-column-bt articleColumnFreeBt" data-id="11899711">订阅专栏</a>
</div>
</div>
</div>
</div>
<article class="baidu_pl">
<div id="article_content" class="article_content clearfix">
<link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/kdoc_html_views-1a98987dfd.css">
<link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/ck_htmledit_views-6e43165c0a.css">
<div id="content_views" class="markdown_views prism-tomorrow-night">
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
</svg>
<p></p>
1. 浏览器本地存储
1.1 浏览器本地存储
浏览器的本地存储:
- Local Storage
- SessionStorage
可以在浏览器的开发者工具看到:

(这就是浏览器本地存储,点x号可以删除当前选中行。)
1.2 localStorage存储
localStorage的存储:

对于上面的Object,Object,我们可以通过JSON.stringify()方法来字符串化:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>localStorage</title>
</head>
<body>
<h2>localStorage的演示</h2>
<button onclick="saveData()">点我保存一个数据</button>
<button onclick="readData()">点我读取一个数据</button>
<button onclick="deleteData()">点我删除一个数据</button>
<button onclick="deleteAllData()">清空localStorage</button>
<script type="text/javascript">
function saveData(){
let p = {
name:"张三",
age:18
};
//可以window可以简写忽略
//需要注意的是这里的两个参数都必须是字符串。
window.localStorage.setItem('msg','hello,world');
//666会转成字符串形式
localStorage.setItem('msg2',666);
//如果传入的是对象,它就会显示Object纯字符串。
localStorage.setItem('person',JSON.stringify(p));
}
<span class="token keyword">function</span> <span class="token function">readData</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
<span class="token keyword">var</span> s1 <span class="token operator">=</span> localStorage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token string">"msg"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> s2 <span class="token operator">=</span> localStorage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token string">"msg2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> s3 <span class="token operator">=</span> localStorage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token string">"person"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>s1<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>s2<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>s3<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">deleteData</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
localStorage<span class="token punctuation">.</span><span class="token function">removeItem</span><span class="token punctuation">(</span><span class="token string">'msg2'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">deleteAllData</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
localStorage<span class="token punctuation">.</span><span class="token function">clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>script</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>body</span><span class="token punctuation">></span></span>
</html>
- 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
localStorage存储最大的特点就是关闭浏览器,再打开浏览器它的数据依然会存在。
localStorage中的数据什么时候会消失:
- 当用户点击了一些功能按钮,操作了remove或clear方法,会让localStorage中的数据消失。
- 当用户主动的清空浏览器的缓存时,也会导致它消失。
1.3 sessionStorage
sessionStorage中存储数据的生命周期是一个会话时期。
功能方法也都和localStorage的操作相同,唯一要注意的就是这个数据的存活时长。
1.4 总结
localStorage和sessionStorage统称为webStorage。

2. 浏览器本地存储的 todoLists案例
在我们上个todoLists案例中,加上浏览器本地存储的效果。
- 最主要的要看App.vue中todolist和watch的实现。
App.vue文件:
<template>
<div id="root">
<div class="todo-container">
<div class="todo-wrap">
<Header1 :receive="receive"></Header1>
<List1
:todoList="todoList"
:checkTodoObj="checkTodoObj"
:deleteTodoObj="deleteTodoObj"
></List1>
<Footer1 :todoList="todoList" :checkAllTodoObj="checkAllTodoObj" :clearAllTodoObj="clearAllTodoObj"></Footer1>
</div>
</div>
</div>
</template>
<script>
import Header1 from "./components/MyHeader.vue"
import Footer1 from "./components/MyFooter.vue"
import List1 from "./components/MyList.vue"
<span class="token keyword">export</span> <span class="token keyword">default</span><span class="token punctuation">{<!-- --></span>
name<span class="token punctuation">:</span><span class="token string">'App'</span><span class="token punctuation">,</span>
components<span class="token punctuation">:</span><span class="token punctuation">{<!-- --></span>
Header1<span class="token punctuation">,</span>
List1<span class="token punctuation">,</span>
Footer1<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token function">data</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
<span class="token keyword">return</span> <span class="token punctuation">{<!-- --></span>
<span class="token comment">//获取当前页面已经存储的localStorage数据。</span>
<span class="token comment">//如果localStorage.getItem('todoList')没有数据返回就返回了null,并且JSON解析出来也是null,这样就报错了!</span>
<span class="token comment">//所以我们要加一个||或,前面赋值报错就只用后面的[]空数组。</span>
todoList<span class="token punctuation">:</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>localStorage<span class="token punctuation">.</span><span class="token function">getItem</span><span class="token punctuation">(</span><span class="token string">'todoList'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
methods<span class="token punctuation">:</span><span class="token punctuation">{<!-- --></span>
<span class="token comment">//从MyHeader中获取数据,添加todoObj对象</span>
<span class="token function">receive</span><span class="token punctuation">(</span>todoObj<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
<span class="token comment">//这样将值传给添加到todoList末尾中。</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>todoList<span class="token punctuation">.</span><span class="token function">unshift</span><span class="token punctuation">(</span>todoObj<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token comment">//勾选或者取消勾选一个todo</span>
<span class="token function">checkTodoObj</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
<span class="token keyword">this</span><span class="token punctuation">.</span>todoList<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span>todoObj<span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{<!-- --></span>
<span class="token keyword">if</span><span class="token punctuation">(</span>todoObj<span class="token punctuation">.</span>id <span class="token operator">==</span> id<span class="token punctuation">)</span>
todoObj<span class="token punctuation">.</span>done <span class="token operator">=</span> <span class="token operator">!</span>todoObj<span class="token punctuation">.</span>done
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token comment">//删除一个TodoObj</span>
<span class="token function">deleteTodoObj</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
<span class="token comment">//注意:过滤出来的是一个新数组,并不是改变了data中的todoList。</span>
<span class="token comment">//因此,要重新赋值一下。</span>
<span class="token comment">// console.log(id)</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>todoList <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>todoList<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span>todoObj<span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{<!-- --></span>
<span class="token keyword">return</span> todoObj<span class="token punctuation">.</span>id <span class="token operator">!==</span> id
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token comment">//全选or取消全选</span>
<span class="token function">checkAllTodoObj</span><span class="token punctuation">(</span>done<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
<span class="token keyword">this</span><span class="token punctuation">.</span>todoList<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span>todo<span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{<!-- --></span>
todo<span class="token punctuation">.</span>done <span class="token operator">=</span> done
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token comment">//清除所有已经完成的todoObj</span>
<span class="token function">clearAllTodoObj</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
<span class="token keyword">this</span><span class="token punctuation">.</span>todoList <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>todoList<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span>todo<span class="token punctuation">)</span><span class="token operator">=></span><span class="token punctuation">{<!-- --></span>
<span class="token keyword">return</span> <span class="token operator">!</span>todo<span class="token punctuation">.</span>done
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">,</span>
<span class="token comment">//实现本地存储</span>
watch<span class="token punctuation">:</span><span class="token punctuation">{<!-- --></span>
todoList<span class="token punctuation">:</span><span class="token punctuation">{<!-- --></span>
<span class="token comment">//开启深度监视,确保对象中的内容被修改了也能重新定义localStorage中的todoList。</span>
deep<span class="token punctuation">:</span><span class="token boolean">true</span><span class="token punctuation">,</span>
<span class="token function">handler</span><span class="token punctuation">(</span>newValue<span class="token punctuation">,</span>oldValue<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
localStorage<span class="token punctuation">.</span><span class="token function">setItem</span><span class="token punctuation">(</span><span class="token string">'todoList'</span><span class="token punctuation">,</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>newValue<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</script>
<style>
body{
background-color: #fff;
}
.btn{
display: inline-block;
padding: 4px 12px;
margin-bottom: 0;
font-size: 14px;
line-height: 20px;
text-align: center;
vertical-align: middle;
cursor: pointer;
box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), 0 1px 2px rgba(0,0,0,0.05);
border-radius: 4px;
}
.btn-danger{
color: #fff;
background-color: #da4f49;
border: 1px solid #bd362f;
}
.btn-danger:hover{
color: #fff;
background-color: #BD362F;
}
.btn:focus{
outline: none;
}
.todo-container{
width:600px;
margin: 0 auto;
}
.todo-container .todo-wrap {
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
}
</style>
- 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
MyHeader.vue文件:
<template>
<div class="todo-header">
<input type="text" placeholder="请输入你的任务名称,按回车确认" @keyup.enter="add">
</div>
</template>
<script>
import {nanoid} from 'nanoid'
export default {
name:"MyHeader",
methods:{
add(e){
//判断是否为空
if(!e.target.value.trim())
return alert('输入不能为空!')
<span class="token comment">//获取用户输入信息</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>target<span class="token punctuation">.</span>value<span class="token punctuation">)</span>
<span class="token comment">//包装用户信息,id使用Nanoid来操作</span>
<span class="token keyword">const</span> todoObj <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span>
id<span class="token punctuation">:</span><span class="token function">nanoid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
title<span class="token punctuation">:</span>e<span class="token punctuation">.</span>target<span class="token punctuation">.</span>value<span class="token punctuation">,</span>
done<span class="token punctuation">:</span><span class="token boolean">false</span>
<span class="token punctuation">}</span>
<span class="token comment">//当前vc拿到receive方法,直接传值就可以了。</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">receive</span><span class="token punctuation">(</span>todoObj<span class="token punctuation">)</span>
e<span class="token punctuation">.</span>target<span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token string">''</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
props<span class="token punctuation">:</span><span class="token punctuation">[</span><span class="token string">'receive'</span><span class="token punctuation">]</span>
<span class="token punctuation">}</span>
</script>
<style scoped>
.todo-header input {
width: 560px;
height: 28px;
font-size: 14px;
border: 1px solid #ccc;
border-radius: 4px;
padding: 4px 7px;
}
.todo-header input:focus {
outline: none;
border-color: rgba(82,168,236,0.8);
box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
}
</style>
- 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
MyList.vue文件:
<template>
<ul class="todo-main">
<!-- 使用props来传递值,父传子 -->
<Item1
v-for="todoObj in todoList"
:key="todoObj.id"
:itemPro="todoObj"
:checkTodoObj="checkTodoObj"
:deleteTodoObj="deleteTodoObj"
></Item1>
</ul>
</template>
<script>
import Item1 from './MyItem.vue'
export default {
name:"MyList",
components:{Item1},
props:['todoList','checkTodoObj','deleteTodoObj']
}
</script>
<style scoped>
.todo-main{
margin-left: 0px;
border: 1px solid #ddd;
border-radius: 2px;
padding: 0px;
}
.todo-empty{
height: 40px;
line-height: 40px;
border: 1px solid #ddd;
border-radius: 2px;
padding-left: 5px;
margin-top: 10px;
}
</style>
- 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
MyItem.vue文件:
<template>
<li>
<label>
<!--
checked勾选该checkbox。
想要下面的props元素控制checkbox,就可以使用:来使其成为js表达式。这样我们就可以通过js表达式
来操作了。这里的itemPro我定义为了{id:'001',title:'吃饭',done:true}的结构。
@click和@change都可以操作事件方面的东西。
--></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>checkbox<span class="token punctuation">"</span></span> <span class="token attr-name">:checked</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>itemPro.done<span class="token punctuation">"</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>handleCheck(itemPro.id)<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span><span class="token punctuation">></span></span>{<!-- -->{itemPro.title}}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>label</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>button</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>btn btn-danger<span class="token punctuation">"</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>handleDelete(itemPro.id)<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>删除<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>li</span><span class="token punctuation">></span></span>
</template>
<script>
export default {
name:"MyItem",
//声明接受todo对象
props:['itemPro','checkTodoObj','deleteTodoObj'],
mounted(){
// console.log(this.itemPro);
},
methods:{
//勾选or取消
handleCheck(id){
//通知App组件将对应的itemPro对象的done值取反
this.checkTodoObj(id)
},
//删除
handleDelete(id){
//根据用户
if(confirm('确定删除吗?')){
this.deleteTodoObj(id)
}
}
}
}
</script>
<style scoped>
li{
list-style: none;
height: 36px;
line-height: 36px;
padding: 0 5px;
border-bottom: 1px solid #ddd;
}
li label {
float: left;
cursor: pointer;
}
li label li input {
vertical-align: middle;
margin-right: 6px;
position: relative;
top: -1px;
}
li button{
float: right;
display: none;
margin-top: 3px;
}
li:before{
content: initial;
}
li:last-child{
border-bottom: none;
}
li:hover{
background-color: #ddd;
}
li:hover button{
display: block;
}
</style>
- 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
MyFooter.vue文件:
<template>
<div class="todo-footer" v-show="total">
<label>
<input type="checkbox" :checked="isAll" @change="checkAll"/>
</label>
<span>
<span>已经完成{{doneTotal}} / 全部:{{total}}</span>
</span>
<button class="btn btn-danger" @click="clearAll">清除已完成任务</button>
</div>
</template>
<script>
export default {
name:"MyFooter",
props:['todoList','checkAllTodoObj','clearAllTodoObj'],
computed:{
total(){
return this.todoList.length
},
doneTotal(){
//reduce的使用:
//第一个参数是函数,当前todoList的数组长度为多少,就调用多少次。
//第二个参数是开始的时候的pre的起始值。
const x = this.todoList.reduce((pre,current)=>{
//这里的pre参数是上一次执行的返回W值。起始索引是0。
// console.log('pre参数:',pre)
//这里的current参数是这次执行的对象。
// console.log('current参数:',current)
return pre + (current.done ? 1:0)
},0)
<span class="token comment">// console.log("reduce的最终返回:",x)</span>
<span class="token keyword">return</span> x<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token function">isAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
<span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>doneTotal <span class="token operator">==</span> <span class="token keyword">this</span><span class="token punctuation">.</span>total <span class="token operator">&&</span> <span class="token keyword">this</span><span class="token punctuation">.</span>total <span class="token operator">></span> <span class="token number">0</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
methods<span class="token punctuation">:</span><span class="token punctuation">{<!-- --></span>
<span class="token function">checkAll</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
<span class="token comment">// console.log(e.target.checked)</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">checkAllTodoObj</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>target<span class="token punctuation">.</span>checked<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token function">clearAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">confirm</span><span class="token punctuation">(</span><span class="token string">"确定清除全部任务吗?"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">clearAllTodoObj</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
}
</script>
<style scoped>
.todo-footer{
height: 40px;
line-height: 40px;
padding-left: 6px;
margin-top: 5px;
}
.todo-footer label{
display: inline-block;
margin-right: 20px;
cursor: pointer;
}
.todo-footer label input{
position: relative;
top:-1px;
vertical-align: middle;
margin-right: 5px;
}
.todo-footer button{
float: right;
margin-top: 5px;
}
</style>
- 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
3. Vue 组件自定义事件
注意:这里是自定义事件,并不是自定义指令,不要搞混了。
vue的组件自定义事件是通过v-on来指定或者@来指定。
3.1 vm.$on 和 vm.$emit的使用
常见情况:
-
this.$refs.student.$on(‘事件名’,function(args){ }) :开发中我们使用这种方式来绑定事件。后面的函数我们都叫它回调函数。

-
this.$emit(‘itholmes’,this.name,1,2,3) 触发当前this组件的itholmes事件,并给它传递多个参数。
官方解释:


$on和$emit一般配合使用的:
- $on(‘itholmes’,function(){})本质上和下面结构一样。

- 再让$emit(itholmes,args)来触发事件,args是可以传递的参数。
- 对应的还有/
o n c e ( 一 次 性 ) , / once(一次性),/ </span><span class="katex-html"><span class="base"><span class="strut" style="height: 1em; vertical-align: -0.25em;"></span><span class="mord mathdefault">o</span><span class="mord mathdefault">n</span><span class="mord mathdefault">c</span><span class="mord mathdefault">e</span><span class="mopen">(</span><span class="mord cjk_fallback">一</span><span class="mord cjk_fallback">次</span><span class="mord cjk_fallback">性</span><span class="mclose">)</span><span class="mord cjk_fallback">,</span><span class="mord">/</span></span></span></span></span>off(解绑)等等。</strong></li></ul>3.2 两种组件自定义事件绑定的方式(实现子组件向父组件传值)
第一种方式:通过父组件给子组件绑定一个自定义事件实现:子给父传递数据。(使用@或v-on)
第二种方式:通过父组件给子组件绑定一个自定义事件实现:子给父传递数据。(使用ref)
App.vue文件:
<template> <div class="app"> <h1>{{msg}}</h1> <!-- 这里是给组件Student的实例对象VueComponent绑定了itholmes事件。 第一种方式:通过父组件给子组件绑定一个自定义事件实现:子给父传递数据。(使用@或v-on) --> <Student v-on:itholmes.once="getStudentName"></Student> <!-- 第二种方式:通过父组件给子组件绑定一个自定义事件实现:子给父传递数据。(使用ref) --> <Student ref="student"></Student> </div> </template><script>
import School from "./components/School.vue"
import Student from "./components/Student.vue"
export default{
name:'App',
components:{Student,School},
data(){
return {
msg:"你好啊!"
}
},
methods:{
getStudentName(name,...params){
console.log("App收到了学生名:",name,params)
}
},
mounted(){
//这种方式相比较上面两种更加灵活一些。
// this.\(refs.student.\)on('itholmes',this.getStudentName)//绑定自定义事件
//也可以用once来操作
this.\(refs<span class="token punctuation">.</span>student<span class="token punctuation">.</span><span class="token function">\)once('itholmes',this.getStudentName)//绑定自定义事件一次性。
}
}
</script><style>
.app{
background-color: gray;
padding: 5px;
}
</style>- 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
Student.vue文件:
<template> <div class="student"> <h2>学生姓名: {{name}}</h2> <h2>学生性别: {{sex}}</h2> <button @click="seneStudentName">把学生姓名给App</button> </div> </template><script>
export default{
name:"Student",
data(){
return {
name:"张三",
sex:"男"
}
},
methods:{
seneStudentName(){
// emit英文直译:发射,排放。
//\(emit来触发Student组件实例身上的itholmes事件,并且将this.name传给itholmes事件中的getStudentName函数。</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">\)emit('itholmes',this.name,1,2,3)
}
}
}
</script><style>
.student{
background-color: pink;
padding: 5px;
margin-top: 30px;
}
</style>- 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
3.3 组件自定义事件 解绑

解绑事件的操作如下:
- this.$off(‘itholmes’); 解绑单个事件。
- this.$off([‘itholmes’,‘demo’]); 解绑多个事件。
- this.$off(); 解绑所有的自定义事件。
<template> <div class="student"> <h2>学生姓名: {{name}}</h2> <h2>学生性别: {{sex}}</h2> <button @click="seneStudentName">把学生姓名给App</button> <button @click="unbind">解绑itholmes事件</button> </div> </template><script>
export default{
name:"Student",
data(){
return {
name:"张三",
sex:"男"
}
},
methods:{
seneStudentName(){
this.\(emit</span><span class="token punctuation">(</span><span class="token string">'itholmes'</span><span class="token punctuation">,</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment">//再指定一个demo事件,来触发</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">\)emit('demo')
},
unbind(){<span class="token comment">//解绑单个事件</span> <span class="token comment">// this.$off('itholmes')</span> <span class="token comment">//解绑多个事件</span> <span class="token comment">// this.$off(['itholmes','demo'])</span> <span class="token comment">//解绑所有的自定义事件</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">$off</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></script>
<style>
.student{
background-color: pink;
padding: 5px;
margin-top: 30px;
}
</style>- 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
当执行$destroy()销毁时,事件会怎么样。

3.4 组件自定义事件的几个误区
3.4.1 this是父组件还是子组件,如何区分?
注意:使用this$refs中拿到的子组件,调用$on或者其他方法中,函数的this指向的是子组件,并不是父组件!
<template> <div class="app"> <h1>{{msg}},学生姓名:{{studentName}}</h1> <Student ref="student"></Student> </div> </template><script>
import School from "./components/School.vue"
import Student from "./components/Student.vue"
export default{
name:'App',
components:{Student,School},
data(){
return {
msg:"你好啊!",
studentName:""
}
},
methods:{
getSchoolName(name){
console.log('App收到了学校名:',name)
},
m1(){
console.log("demo事件被触发了。")
}
},
mounted(){
this.\(refs<span class="token punctuation">.</span>student<span class="token punctuation">.</span><span class="token function">\)on('itholmes',function(name,...params){
console.log("App收到了学生名:",name,params)
console.log(this)
//这样做是不可以的!因为这里的this指向的不是当前App组件,而是我们$refs中student组件。
this.studentName = name
//因此我们在这里设置name,是设置的student子组件的,并不是App组件!!
//这个坑要注意!
})
}
}
</script><style>
.app{
background-color: gray;
padding: 5px;
}
</style>- 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
这种问题可以通过箭头函数来解决。

也可以通过在父组件创建methods函数来解决。

3.4.2 native 修饰符的使用
如果我们想给组件添加原生的一些事件,例如:click事件。组件依然会将它认为是自定义事件!
这个时候就可以使用native修饰符来修饰原生事件,让这整个组件都添加上这个原生事件。

3.5 自定义事件总结
组件的自定义组件事件是一种组件的通信方式,适用于:子组件 向 父组件发送。
- 一定注意this的指向问题,是指向的父组件还是子组件,箭头函数下是没有this的要向外查询this。
- 注意$on的回调函数一般是设置在父组件中。这样也方便父组件接受子组件的传值。
4. 全局事件总线
4.1 全局事件总线的 作用和流程
全局事件总线的作用就是让任意组件之间可以通信。

Vue与VueComponent的一个重要内置关系:
- VueComponent.prototype.__proto__ === Vue.prototype 。

全局的事件总线就是基于这个规则的。
事件常用的$on,$emit,$off都是在vue的原型对象上面,就是因为组件和vue原型对象存在一个内置的原型链关系,所以组件才能调用这些方法。
4.2 通过自定义vc组件实例对象 实现全局事件总线(不推荐)
就是通过下面的vc组件的实例对象d实现的。
main.js文件:
import Vue from "vue" import App from "./App.vue"Vue.config.productionTip = false;
//这里如果设置了一个Object类型,Object的原型链上面是没有\(emit,\)on这些东西的。
// Vue.prototype.x = {a:1,b:2}const Demo = Vue.extend({})
//这里的d就是vc组件的实例对象。
const d = new Demo();//因此,这里我们想要实现事件总线就必须得设置一个vue实例对象或者vc组件对象
Vue.prototype.x = d;new Vue({
el:'#app',
render:h=>h(App)
})- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
School.vue组件:
<template> <div class="school"> <h2>学校姓名: {{name}}</h2> <h2>学校地址: {{address}}</h2> </div> </template><script>
export default{
name:"School",
data(){
return {
name:"清华大学",
address:"北京"
}
},
mounted(){
// console.log('School',this)
this.x.$on('hello',(data)=>{
console.log("我是School组件,收到数据",data)
})
}
}
</script><style>
.school{
background-color: skyblue;
}
</style>- 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
Student.vue文件:
<template> <div class="student"> <h2>学生姓名: {{name}}</h2> <h2>学生性别: {{sex}}</h2> <button @click="sendStudentName">把学生名给School组件</button> </div> </template><script>
export default{
name:"Student",
data(){
return {
name:"张三",
sex:"男"
}
},
methods:{
sendStudentName(){
this.x.$emit("hello",this.name)
}
}
}
</script><style>
.student{
background-color: pink;
padding: 5px;
margin-top: 30px;
}
</style>- 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
4.3 通过当前的Vue实例对象 实现全局事件总线(推荐)
首先,我们不能写成这种形式。

我们可以通过钩子函数beforeCreate来操作:
import Vue from "vue" import App from "./App.vue"Vue.config.productionTip = false;
new Vue({
el:'#app',
render:h=>h(App),
beforeCreate() {
//这里的this就是指向的当前vm对象。
Vue.prototype.x = this; //安装全局事件总线
}
})- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
一般安装全局事件总线的名字叫做$bus。
完整代码如下:
import Vue from "vue" import App from "./App.vue"Vue.config.productionTip = false;
new Vue({
el:'#app',
render:h=>h(App),
beforeCreate() {
Vue.prototype.$bus = this;
}
})- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
Student.vue文件:
<template> <div class="student"> <h2>学生姓名: {{name}}</h2> <h2>学生性别: {{sex}}</h2> <button @click="sendStudentName">把学生名给School组件</button> </div> </template><script>
export default{
name:"Student",
data(){
return {
name:"张三",
sex:"男"
}
},
methods:{
sendStudentName(){
this.\(bus<span class="token punctuation">.</span><span class="token function">\)emit("hello",this.name)
}
}
}
</script><style>
.student{
background-color: pink;
padding: 5px;
margin-top: 30px;
}
</style>- 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
School.vue文件:
<template> <div class="school"> <h2>学校姓名: {{name}}</h2> <h2>学校地址: {{address}}</h2> </div> </template><script>
export default{
name:"School",
data(){
return {
name:"清华大学",
address:"北京"
}
},
mounted(){
// console.log('School',this)
this.\(bus<span class="token punctuation">.</span><span class="token function">\)on('hello',(data)=>{
console.log("我是School组件,收到数据",data)
})
},
//记得在组件销毁之前,因为我们的这个\(bus是一直全局都在的!需要用的就用,不需要的就销毁!</span> <span class="token function">beforeDestroy</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> <span class="token keyword">this</span><span class="token punctuation">.</span>\)bus.$off("hello")
}
}
</script><style>
.school{
background-color: skyblue;
}
</style>- 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
4.4 全局事件总线 总结

5. 对于todoList的全局事件总线修改
main.js文件:
import Vue from "vue" import App from "./App.vue"Vue.config.productionTip = false;
new Vue({
el:'#app',
render:h=>h(App),
beforeCreate() {
//安装事件总线
Vue.prototype.$bus = this;
}
})- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
MyHeader.vue
<template> <div class="todo-header"> <input type="text" placeholder="请输入你的任务名称,按回车确认" @keyup.enter="add"> </div> </template><script>
import {nanoid} from 'nanoid'
export default {
name:"MyHeader",
methods:{
add(e){
//判断是否为空
if(!e.target.value.trim())
return alert('输入不能为空!')<span class="token comment">//获取用户输入信息</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>target<span class="token punctuation">.</span>value<span class="token punctuation">)</span> <span class="token comment">//包装用户信息,id使用Nanoid来操作</span> <span class="token keyword">const</span> todoObj <span class="token operator">=</span> <span class="token punctuation">{<!-- --></span> id<span class="token punctuation">:</span><span class="token function">nanoid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> title<span class="token punctuation">:</span>e<span class="token punctuation">.</span>target<span class="token punctuation">.</span>value<span class="token punctuation">,</span> done<span class="token punctuation">:</span><span class="token boolean">false</span> <span class="token punctuation">}</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">$emit</span><span class="token punctuation">(</span><span class="token string">"receive"</span><span class="token punctuation">,</span>todoObj<span class="token punctuation">)</span> <span class="token comment">//输入完成后清空 </span> e<span class="token punctuation">.</span>target<span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token string">''</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span></script>
<style scoped>
.todo-header input {
width: 560px;
height: 28px;
font-size: 14px;
border: 1px solid #ccc;
border-radius: 4px;
padding: 4px 7px;
}
.todo-header input:focus {
outline: none;
border-color: rgba(82,168,236,0.8);
box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
}
</style>- 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
MyList.vue文件:
<template> <ul class="todo-main"> <!-- 使用props来传递值,父传子 --> <Item1 v-for="todoObj in todoList" :key="todoObj.id" :itemPro="todoObj" ></Item1> </ul> </template><script>
import Item1 from './MyItem.vue'
export default {
name:"MyList",
components:{Item1},
props:['todoList']
}
</script><style scoped>
.todo-main{
margin-left: 0px;
border: 1px solid #ddd;
border-radius: 2px;
padding: 0px;
}
.todo-empty{
height: 40px;
line-height: 40px;
border: 1px solid #ddd;
border-radius: 2px;
padding-left: 5px;
margin-top: 10px;
}
</style>- 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
MyItem.vue文件:
<template> <li> <label> <!-- checked勾选该checkbox。 想要下面的props元素控制checkbox,就可以使用:来使其成为js表达式。这样我们就可以通过js表达式 来操作了。这里的itemPro我定义为了{id:'001',title:'吃饭',done:true}的结构。@click和@change都可以操作事件方面的东西。 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>checkbox<span class="token punctuation">"</span></span> <span class="token attr-name">:checked</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>itemPro.done<span class="token punctuation">"</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>handleCheck(itemPro.id)<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>span</span><span class="token punctuation">></span></span>{<!-- -->{itemPro.title}}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>span</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>label</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>button</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>btn btn-danger<span class="token punctuation">"</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>handleDelete(itemPro.id)<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>删除<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>button</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>li</span><span class="token punctuation">></span></span></template>
<script>
export default {
name:"MyItem",
//声明接受todo对象
props:['itemPro'],
mounted(){
// console.log(this.itemPro);
},
methods:{
//勾选or取消
handleCheck(id){
//通知App组件将对应的itemPro对象的done值取反
this.\(bus<span class="token punctuation">.</span><span class="token function">\)emit('checkTodoObj',id)
},
//删除
handleDelete(id){
//根据用户
if(confirm('确定删除吗?')){
this.\(bus<span class="token punctuation">.</span><span class="token function">\)emit("deleteTodoObj",id)
}
}
}
}
</script><style scoped>
li{
list-style: none;
height: 36px;
line-height: 36px;
padding: 0 5px;
border-bottom: 1px solid #ddd;
}
li label {
float: left;
cursor: pointer;
}
li label li input {
vertical-align: middle;
margin-right: 6px;
position: relative;
top: -1px;
}
li button{
float: right;
display: none;
margin-top: 3px;
}
li:before{
content: initial;
}
li:last-child{
border-bottom: none;
}
li:hover{
background-color: #ddd;
}
li:hover button{
display: block;
}
</style>- 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
MyFooter.vue文件:
<template> <div class="todo-footer" v-show="total"> <label> <input type="checkbox" :checked="isAll" @change="checkAll"/> </label> <span> <span>已经完成{{doneTotal}} / 全部:{{total}}</span> </span> <button class="btn btn-danger" @click="clearAll">清除已完成任务</button> </div> </template><script>
export default {
name:"MyFooter",
props:['todoList'],
computed:{
total(){
return this.todoList.length
},
doneTotal(){
//reduce的使用:
//第一个参数是函数,当前todoList的数组长度为多少,就调用多少次。
//第二个参数是开始的时候的pre的起始值。
const x = this.todoList.reduce((pre,current)=>{
//这里的pre参数是上一次执行的返回W值。起始索引是0。
// console.log('pre参数:',pre)
//这里的current参数是这次执行的对象。
// console.log('current参数:',current)
return pre + (current.done ? 1:0)
},0)<span class="token comment">// console.log("reduce的最终返回:",x)</span> <span class="token keyword">return</span> x<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">isAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>doneTotal <span class="token operator">==</span> <span class="token keyword">this</span><span class="token punctuation">.</span>total <span class="token operator">&&</span> <span class="token keyword">this</span><span class="token punctuation">.</span>total <span class="token operator">></span> <span class="token number">0</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> methods<span class="token punctuation">:</span><span class="token punctuation">{<!-- --></span> <span class="token function">checkAll</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> <span class="token comment">// console.log(e.target.checked)</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">$emit</span><span class="token punctuation">(</span><span class="token string">"checkAllTodoObj"</span><span class="token punctuation">,</span>e<span class="token punctuation">.</span>target<span class="token punctuation">.</span>checked<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function">clearAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">confirm</span><span class="token punctuation">(</span><span class="token string">"确定清除全部任务吗?"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">$emit</span><span class="token punctuation">(</span><span class="token string">"clearAllTodoObj"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span>}
</script><style scoped>
.todo-footer{
height: 40px;
line-height: 40px;
padding-left: 6px;
margin-top: 5px;
}
.todo-footer label{
display: inline-block;
margin-right: 20px;
cursor: pointer;
}
.todo-footer label input{
position: relative;
top:-1px;
vertical-align: middle;
margin-right: 5px;
}
.todo-footer button{
float: right;
margin-top: 5px;
}
</style>- 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
