仿照旧版支付宝生活服务模块-常用应用的添加与删减(下)

先上效果图

 

稍稍解释一下: 

  由于截屏不到点击时状态效果,姑且用红色框框代表点击时效果

 

实现原理:

  1. 首先从样式上看,分两种状态: 编辑时与完成时,这两种状态的样式需要先写好,通过变量控制类名去实现
  2. 下面列表中每一个应用都有2种状态:+/- 这里可以给每个元素一个默认变量值为false,改变时变为true
  3. 核心算法就是使用数组的slice,concat方法,去删除数组arr中下标为d的元素,
    // 删除下标为d的元素
    arrDel(arr, d) {
       // arr.slice(s,e) s起始索引 e结束索引  返回值: 被删除的元素数组
       return arr.slice(0, d).concat(arr.slice(d + 1));
    },

  这个函数简直吊炸天,有没有,不过不是姐想的,是姐的leader创造的,简直不要太好用~

 

  好了,言归正传,来说第4条:

  4.还用了一个点睛之笔的方法,就是烂大街的: arr.indexOf(a)

  • 没错他就是用来判断 arr 是否包含 a,我们通常用 ==-1 来表示不包含
  • 殊不知包含状态下会返回a在arr的下标值
  • 如 [1,2,3,4].indexOf(3) = 2   2就是3在数组中的索引值
  • 有了这个索引值就可以与 arrDel函数配置使用,达到王炸的效果

 

原理已说完,上代码

html:

    <!-- 常用应用 -->
    <div class="commonOption">
      <div class="title_box">
        <div class="title">常用应用</div>
        <div class="edit" @click.this="changeName">{{editDesc}}</div>
      </div>
      <!-- 常用应用列表 -->
      <ul class="common_list">
        <li class="common_item" v-for="(citem,cindex) in commonList" :key="cindex">
          <div class="apply_box" @click="goCommonPage(citem)" :class="{'selectStatus':isEdit}">
            <i
              :style="{background:`url(${require(`@/assets/images/life/index/${citem.icon_name}.png`)}) no-repeat center/100%`}"
              class="apply_icon"
            ></i>
            <p class="apply_name">{{citem.content_name}}</p>
            <i class="sub_icon" v-if="isEdit"></i>
          </div>
        </li>
      </ul>
      <div class="line"></div>
    </div>


   <!-- 内容列表 -->
    <ul
      :class="['content_list_box',{'contentFixed':Fixed}]"
      :style="{height:(screenHeight + lastTop - 260) + 'px'}"
    >
      <li
        v-for="(item,index) in contentBox"
        :key="index"
        class="content_list_item"
        @scroll="contentScroll(index)"
        ref="contentRef"
        @click="goPage(item)"
      >
        <div class="content_title" v-if="index" ref="contentBox">{{item.title}}</div>
        <div class="content_box">
          <div
            v-for="(subItem,subIndex) in item.contentList"
            :key="subIndex"
            class="content_item"
            @click="goLifePage(subItem,subIndex)"
          >
            <div class="item_inner" :class="{'selectStatus':isEdit}">
              <i
                :style="{background:`url(${require(`@/assets/images/life/index/${subItem.icon_name}.png`)}) no-repeat center/100%`}"
                class="icon"
              ></i>
              <p class="content_name">{{subItem.content_name}}</p>
              <i class="jia_icon" v-if="isEdit" :class="{'jianIcon':subItem.changeIcon}"></i>
            </div>
          </div>
        </div>
        <div class="line" v-if="index<contentBox.length-1"></div>
      </li>
    </ul>

 

js:

