33-Vue脚手架-浏览器本地存储(使用本地存储优化Todo-List案例)

发布时间 2023-10-30 11:57:52作者: 马铃薯1
什么是网络存储
在HTML5之前,开发人员一般是通过使用Cookie在客户端保存一些简单的信息的。
在HTML5发布后,提供了一种新的客户端本地保存数据的方法,那就是Web Storage,存储内容大小一般支持5MB左右(不同浏览器可能还不一样),它允许 Web 应用程序在用户浏览器中实现本地存储机制,两种最常见的 Web 存储形式是 LocalStorage 和 Session Storage。
1) LocalStorage
localStorage的生命周期是永久,存储在其中的数据永远不会离开浏览器,并且会一直保留在那里,直到您明确将其删除
2)Session Storage
sessionStorage的生命周期为当前窗口或标签页,一旦窗口或标签页被关闭了,那么存储在其中的数据就会被删除
 
相关API(localStorage 和 sessionStorage 的接口基本一致)
1)xxxxStorage.setItem("key","value")
该方法接收一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值
2)xxxxStorage.getItem("key")
该方法接收一个键名作为参数,返回键名对应的值
3)xxxxStorage.remove("key")
该方法接收一个键名作为参数,并把该键名从存储中删除
4)xxxxStorage.clear()
该方法会清空存储中的所有数据
 
备注:
1)LocalStorage存储的内容,需要手动存储才会消失
2)SessionStorage存储的内容,会随着浏览器窗口关闭而消失
3)xxxxStorage.getItem(xxx),如果xxx对应的value获取不到,那么getItem的返回值是Null
4)JSON.parse(null) 的结果依然是 Null
 
扩展:
JSON.parse() 方法用来解析 JSON 字符串
JSON.stringify() 方法将一个 JavaScript 对象或值转换为 JSON 字符串
let p = {name:"马铃薯", age:26}

// JSON.stringify() 方法将一个 JavaScript 对象或值转换为 JSON 字符串
const person = JSON.stringify(p)
console.log("@@",person)

// JSON.parse() 方法用来解析 JSON 字符串
console.log("@@",JSON.parse(person))

 

通过 唯品会 官网的历史搜索记录,来简单理解一下,本地存储LocalStorage,通过以键值对的形式保存数据【Key:searchHistoryData】 【Value:"数码相机"】

 

 

使用LocalStroage的小案例,这里直接使用JavaScript编写(localStorage的生命周期是永久,重新打开浏览器数据仍然存在)

localStroage.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>localStorage</title>
    </head>
    <body>
        <h2>localStorage</h2>
        <button onclick="saveData()">点击保存数据</button>
        <button onclick="showData()">点击获取数据</button>
        <button onclick="deleteData()">点击删除一条数据</button>
        <button onclick="deleteAllData()">点击删除所有数据</button>

        <script type="text/javascript">

            let p = {name:"马铃薯", age:26}

            function saveData(){
                // 将value存储到key字段
                localStorage.setItem("msg","hello")
                localStorage.setItem("msg2",888) // 这里保存的时候,会将整型类型转换为字符类型
                // JSON.stringify() 方法将一个 JavaScript 对象或值转换为 JSON 字符串
                localStorage.setItem("person",JSON.stringify(p))
            }
            function showData(){
                console.log("获取localStorage中 'msg' 本地存储的值:" , localStorage.getItem("msg"))
                console.log("获取localStorage中 'msg2' 本地存储的值:" , localStorage.getItem("msg2"))

                const person = localStorage.getItem("person")
                // JSON.parse() 方法用来解析 JSON 字符串
                console.log("获取localStorage中 'person 本地存储的值:" , JSON.parse(person))
            }
            function deleteData(){
                localStorage.removeItem("msg2")
                console.log("localStorage中 'msg2' 已删除...")
            }
            function deleteAllData(){
                localStorage.clear()
                console.log("localStorage中 已清空 所有数据...")
            }
        </script>

    </body>
</html>

 

 

