zoukankan      html  css  js  c++  java
  • 仿照旧版支付宝生活服务模块-常用应用的添加与删减(下)

    先上效果图

    稍稍解释一下: 

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

    实现原理:

    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

  • 相关阅读:
    iOS内购开发(也许是最全的介绍)
    React Native 学习(三)之 FlexBox 布局
    React Native组件解析(二)之Text
    苹果开发者账号(个人、公司、企业)的区别
    React Native学习(二)之View
    搭建React Native开发环境
    iOS 提交AppStore不出现构建的版本
    Python使用Mysql过程中一些错误
    数据分析之漏斗模型
    项目管理之敏捷方式(我们的方式)
  • 原文地址:https://www.cnblogs.com/huangaiya/p/12857659.html
Copyright © 2011-2022 走看看