目录
一、浏览器本地存储(webStorage)
1. 存储内容大小一般支持5MB左右(不同浏览器可能不一样)
2. 浏览器通过window.sessionStorage 和window.localStorage 属性来实现本地存储机制
3. 相关API:
(1)xxxxxStorage.setItem('key', 'value')
该方法接受一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值
(2)xxxxxStorage.getItem('key')
该方法接受一个键名作为参数,返回键名对应的值
(3)xxxxxStorage.removeItem('key')
该方法接受一个键名作为参数,并把该键名从存储中删除
(4)xxxxxStorage.clear()
该方法会清空存储中的所有数据
4. 备注:
- SessionStorage存储的内容会随着浏览器窗口关闭而消失
- LocalStorage存储的内容,需要手动清除才会消失
- xxxxxStorage.getItem(xxx) 如果xxx对应的value获取不到,那么getItem的返回值是null
- JSON.parse(null) 的结果依然是null
二、TodoList案例_本地存储
将TodoList案例中App.vue中的数据改为添加到浏览器中的 localStorage,并且列表将从localStorage中获取todos数据
App.vue 中 script标签内的内容修改和调整:添加了watch属性以及调整todos数据
<script>
import UserHeader from "./components/UserHeader.vue";
import UserList from "./components/UserList.vue";
import UserFooter from "./components/UserFooter.vue";
export default {
name: "App",
components: { UserHeader, UserList, UserFooter },
data() {
return {
// 获取数据时需解析localStorage内的转换为JSON的值,且需要或一个空数组,防止返回为null影响其他组件获取对应的属性,例如:底部组件获取todos的长度
todos: JSON.parse(localStorage.getItem("todos")) || [],
};
},
methods: {
// 添加一个todo
addTodo(todoObj) {
this.todos.unshift(todoObj);
},
// 勾选或取消勾线一个todo
checkTodo(id) {
this.todos.forEach((todo) => {
if (todo.id === id) todo.done = !todo.done;
});
},
// 删除一个todo
deleteTodo(id) {
this.todos = this.todos.filter((todo) => todo.id !== id);
},
// 全选或取消全选
checkAllTodo(done) {
this.todos.forEach((todo) => {
todo.done = done;
});
},
// 清除所有已经完成的todo
clearAllTodo() {
this.todos = this.todos.filter((todo) => {
return !todo.done;
});
},
},
watch: {
todos: {
// 需采用深度监视,否则在该百年checkbox框后,localStorage内的对应的属性不会发生改变
deep: true,
handler(value) {
// 需转换为JSON形式,否则在localStorage内产看为[object object]
localStorage.setItem("todos", JSON.stringify(value));
},
},
},
};
</script>
由图可看出,添加事件后,数据会存储在浏览器的localStorage中且改变checkbox后,localStorage内todos内对应的done的布尔值也会跟随改变,并且在刷新页面后,数据也不会重置
三、组件自定义事件
1. 一种组件间的通信方式,适用于:子组件 ===> 父组件
2. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件回调在A中)
3. 绑定自定义事件:
(1)第一种方式,在父组件中:
<Demo @自定义事件名="事件回调名">
或
<Demo v-on:自定义事件名="事件回调名">
·(2)第二种方式,在父组件中:
<Demo ref="demo"/>
...
mounted(){
this.$refs.xxx.$on('自定义事件名',this.事件回调名)
}
(3)若想让自定义事件只能触发一次,可以使用 once 修饰符,或$once方法
4. 触发自定义事件:
this.$emit('自定义事件名',数据)
5. 解绑自定义事件:
this.$off('自定义事件名')
6. 组件上也可以绑定原生DOM事件,需要使用native修饰符,如果未使用,默认为自定义事件
<Demo @click.native="事件回调名"/>
7. 注意:通过 this.$refs.xxx.$on('自定义事件名', 回调) 绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出现问题
四、TodoList案例_自定义事件
4.1 UserHeader组件
修改 App.vue 中 UserHeader组件标签中绑定的事件
<!-- <UserHeader :addTodo="addTodo"></UserHeader> -->
<UserHeader @addTodo="addTodo"></UserHeader>
调整UserHeader.vue 中 script标签内的内容
<script>
import { nanoid } from "nanoid";
export default {
name: "UserHeader",
// props: ["addTodo"],
data() {
return {
title: "",
};
},
methods: {
add(e) {
// 校验数据
if (!this.title) return alert("输入不能为空");
const todoObj = { id: nanoid(), title: this.title, done: false };
// 通知App组件去添加一个todo对象
// this.addTodo(todoObj);
// 自定义事件 - addTodo
this.$emit("addTodo", todoObj);
this.title = "";
},
},
};
</script>
由图示可看出,在添加事件后,可以在控制台中看到自定义事件 addTodo 被调用
4.2 UserFooter组件
修改 App.vue 中 UserFooter组件标签中绑定的事件
<!-- <UserFooter
:todos="todos"
:checkAllTodo="checkAllTodo"
:clearAllTodo="clearAllTodo"
></UserFooter> -->
<UserFooter
:todos="todos"
@checkAllTodo="checkAllTodo"
@clearAllTodo="clearAllTodo"
></UserFooter>
调整UserFooter.vue 中 script标签内的内容
<script>
export default {
name: "UserFooter",
// props: ["todos", "checkAllTodo", "clearAllTodo"],
// 自定义事件
props: ["todos"],
computed: {
total() {
return this.todos.length;
},
doneTotal() {
return this.todos.reduce((pre, todo) => pre + (todo.done ? 1 : 0), 0);
},
isAll: {
get() {
return this.total === this.doneTotal && this.total > 0;
},
set(value) {
// this.checkAllTodo(value);
// 自定义事件 - clearAllTodo
this.$emit("checkAllTodo", value);
},
},
},
methods: {
clearAll() {
if (confirm("您确认要清除已完成的任务吗?")) {
// this.clearAllTodo();
// 自定义事件 - clearAllTodo
this.$emit("clearAllTodo");
}
},
},
};
</script>
由图示控制台中,可看出点击底部的复选框后会触发 自定义事件checkAllTodo,点击 删除已完成任务按钮 会触发 自定义事件clearAllTodo