同理,使用SessionStroage的小案例,相关API接口都是一样的(sessionStorage的生命周期为当前窗口或标签页,重新打开浏览器数据则不存在)

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>sessionStorage</title>
    </head>
    <body>
        <h2>sessionStorage</h2>
        <button onclick="saveData()">点击保存数据</button>
        <button onclick="showData()">点击获取数据</button>
        <button onclick="deleteData()">点击删除一条数据</button>
        <button onclick="deleteAllData()">点击删除所有数据</button>
        
        <script type="text/javascript">
        
            let p = {name:"马铃薯", age:26}
        
            function saveData(){
                // 将value存储到key字段
                sessionStorage.setItem("msg","hello")
                sessionStorage.setItem("msg2",888) // 这里保存的时候,会将整型类型转换为字符类型
                // JSON.stringify() 方法将一个 JavaScript 对象或值转换为 JSON 字符串
                sessionStorage.setItem("person",JSON.stringify(p))
            }
            function showData(){
                console.log("获取sessionStorage中 'msg' 本地存储的值:" , sessionStorage.getItem("msg"))
                console.log("获取sessionStorage中 'msg2' 本地存储的值:" , sessionStorage.getItem("msg2"))
        
                const person = sessionStorage.getItem("person")
                // JSON.parse() 方法用来解析 JSON 字符串
                console.log("获取sessionStorage中 'person 本地存储的值:" , JSON.parse(person))
            }
            function deleteData(){
                sessionStorage.removeItem("msg2")
                console.log("sessionStorage中 'msg2' 已删除...")
            }
            function deleteAllData(){
                sessionStorage.clear()
                console.log("sessionStorage中 已清空 所有数据...")
            }
        </script>
        
    </body>
</html>

 

使用本地存储优化Todo-List案例

src/App.vue(主要修改的是这个部分,通过监视属性todos实现localStorage本地存储,在data中将localStorage数据读取到todos属性中)

<template>
  <div id="root">
    <div class="todo-container">
      <div class="todo-wrap">
        <!--动态绑定函数,在父组件定义一个函数,子组件调用该函数,父组件就可以收到子组件传过来的参数 :addTodo="addTodo"-->
        <UserHeader :addTodo="addTodo"></UserHeader>

        <UserList
            :todos="todos"
            :checkTodo="checkTodo"
            :deleteTodo="deleteTodo"
        ></UserList>

        <UserFooter :todos="todos" :checkAllTodo="checkAllTodo" :clearAllTodo="clearAllTodo"></UserFooter>

      </div>
    </div>
  </div>
</template>

<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 {
      // todos: [
      //   { id: "001", title: "起床", done: true },
      //   { id: "002", title: "洗漱", done: false },
      //   { id: "003", title: "睡觉", done: true },
      // ],

      // 这里,将 todos 数据读取 localStorage 本地存储;如果初始化数据为空返回null时,则赋值一个空数组
      // JSON.parse() 方法用来解析 JSON 字符串

      // 在json中,||逻辑运算符
      // 1.只要 || 前面为 false,不管 || 后面是 true 还是 false,都返回 || 后面的值。
      // 2.只要 || 前面为 true,不管 || 后面是 true 还是 false,都返回 || 前面的值。
      todos:JSON.parse(localStorage.getItem("todos")) || []
    };
  },

  // 使用监视属性,通过监视todos属性,实现 localStorage 本地存储 todos 数据
  watch:{
    todos:{
      // 深度监视,监视对象内部值的改变
      deep:true,

      handler(newValue){
        // JSON.stringify() 方法将一个 JavaScript 对象或值转换为 JSON 字符串
        console.log("@@监视属性",JSON.stringify(newValue))
        localStorage.setItem("todos",JSON.stringify(newValue))
      }
    }

  },

  methods: {
    // 添加一个todo
    addTodo(todoObj) {
      console.log("我是APP组件,我收到了数据:",todoObj)
      // unshift() 在数组头部添加元素
      this.todos.unshift(todoObj);
    },
    // 勾选or取消勾选一个todo
    checkTodo(id) {
      // forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数
      this.todos.forEach((todo) => {
        // 将tudo的done属性进行取反
        if (todo.id === id) todo.done = !todo.done;
      });
    },
    // 删除一个
    deleteTodo(id) {
      // 数组.filter() 实现数组的过滤,创建一个新数组, 其包含通过所提供函数实现的测试的所有元素
      // 过滤出,todo.id 不是 id 的数据
      this.todos = this.todos.filter((todo) => todo.id !== id);
    },
    // 全选or全不选
    checkAllTodo(done) {
      // forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数
      this.todos.forEach((todo) => {
        todo.done = done;
      });
    },
    //清除所有已经完成的任务
    clearAllTodo() {
     if(confirm("确认删除所有已完成的任务吗")){
       // 数组.filter() 实现数组的过滤,创建一个新数组, 其包含通过所提供函数实现的测试的所有元素
       // 过滤出,todo.done 还没完成 的数据
       // this.todos = this.todos.filter((todo) => todo.done == false);
       this.todos = this.todos.filter((todo) => !todo.done);
     }
    },
  },
};
</script>

<style>
/*base*/
body {
  background: #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>