天天看点

【Vue学习总结】9.Vue结合localStorage和生命周期实现todolist

接上篇《8.Vue事件结合双向数据绑定实现todolist》

上一篇我们主要讲解了通过Vue事件,结合双向数据绑定来实现todolist(待办事项列表)的效果。本篇我们讲解如何结合Vue的模块化以及封装Storage实现todolist(待办事项列表)。

本系列博文使用的Vue版本:2.6.11

上一篇我们实现了带有“进行中”和“已完成”效果的todolist(待办事项列表):

【Vue学习总结】9.Vue结合localStorage和生命周期实现todolist

最后我们提出了一个问题,就是会发现刷新页面的时候,之前的list中新增的数据是被清空的,我们想要实现数据临时缓存化,如何实现?

通过本篇的学习,我们可以实现缓存list的效果,并了解这个功能的原理,顺便优化我们的todolist功能。

一、使用loaclStroage

想要实现前端数据的缓存功能,可以使用loaclStroage结合vue生命周期函数mounted来实现。

1、loaclStroage介绍

什么是loaclStroage?loaclStroage是Html5中加入的新特性,该特性可作为本地存储来使用,即在浏览器上提供了一个5M大小的存储,将第一次请求的数据直接存储到本地,解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间为4k)。

使用localStorage需要注意一下事项:

(1)IE8以上的IE版本才支持localStorage这个属性。

(2)localStorage的值类型限定为string类型,如果存储JSON对象类型,需要转换。

(3)localStorage在浏览器的隐私模式下面是不可读取的。

(4)localStorage存储内容多会导致页面卡顿。

(5)localStorage不能被爬虫抓取到。

(6)localStorage遵循同源策略,不同网站不能直接共用相同的localStorage。

localStorage还有个兄弟叫sessionStorage,他们唯一的区别就是localStorage是永久性存储,而sessionStorage在会话结束的时候其存储的键值对会被清空。

2、loaclStroage写法

(1)存储数据到本地

loaclStroage.setItem('name','张三');
const user = {
    name: '李四',
    age: '20',
    id: '001'
}
loaclStroage.setItem('user',JSON.stringify(user));//json对象要转换为字符串
           

或直接定义属性:

//写入a字段
loaclStroage["a"]=1;
//写入b字段
loaclStroage.b=1;
           

(2)从本地获取数据

var data = JSON.parse(loaclStroage.getItem('name'));
var userStr = JSON.parse(loaclStroage.getItem('user'));
var userObj=JSON.parse(userStr);//将JSON字符串转换成为JSON对象
           

或从属性获取:

//获取a字段
var a = loaclStroage["a"];
//获取b字段
var b = loaclStroage.b;
           

(3)从本地删除

loaclStroage.removeItem('name');
           

(4)清除本地所有数据

loaclStroage.clear();
           

了解了loaclStroage之后,我们就可以将之前的数据进行一个缓存操作了。我们可以分别在之前的addDate()方法和removeData()方法中,新增loaclStroage的插入操作:

methods:{ /*存放自定义方法的地方 */
    doAdd(){
      //1、获取文本框输入的信息  
      //2、将文本框的值push到list中,并清空文本框
      this.list.push({
        title: this.todo,
        checked: true
      });
      this.todo='';
      //将list存储进本地缓存
      localStorage.setItem('list',JSON.stringify(this.list));
    },removeData(key){
      this.list.splice(key,1);
      //将新的list覆盖原有缓存
      localStorage.setItem('list',JSON.stringify(this.list));
    },doAdd2(e){
      if(e.keyCode==13){
        //当按下回车键的时候,执行doAdd方法
        this.doAdd();
      }
    }
}
           

此时我们在刷新页面的时候还无法实现list的还原,因为我们没有为list重新初始化,此时需要使用vue生命周期函数mounted。

二、vue生命周期函数

一个vue实例从被创建,运行、到最后被销毁,是一个完整的生命周期过程,在这期间,vue提供了beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestory、destoryed这些生命周期函数,具体的作用和区别见下表:

【Vue学习总结】9.Vue结合localStorage和生命周期实现todolist

想要更深入的了解vue的生命周期,可以参见官网的文档:

https://cn.vuejs.org/v2/guide/instance.html

这里我们想要在页面模板加载好之前,从本地存储中获取list信息,重新赋值到this.list上,选择上面的mounted函数。

另外,我们在点击数据切换和删除的时候,也需要更新本地的list,否则刷新后数据切换和删除状态无法同步。因为实在状态更新之后做的操作,所以这里要使用updated函数。

使用vue的生命周期函数时,位置和data()以及methods是同级的,写法如下:

<script>
export default {
  name: 'app',
  data () {
      return {
        //省略...
      }
  },
  methods:{ /*存放自定义方法的地方 */
    //省略...
  },mounted(){
    var list = JSON.parse(localStorage.getItem('list'));
    if(list){//判空
      this.list=list;
    }
  },beforeUpdate(){
    localStorage.setItem('list',JSON.stringify(this.list));
  }
}
</script>
           

上面我们就在页面刷新时重新从本地存储获取到了缓存的list,并重新渲染在页面上。

这样我们就实现了本地缓存的效果:

【Vue学习总结】9.Vue结合localStorage和生命周期实现todolist

完整代码:

