zoukankan      html  css  js  c++  java
  • 参考美团、饿了么 && localStorage

    localStorage使用。
     
         为什么要使用 localStorage? 
         因为在之前的讨论过程中,问题:每次添加一件商品和去掉一个商品都需要发送一个http请求来更新购物车,目的是为了在用户下次登录的时候可以记得购物车里的内容,这样, 如果用户选了之后即使没有付款,但是下次登录的时候仍然一打开页面我们就可以把localStorage中的内容显示出来,这样,用户体验会更好一些,比如饿了么在小程序上的做法就是这样,但是美团不是,美团并没有保存购物车中的内容, 而饿了么保存了,之所以可以判断使用的时localStorage,是因为我们在断网的情况下他也可以记录。 
         之所以可用,是因为在兼容性上也不存在问题,支持IE8,Android2.1(几乎是所有的了)、以及iOS3,所以兼容想上可以做。
         另外,localStorage可以存储JSON字符串,所以说数据也没有问题,并且本地的存储量在5M,足以满足我们的需求。 
         同样的,localStorage也存在跨域的问题,只能在一个网站下面使用,废话不多说,开始吧。 
         
         具体思路:
         当用户添加一件商品的时候,我们就把相应的商品的sbgaid值存储到localStorage中,并且因为使用localStorage也只需要购物车部分,我们现在有两种选择:
         一种是添加一个商品存储到一个键值对中; 删除一件商品,就删除一个键值对。
         优点: 比较简单,添加setItem, 删除removeItem。 缺点: 可能会比较乱, 全是一堆键值对。           
     
         还有一种做法是先新建一个对象,然后添加一个商品,就把键值对添加到这个对象上,然后在JSON.stringify,然后再存储到locolStorage中。 
         优点:  可能看上去可以整洁一些。 缺点: 需要不断的更新这个对象,然后就是转换和替换JOSN字符串,结果就是消耗性能。 
     
         师兄的意思是从商品中寻找localStorage,我们可以来使用localStorage的遍历方法判断是否相等来做。。 
         
         需要知道的时,我们需要存储的是什么? 一个是sbgaid,这个是每一个商品都不同的,所以可以作为键,那么值是什么呢? 当然就是用户需要买的数量了! 存储的过程中,如果add,就amount为1, 如果remove,那么就直接删除这个键值对即可。所以还是使用前者好一些。
         
         综合考虑两种,其实用户的购物车往往很少,所以即使是散的键值对,也不会很乱,影响不大,所以我决定最终采用第一种做法。  
     
     
    2017年6月19日更新
      目前项目的需求是做成微商厦的形式,所以说我们需要改变localStorage的存储形式,对应于不同的店铺都要有不同的k-v,大致如下所示:
        var sbid1 = {
            // 商品标记
            sbgaid1: {
              name: 'apple',
              number: 1,
              unitPrice: 25,
              unit: "",
              sbgaid: 'sbgaid1'
            },
            sbgaid2: {
              name: 'pear',
              number: 1,
              unitPrice: 85,
              unit: "",
              sbgaid: 'sbgaid2'
            },
            sbgaid3: {
              name: 'pig',
              number: 1,
              unitPrice: 5,
              unit: "",
              sbgaid: 'sbgaid3'
            },
            // 总价,在订单页刷新的时候是需要的。
            totalPrice: 115
        };
    
        var sbid2 =  {
            sbgaid1: {
              name: 'apple',
              number: 1,
              unitPrice: 25,
              unit: "哦哦",
              sbgaid: 'sbgaid1'
            },
            sbgaid2: {
              name: 'pear',
              number: 1,
              unitPrice: 5,
              unit: "",
              sbgaid: 'sbgaid2'
            },
            sbgaid3: {
              name: 'pig',
              number: 1,
              unitPrice: 15,
              unit: "",
              sbgaid: 'sbgaid3'
            },
            totalPrice: 45
        };
    
        // 存储方式二
        localStorage.setItem('sbid1', JSON.stringify(sbid1));
        localStorage.setItem('sbid2', JSON.stringify(sbid2));
    整体思路:
      一、
      首先解决添加商品和减去商品的问题,在添加商品的时候,首先检测当前的sbid是否存在,如果不存在就创建一个值为相应sbid的localStorage键值对,值为一个对象,然后对象中查看是否有相应的商品,如果有相应的商品,我们就直接给number++,如果没有相应的商品,我们就创建一个该商品的对象,并保存相应的信息。然后再存储。 如果是减去一个商品,就要直接减1,如果结果为0,那么删去对象的这个键就可以了。
     
     
     
     
     
     
     
     
     
     
     
     
      
     
    补充: 
      之前试了一下采用localStorage做购物车的页面,但是有一个问题很明显的出现了。
      还是要先说一说饿了么为什么要用localStorage,这是因为饿了么希望当用户某次选中某些产品之后,然后退出,在下次进来的时候可以显示出这些之前点击过的商品。 
      这一点很重要,我之前尝试的方法是采用组件懒加载的方式,也就是说,比如一个店家中五个分类,每个分类下大概有30件产品,当我进入主页时,我会自动把第一个分类下的产品显示出来10条(注意:不是显示完全)。 如下所示:
      
     
      然后获取到这些数据之后,就把数据存放到vue的store中,这样,下次用户再加载时,就可以使用使用store中的了。  
      如果我希望看到该分类下的更多,那么我一定会向下拉,这里我使用了懒加载,当用户拉到底部时,开始加载更多的数据,这样就避免了不必要的数据浪费。 
      当看其他分类下的产品时,比如我点击一下哈哈,这时又会发送一个ajax请求, 请求到这个页面下的前10条数据。 当我希望看更多时,拉到底部开始加载更多数据。 
      而这就有一个问题! --- 那就是如果暂时性的网络差,那么我可能已经点击了哈哈,但是界面还停留在蔬菜的内容上,这是因为vue的view是由数据驱动的,我这样的做法如果没有获取到数据, 那么界面就不会发生变化,这样的用户体验是非常的不好的。 所以这种方法不可取。 

       那么饿了么团队处理这种问题的思路是什么呢? 

       打开饿了么的web app,可以很容易发现,饿了么的思路如下:

      进入首页,先定位(这个无论是美团还是饿了么都是这么做的,优点是可以根据你的位置来提供附近的店家,但是缺点也是存在的,它占用带宽比较多,4g的网络还要加载一会,如果网络再差一点,那么几乎要卡死。), 定位成功之后就是推荐商家的界面,每一个店家是一个item,并且我们可以无限向下拉,这个界面采用了懒加载的方式,用户体验还是很不错的(除了之前说到的位置定位以外)。 对于这些店家的介绍无非是店名、评分、位置、月订单数、配送费、起送价格、 一些优惠政策等等。 

      进入其中的一个店家之后, 其上半部分是店家的介绍,下面是商品的罗列和可以左右切换的评分。 对于商品而言, 同样,左边是分类,右边是商品。主要说一说它的实现方式: 进入店家之后,先显示分类,然后显示出所有分类下的所有商品!!!! 而不是点击一个分类之后再发送ajax。 并且只有第一个分类的图片是事先加载好的。其他分类只是加载了基本的数据,而没有加载图片,我们通过断网就可以发现。并且无论一个分类下有几十件商品,他都是一次性加载完的,那么这样做的好处是什么呢? 我个人认为好处有以下几点:

    • 第一、 这是最为重要的一点 --- 一次性加载完所有的数据,我们就可以和本地的localStorage做比较,然后把用户上次选择过的商品标记出来,让用户快速看到之前选了的商品,因为比如我之前的做法,每次只加载一个分类的下的10件商品,那么这个分类下的其他商品由于没有请求,所以和本地的localStorage就无法比较,所以说我们就无法标记用户之前的购物车内容。并且利用localStorage的方式可以节省不少带宽,很好用。 而如果一次全部加载完成,那么我们就可以直接标记处所有了。 
    • 第二、 这样做所浪费的带宽并不多,读取localStorage的性能消耗应该是可以接受的。 因为对于其他分类下的产品我们没有下载图片,而只是接受一下数据而已,比如这个店家共有五个分类,那么我们只不过就多使用了4个http请求而已,为什么这么说呢? 因为我们一下请求了所有的商品,关键是没有请求图片,我们知道一个图片就要发送一个http请求,并且图片的大小往往要比数据大得多!!! 所以这种方法是可取的。 只要我们能够解决如何做到只请求数据,而不请求图片即可。再说一下localStorage消耗的性能问题 --- 首先说明: 购物车一定是从商品来匹配购物车的内容,即接收到一个数据,然后遍历购物车即可。一般用户的购物车不可能有太多商品,所以一个数据循环那么几个localStorage,几乎是不怎么消耗性能的,这点我觉得不必担心。 
    • 第三、大大提高了用户体验。 为什么这么说呢?  之前我提到过我的做法的问题,就是点击一个分类请求其中的内容并显示, 这样的缺点在于 --- 如果在网络较差的情况下,我们所得到的内容可能还是原来的,还没有被替换。 但是如果使用这种方式,一个很大的好处就是 --- 因为已经获得了所有数据,所以在切换上面数据的更新是很快的,完全不存在延迟的问题,而图片的加载就取决于你的网络情况了,但是大多数情况下,我们并不在意图片是否显示,可能我们只是看到名字之后就下单了,所以这对于提高用户体验的帮助非常的大!   

      

        总而言之,可以采取这种思路! 用户体验必然得到大幅度的提高!!!!

       但是使用这种方式,存在哪些亟待解决的问题呢?

    • 首先, 应该解决请求时的pageSize问题,如何做到一次性获取所有的数据? 
    • 如何做到对于其他的分类只请求数据,而不请求图片?
    • 是否需要所谓的复选框? 美团、饿了么都是没有的,并且意义可能不大! 
    • 首页是否需要添加更多的内容呢?   
    • 微信小程序的开发需要吗? 还是挺愿意做一个小程序的。 

        回答问题

    • 如果商家中的商品有10000条,那么我们可能返回10000条数据吗? 那是不可能的,所以不可能让后端做到一下返回这么多数据。 另外,如果数据库有脏数据,那么显然也是不适合的,所以任忠锋师兄的建议是取一个比较大的数字就可以了,比如50条数据, 对于一般的商家而言,50条数据往往就代表了这个分类下的所有数据。
    • 只请求数据,不请求图片可以使用 jqury插件 lazyload, 当然对于vue也是一样的。
    • 还是需要复选框的,毕竟如果做好了,那么后面想要用就用,不想要用就算了。 
    • 根据任忠锋师兄的想法首页可能需要添加一些优惠信息。 
    • 微信小程序实际上可以在这个项目做完之后着手做了,如果可以实现相同的功能,那么何乐而不为呢? 

      

      在尝试这个方法的过程中,我还是不可避免的遇到了问题。 其实也不是问题,只是我之前的想法可能出现了偏差。 比如说,对于用这个方式我们来分析一下图片是怎么加载的。 即一进入之后首先加载了必须要加载的东西。 

      并且可以看到加载其他种类的商品数据只发了3个http请求,并且请求到的数据量是很小的,所以这种思路是绝对划得来的。   

      

      对于饿了么,我们还可以发现它做的一个比较好的地方,那就是在进入一个店铺之后,用户体验做的是真的很棒,比如我先进入这个店,它此时并没有获取图片,而是等到获取了所有的分类之后才开始获取图片。如果不是这样做,那么我们很有可能在得到其他分类的时间会非常长。 

      即进入店铺,优先获取所有分类下的所有商品的数据,这是第一步,第二步才是获取第一个分类下的图片。 

      

     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    fetch的使用--当无法判断后台返回数据为什么类型时如何操作
    单页面与多页面间的区别及优缺点
    关于倒计时在关屏后不准确的问题
    前端分页仿百度分页效果
    pc端的弹性布局适配方案
    前端性能优化方向
    居民身份证号码组成规则
    axios简单介绍
    es6 promise 简单总结
    js原型链和原型链的继承
  • 原文地址:https://www.cnblogs.com/zhuzhenwei918/p/6931416.html
Copyright © 2011-2022 走看看