Vue脚手架系列05-数据持久化

253 阅读1分钟

1.中央事件总线boss的使用:

  • main.js里面挂载一个$boss

    • import Vue from 'vue'
      import App from './App.vue'
      //导入axios
      import axios from "axios";
      //这样在vue实例对象中就可以通过this.$http来使用axios了
      Vue.prototype.$http = axios;
      Vue.prototype.$boss = new Vue();
      
      Vue.config.productionTip = false;
      
      new Vue({
        render: h => h(App),
      }).$mount('#app')
      
  • 因为需要实现点击购物车按钮实现,添加到我的购物车列表的功能,所以需要在cart.vue,在created的声明周期函数中通过this.$boss.$on绑定addcart事件逻辑,也就是在cart组件一开始创建的时候就对他进行一个事件绑定

    • //cart.vue组件
      
      <template>
          <div>
              <h2>{{title}}</h2>
              <table border="1">
                  <tr>
                      <th>#</th>
                      <th>课程:</th>
                      <th>单价:</th>
                      <th>数量:</th>
                      <th>总价:</th>
                  </tr>
                  <tr v-for="(item,index) in cart" :key="index">
                      <td >
                          <input type="checkbox" v-model="item.active">    
                      </td>
                      <td>{{item.title}}</td>
                      <td>{{item.price}}</td>
                      <td>
                          <button @click="reduc(index)">-</button>
                          {{item.count}}
                          <button @click="add(index)">+</button>
                      </td>
                      <td>
                          ¥{{item.price*item.count}}
                      </td>
                  </tr>
                  <tr>
                      <td></td>
                      <td colspan="2">{{activeCount}}/{{count}}</td>
                      <td colspan="2">{{allCount}}</td>
                  </tr>
              </table>
          </div>
      </template>
      <script>
      export default {
          name:"cart",
          props:["title",],
          data() {
              return {
                  //🌵①:如果本地存储有位置,那么就获取cart读取,没有的话就赋值一个空数组
                  cart:JSON.parse(localStorage.getItem('cart'))||[]
              }
          },
          watch: {
            //🌵②:监听新值,然后cart,如果有新的变化,那么直接就通过this.setLocalData将值存到缓存中
              cart:{
                  deep:true,
                  handler(n,o){
                      console.log(n,'我是新值');
                      console.log(o,'我是老值');
                      this.setLocalData(n);
                  }
              }
          },
          // 这个就是通过this.$boss.$on去绑定一addCart事件
          created() {
              this.$boss.$on("addCart",good=>{
                  //查找现在数组中是否有id一样的值
             const ret = this.cart.find(v=>{
                      return v.id===good.id;
                  })
                  console.log(ret);
                  if(!ret){
                      this.cart.push(good);
                  }else{
                      ret.count++;
                  }
              })
          },
          methods: {
            //🌵③:将cart数据存入本缓存中去
              setLocalData(n){
                  console.log(n);
                  this.$boss.$emit("allnum",n.length);
                  //这里是将数据存放到本地里去
                  localStorage.setItem("cart",JSON.stringify(n));
              },
              remove(i){
                  if(window.confirm("确定要删除么?")){
                      this.cart.splice(i,1);
                  }
              },
              reduc(i){
                  let count = this.cart[i].count;
                  count >1 ? this.cart[i].count -=1 : this.remove(i)
              },
              add(i){
                  this.cart[i].count+=1;
              }
          },
          computed: {
              count(){
                  return this.cart.length;
              },
              activeCount(){
                  return this.cart.filter(v=>v.active).length;
              },
              activeitem(){
                  return this.cart.filter(v=>v.active);
              },
              allCount(){
                  return this.cart.reduce((sum,c)=>{
                      if(c.active){
                          sum+= c.price * c.count
                      }
                      return sum;
                  },0); 
              }
          },
      }
      </script>
      <style scoped>
      table{
          text-align: center;
      }
      </style>
      
  • 在app.vue文件中,在methods方法里面通过this.$emit("addCart","参数")去触发上面之前在Cart.vue组件中通过this.$boss.$on绑定的事件addCart

<template>
  <div id="app">
    <ul>
      <li v-for="(item,index) in cartList" :key="index">
        <h3>{{item.title}}</h3>
        <p>{{item.price}}</p>
        <button @click="addCart(index)">添加购物车</button>
      </li>
    </ul>
    <div>当前购物车里面有{{num}}件商品</div>
    <my-cart :title="title"></my-cart>
  </div>
</template>

<script>
import myCart from "./components/Cart";
export default {
  name: 'App',
  components: {
    myCart,
  },
  async created() {   
    //用来计算当期那的购物车数量的
    this.$boss.$on("allnum",(num)=>{
      this.num=num;
    })

    //🌵一般来说都是通过try catch 来解决async 和 await的报错问题
    try {
      const res = await this.$http.get("/api/cartList");
      this.cartList=res.data.result;
    } catch (error) {
      console.log(error);
    }

  },
  data() {
    return {
      cartList:[    
      ],
      title:"我的购物车",
      num:0,
    }
  },
  methods: {
    addCart(i){
       const goods=this.cartList[i];
       this.$boss.$emit("addCart",goods);
    },
  },
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
}
</style>

2.数据持久化

先来看下上面的几个例子代码中的操作吧。

  • 🌵①:cart组件中的data:如果本地存储有位置,那么就获取cart读取,没有的话就赋值一个空数组

  • 🌵②:在watch中监听cart新值,如果有新的变化,那么直接就通过this.setLocalData将值存到缓存中

  • 🌵③:将cart数据存入本缓存中去

    •     setLocalData(n){
              console.log(n);
              this.$boss.$emit("allnum",n.length);
              //这里是将数据存放到本地里去
              localStorage.setItem("cart",JSON.stringify(n));
          },
      
    • 通过setItem设置的时候需要使JSON.Stringfy()去将 JavaScript 值转换为 JavaScript 对象表示法 (JSON) 字符串

    • 通过getItem读取缓存的时候需要使用JSON.parse()去将将 JavaScript 对象表示法 (JSON) 字符串转换为对象