<template>
  <!-- vue的模板里面,所有的内容都需要被一个根节点包裹起来 -->
  <div id="app">
    <h2>{{msg}}</h2>
    
    <input type="text" v-model="todo" @keydown="doAdd2($event)"> <button @click="doAdd()">增加</button>
    <hr/><br/>
    <h2>进行中</h2>
    <ul>
       <div v-for="(item,key) in list" :key="key">
          <li v-if="item.checked">
            <input type="checkbox" v-model="item.checked">{{item}}---<button @click="removeData(key)">删除</button>
          </li>
       </div>
    </ul>
    <h2>已完成</h2>
    <ul>
       <div v-for="(item,key) in list" :key="key">
          <li v-if="!item.checked">
            <input type="checkbox" v-model="item.checked">{{item}}---<button @click="removeData(key)">删除</button>
          </li>
       </div>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'app',
  data () {
      return {
        msg: '你好,vue',
        todo:'',
        list:[
          {
            title: '1111',
            checked: true
          },
          {
            title: '2222',
            checked: false
          }
        ]
      }
  },
  methods:{ /*存放自定义方法的地方 */
    doAdd(){
      //1、获取文本框输入的信息  
        //2、将文本框的值push到list中,并清空文本框
      this.list.push({
        title: this.todo,
        checked: true
      });
      this.todo='';
      //将list存储进本地缓存
      localStorage.setItem('list',JSON.stringify(this.list));
    },removeData(key){
      this.list.splice(key,1);
      //将新的list覆盖原有缓存
      localStorage.setItem('list',JSON.stringify(this.list));
    },doAdd2(e){
      if(e.keyCode==13){
        //当按下回车键的时候,执行doAdd方法
        this.doAdd();
      }
    }
  },mounted(){
    var list = JSON.parse(localStorage.getItem('list'));
    if(list){//判空
      this.list=list;
    }
  },beforeUpdate(){
    localStorage.setItem('list',JSON.stringify(this.list));
  }
}
</script>

<style>
</style>
           

三、封装localStorage

我们使用localStorage时,调用它需要用localStorage.setItem、localStorage.getItem方法,比较长,我们可以将localStorage的一些函数封装起来,成一个简单对象,然后引入到主页面来使用,方便我们编写代码。

在vue中,封装一个js对象(模块化对象,是Node中的概念),我们首先到工程的src下新建一个model文件夹,然后创建一个名为“storage”的js文件:

【Vue学习总结】9.Vue结合localStorage和生命周期实现todolist

然后编写以下内容:

//封装操作localStorage本地存储的方法
//模块化对象
var storage = {
   
    set(key,value){
        localStorage.setItem(key,JSON.stringify(value));
    },
    get(key){
        return JSON.parse(localStorage.getItem(key));
    },remove(key){
        localStorage.removeItem(key);
    }

}

export default storage;
           

这里我们封装了localStorage的一些函数(添加了JSON解析),然后将storage对象暴露出来。

然后我们在App.vue文件中引用这个storage对象:

<script>
import storage from './model/storage.js'
export default {
  name: 'app',
  data () {
      return {
        //省略...
      }
  },
  methods:{ /*存放自定义方法的地方 */
    //省略...
  },mounted(){
    //省略...
  },beforeUpdate(){
    //省略...
  }
}
</script>
           

可以看到,是在<script>脚本区域,声明data之前引入storage对象的。然后整个代码更新如下:

<template>
  <!-- vue的模板里面,所有的内容都需要被一个根节点包裹起来 -->
  <div id="app">
    <h2>{{msg}}</h2>
    
    <input type="text" v-model="todo" @keydown="doAdd2($event)"> <button @click="doAdd()">增加</button>
    <hr/><br/>
    <h2>进行中</h2>
    <ul>
       <div v-for="(item,key) in list" :key="key">
          <li v-if="item.checked">
            <input type="checkbox" v-model="item.checked">{{item}}---<button @click="removeData(key)">删除</button>
          </li>
       </div>
    </ul>
    <h2>已完成</h2>
    <ul>
       <div v-for="(item,key) in list" :key="key">
          <li v-if="!item.checked">
            <input type="checkbox" v-model="item.checked">{{item}}---<button @click="removeData(key)">删除</button>
          </li>
       </div>
    </ul>
  </div>
</template>

<script>
import storage from './model/storage.js'
export default {
  name: 'app',
  data () {
      return {
        msg: '你好,vue',
        todo:'',
        list:[
          {
            title: '1111',
            checked: true
          },
          {
            title: '2222',
            checked: false
          }
        ]
      }
  },
  methods:{ /*存放自定义方法的地方 */
    doAdd(){
      //1、获取文本框输入的信息  
        //2、将文本框的值push到list中,并清空文本框
      this.list.push({
        title: this.todo,
        checked: true
      });
      this.todo='';
      //将list存储进本地缓存
      storage.set('list',this.list);
    },removeData(key){
      this.list.splice(key,1);
      //将新的list覆盖原有缓存
      storage.set('list',this.list);
    },doAdd2(e){
      if(e.keyCode==13){
        //当按下回车键的时候,执行doAdd方法
        this.doAdd();
      }
    }
  },mounted(){
    var list = storage.get('list');
    if(list){//判空
      this.list=list;
    }
  },beforeUpdate(){
    storage.set('list',this.list);
  }
}
</script>

<style>
</style>
           

以上就是我们通过localStorage和生命周期以及模块化封装实现了list缓存的效果。

参考:

https://www.cnblogs.com/st-leslie/p/5617130.html

https://www.imooc.com/article/details/id/24462

https://blog.csdn.net/mqingo/article/details/86031260

《IT营:itying.com-2018年Vue2.x 5小时入门视频教程》

转载请注明出处:https://blog.csdn.net/acmman/article/details/108308837