欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

如何修复在移动动表现差异很大的选择框---中级程序员研究

程序员文章站 2022-05-02 12:11:30
在移动端开发中,我们往往需要按照设计稿去高度还原效果图,并且实现交互方式,下面看一下一个标签的表现形式: select 在iOS中的表现: 但是在安卓上并不是这样的效果 交互表现得差异性需要优化,那么问题来了,怎么优化。如何去保持同一标签可以表现相同得样式和交互方式。其实这也是前端的重要工作之一:兼 ......

在移动端开发中,我们往往需要按照设计稿去高度还原效果图,并且实现交互方式,下面看一下一个标签的表现形式: select 

在ios中的表现:

如何修复在移动动表现差异很大的选择框---中级程序员研究

但是在安卓上并不是这样的效果

如何修复在移动动表现差异很大的选择框---中级程序员研究

 

 交互表现得差异性需要优化,那么问题来了,怎么优化。如何去保持同一标签可以表现相同得样式和交互方式。其实这也是前端的重要工作之一:兼容性和适配,也对应着招聘的要求之一:高度还原设计稿;言归正传,看到select不同的表现。我们如何实现这个替换呢?用过element-ui,iview等框架的小伙伴都知道,他们为了保持统一的表现,放弃了select,option;而是封装了自己的el-select 或者select; 

 

vant中的picker

element-ui

以上框架都实现了select的封装,但是在开放中,我们如果没有使用它们自身的框架,而是我们项目本身的框架,用起来很是费劲;大家都知道前端开发现在最火的是组件化开发,组件就是组件,可以快速移植和安装;最重要的是可以差异化这个组件,而且你也便于维护;安装其中的某个组件,你可能要花费30分钟去修改配置和调试,但是极有可能不会成功,这是很痛心、很扎心;

那么推荐下面一个最简单的替换组件,

这个组件昨天发布,对没有错就是我写的,支持 npm install yh-select ,目前只支持vue, 安装完成后,select option ,可以用一行标签搞定了,详情请看yh-select;(如果你想一起组队开发组件,那么请加微信xingguangbi,我们一起发布自己的组件)

修复不同的表现方式和交互方式,需要我们去替换产生差异的一些标签,用相同的标签去组装我们想要的效果:

下面分享一下我替换select的思路:

ul>li存放option的每一列,外面再来一个div包裹它,下拉的箭头实现,背景色去填充,不使用图片和字体图标,好处:尽量减少组件的依赖性,减少请求;

一个点击外部的指令

const clickoutsidecontext = "@@clickoutsidecontext";

export default {
  /*
   @param el 指令所绑定的元素
   @param binding {object} 
   @param vnode vue编译生成的虚拟节点
   */
  bind(el, binding, vnode) {
    const documenthandler = function(e) {
      if (!vnode.context || el.contains(e.target)) {
        return false;
      }
      if (binding.expression) {
        vnode.context[el[clickoutsidecontext].methodname](e);
      } else {
        el[clickoutsidecontext].bindingfn(e);
      }
    };
    el[clickoutsidecontext] = {
      documenthandler,
      methodname: binding.expression,
      bindingfn: binding.value
    };
    settimeout(() => {
      document.addeventlistener("click", documenthandler);
    }, 0);
  },
  update(el, binding) {
    el[clickoutsidecontext].methodname = binding.expression;
    el[clickoutsidecontext].bindingfn = binding.value;
  },
  unbind(el) {
    document.removeeventlistener(
      "click",
      el[clickoutsidecontext].documenthandler
    );
  }
};

 核心组件如下:

<template>
  <div
    v-clickoutside="handleclose"
    class="select-wrapper"
    @click.prevent="self"
    :class="{'active':selflag}"
    :style="{'z-index':min}"
  >
    <div class="inners">{{models[names]}}</div>
    <div class="arrow" @click.stop="self"></div>
    <ul v-show="selflag">
      <li
        :class="{'active':models.value==item.value}"
        v-for="(item,index) in options"
        :key="index"
        :value="item[val]"
        @click.stop="sels(item)"
      >{{item[names]}}</li>
    </ul>
  </div>
</template>
<script>
import clickoutside from "./close";
export default {
  directives: { clickoutside },
  model: {
    prop: "sel",
    event: "change"
  },
  props: ["options", "sel", "val", "names"],
  data() {
    return {
      selflag: false,
      models: "",
      min: 0
    };
  },
  methods: {
    self() {
      this.min = 100;
      this.selflag = !this.selflag;
    },
    init() {
      this.models = this.sel;
    },
    sels(item) {
      this.models = item;
      this.selflag = !this.selflag;
      this.$emit("change", item);
    },
    handleclose() {
      this.min = 0;
      this.selflag = false;
    }
  },
  mounted() {
    this.init();
  }
};
</script>
<style scoped>
.select-wrapper {
  width: 120px;
  border: 1px solid #999;
  padding: 2px 30px 0 5px;
  font-size: 12px;
  height: 18px;
  position: relative;
  z-index: -1;
}
.inners {
  padding-right: 30px;
  overflow: hidden;
}
.select-wrapper .arrow {
  position: absolute;
  top: 50%;
  right: 10px;
  z-index: 30;
  transform: translatey(-50%);
  border-top: 5px solid #999;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
}
.active {
  box-shadow: 0 0 3px #1e90ff;
}
.select-wrapper ul {
  list-style: none;
  margin: 0;
  padding: 0;
  width: fit-content;
  text-align: left;
  position: absolute;
  max-height: 160px;
  overflow-y: auto;
  bottom: 0;
  transform: translatey(101%);
  left: 0;
  z-index: 10;
  background: #fff;
  border: 1px solid #1e90ff;
  min-width: 100%;
}
.select-wrapper li {
  padding: 0 45px 0 0;
  background: #fff;
}
.select-wrapper li:hover {
  background: #1e90ff;
  color: #fff;
}
.select-wrapper li.active {
  background: #1e90ff;
  color: #fff;
}
</style>

  源码地址:我要下载源码 (如果喜欢,请记得star一下);

最后提供一个问题解答的机会,交流的微信群,可以一起交流学习,如果你想进入请加微信:xingguangbi(备注交流解答);