data() {
    return {
      contentBox: [
        {
          type: "videoEnt",
          title: "视频娱乐",
          contentList: [
            {
              type: "iqiyiVideo",
              icon_name: "aiqiyi@2x",
              content_name: "爱奇艺",
              changeIcon: false
            },
            {
              type: "tencentVideo",
              icon_name: "tengxunshipin@2x",
              content_name: "腾讯视频",
              changeIcon: false
            },
            {
              type: "youkuVideo",
              icon_name: "youkushipin@2x",
              content_name: "优酷视频",
              changeIcon: false
            }
          ]
        },
        {
          title: "卡密相关",
          contentList: [
            {
              type: "jingdongEcard",
              icon_name: "jingdongeka@2x",
              content_name: "京东E卡卡密",
              changeIcon: false
            },
            {
              type: "wangyiEcard",
              icon_name: "wangyi@2x",
              content_name: "网易严选",
              changeIcon: false
            }
          ]
        },
        {
          title: "充值中心",
          contentList: [
            {
              type: "FlowRecharge",
              icon_name: "liuliang@2x",
              content_name: "流量充值",
              changeIcon: false
            },
            {
              type: "PhoneRecharge",
              icon_name: "huafei@2x",
              content_name: "话费充值",
              changeIcon: false
            }
          ]
        },
        {
          title: "生活缴费",
          contentList: [
            {
              type: "lifePayment",
              icon_name: "shuifei@2x",
              content_name: "水费查缴",
              changeIcon: false
            },
            {
              type: "lifePayment",
              icon_name: "dianfei@2x",
              content_name: "电费查缴",
              changeIcon: false
            },
            {
              type: "lifePayment",
              icon_name: "ranqi@2x",
              content_name: "燃气查缴",
              changeIcon: false
            }
          ]
        },
        {
          title: "车务交罚",
          contentList: [
            {
              type: "violationSearch",
              icon_name: "chaxun@2x",
              content_name: "违章查询",
              changeIcon: false
            },
            {
              type: "violationPay",
              icon_name: "jiaofei@2x",
              content_name: "违章缴费",
              changeIcon: false
            }
          ]
        },
        {
          type: "",
          title: "生活服务",
          contentList: [
            {
              type: "weather",
              icon_name: "zhiliang@2x",
              content_name: "天气预报",
              changeIcon: false
            },
            {
              type: "aqi",
              icon_name: "yubao@2x",
              content_name: "空气质量",
              changeIcon: false
            }
          ]
        }
      ], 
      commonList:
        JSON.parse(
          window.localStorage.getItem("commonList") &&
            window.localStorage.getItem("commonList") == "undefined"
            ? "[]"
            : window.localStorage.getItem("commonList")
        ) || [], // 常用列表
      editDesc: "编辑", // 按钮字体
      isEdit: false, // 是否编辑状态
    };
  },

created() {
    this.dealInit();
  },

methods: {
    //初始化图标--将列表中已存在于常用应用中的图标+改成-
    dealInit() {
      // 改变旧的数组一般使用foreach,想要获取新的数组就用map
      let keys = this.commonList.map(res => res.content_name);
      this.contentBox.forEach(item => {
        if (item.contentList) {
          item.contentList.forEach(res => {
            res.changeIcon =
              keys.indexOf(res.content_name) !== -1 ? true : false;
          });
        }
      });
    },
    // 常用应用取消并跳转
    goCommonPage(citem) {
      if (this.isEdit) {
        this.dealShift(citem);
      } else {
        this.goPage(citem);
      }
    },
    // 列表中应用添加到 常用应用
    goLifePage(item) {
      if (this.isEdit) {
        if (this.commonList && this.commonList.length >= 8) {
          this.$Toast("最多可添加8个应用");
          return false;
        }
        // 加数据
        this.dealShift(item);
      } else {
        this.goPage(item);
      }
    },
    // 删除/添加 常用应用
    dealShift(item = null) {
      // indexOf的一个巧妙的用处:判断数组中是否包含该元素时,= -1 代表不包含,>-1时 代表获取的元素在数组中的下标
      // 通过indexOf获取下标,即可不需要考虑下标从何而来
      if (Array.isArray(this.commonList)) {
        // 获取常用应用中以名字组成的数组
        let keys = this.commonList.map(res => res.content_name);
        // 判断当前点击应用是否被包含在常用应用中-是则返回索引值,否则返回-1
        let index = keys.indexOf(item.content_name);
        //存在时,点击后就-变成+
        if (index !== -1) {
          item.changeIcon = false;
          this.commonList = this.arrDel(this.commonList, index);
        } 
        //不存在,点击后就+变成减-
        else { 
          if (item) {
            item.changeIcon = true;
            this.commonList.push(item);
          }
        }
        window.localStorage.setItem(
          "commonList",
          JSON.stringify(this.commonList)
        );
      }
    },
    // 删除下标为d的元素
    arrDel(arr, d) {
      // arr.slice(s,e) s起始索引 e结束索引  返回值: 被删除的元素数组
      return arr.slice(0, d).concat(arr.slice(d + 1));
    },

    // 更换字段
    changeName() {
      if (this.editDesc === "编辑") {
        this.editDesc = "完成";
        this.isEdit = true;
      } else {
        this.editDesc = "编辑";
        this.isEdit = false;
      }
    },
}

 

分享一刻:

一位大佬的书: 《The Pragmatic Programmer》《程序员修炼之道》

https://caicaishmily.gitbooks.io/pragmatic_programmer/content/Chapter1/%E5%8A%A1%E5%AE%9E%E4%B8%BB%E4%B9%89%E5%93%B2%E5%AD%A6.html

 

posted @ 2020-05-09 15:35  银翘解毒片  阅读(383)  评论(2编辑  收藏  举报