element-ui 移动端适配修改

展示 element-ui 项目中移动端适配组件及代码修改

页面布局组件

  1. 通过col和row实现对页面进行24栏栅格布局,但在移动端,栅格会出现过小的现象,因此限制span和gutter以及flex等属性在pc端有效。
  2. 分栏偏移会使得移动端布局超出屏幕,因此也限制了offset以及响应式布局的属性等在pc端有效。
// row.js 修改内容
export default {
  computed: {
    // 新增用户设备是移动端的属性
    userAgentMobile() {
      return window.innerWidth <= 720;
    }
  },
  render(h) {
    return h(this.tag, {
        // 限制属性flex的实现只有在pc端的情况下才有效
      class: [
        'el-row',
        { 'el-row--flex': !this.userAgentMobile && this.type === 'flex' },
        this.justify !== 'start' && !this.userAgentMobile ? `is-justify-${this.justify}` : '',
        this.align !== 'top' && !this.userAgentMobile ? `is-align-${this.align}` : ''
      ],
      // 限制属性gutter只在pc端有效  
      style: !this.userAgentMobile ? this.style : {}
    }, this.$slots.default);
  }
}
// col.js 修改内容
export default {
  computed: {
    userAgentMobile() { // 计算当前窗口否是移动端
      return window.innerWidth <= 720;
    }
  },
  render(h) {
    let classList = [];
    let style = {};
    // 限制下列属性在pc端有效
    if (!this.userAgentMobile) {
      if (this.gutter) {
        style.paddingLeft = this.gutter / 2 + 'px';
        style.paddingRight = style.paddingLeft;
      }

      ['span', 'offset', 'pull', 'push'].forEach(prop => {
        if (this[prop] || this[prop] === 0) {
          classList.push(
            prop !== 'span'
              ? `el-col-${prop}-${this[prop]}`
              : `el-col-${this[prop]}`
          );
        }
      });

      ['xs', 'sm', 'md', 'lg', 'xl'].forEach(size => {
        if (typeof this[size] === 'number') {
          classList.push(`el-col-${size}-${this[size]}`);
        } else if (typeof this[size] === 'object') {
          let props = this[size];
          Object.keys(props).forEach(prop => {
            classList.push(
              prop !== 'span'
                ? `el-col-${size}-${prop}-${props[prop]}`
                : `el-col-${size}-${props[prop]}`
            );
          });
        }
      });
    }

    return h(this.tag, {
      class: ['el-col', classList],
      style
    }, this.$slots.default);
  }
}

form表单组件

  1. form 表单组件默认的label和content是左右结构,如果label过长,在移动端就会导致content过小,因此将form表单在移动端(屏幕宽度小于720px)改为上下结构。由于form表单为我们提供了label与content相对位置为上下结构的样式和属性,因此只需要在移动端将label改为top模式即可。
  2. form表单提供了inline行内表单样式,在移动端会由于inline-block的设置导致form表单项错乱。因此将移动端的行内样式取消。
<template>
  <!--form.vue修改内容-->
  <!--labelPosition改为labelPositionMobiel适配移动端-->
  <!--el-form-inline仅在pc端生效-->
  <form class="el-form" :class="[
    labelPositionMobile ? 'el-form--label-' + labelPositionMobile : '',
    { 'el-form--inline': !userAgentMobile && inline }
  ]">
    <slot></slot>
  </form>
</template>
<script>
  export default {
    data() {
      return {
        userAgentMobile: '' // 新增用户设备是移动端的属性
      }
    }
    computed: {
      // 如果是移动端form表单的label位置属性为top,否则根据传来的labelPosition值设置
      labelPositionMobile() {
        return this.userAgentMobile ? 'top' : this.labelPosition
      }
    },
    created() {
      // 根据屏幕大小计算移动端
      this.userAgentMobile = window.innerWidth <= 720
    }
  }
</script>
// form-item.vue 修改内容
<script>
  export default {
    computed: {
      labelStyle() {
        const ret = {};
        if (this.form.labelPositionMobile === 'top') return ret; // labelPosition改为labelPositionMobile
        const labelWidth = this.labelWidth || this.form.labelWidth;
        if (labelWidth) {
          ret.width = labelWidth;
        }
        return ret;
      },
      contentStyle() {
        const ret = {};
        const label = this.label;
        if (this.form.labelPositionMobile === 'top' || this.form.inline) return ret; // labelPosition改为labelPositionMobile
        if (!label && !this.labelWidth && this.isNested) return ret;
        const labelWidth = this.labelWidth || this.form.labelWidth;
        if (labelWidth === 'auto') {
          if (this.labelWidth === 'auto') {
            ret.marginLeft = this.computedLabelWidth;
          } else if (this.form.labelWidth === 'auto') {
            ret.marginLeft = this.elForm.autoLabelWidth;
          }
        } else {
          ret.marginLeft = labelWidth;
        }
        return ret;
      },
    }
  }
</script>

dialog组件

  1. dialog组件提供了width属性让使用者可以自定义弹框窗口的宽度,但是在移动端,该属性可能导致弹框窗口超出移动端屏幕的现象,因此将移动端弹框窗口宽度默认设置为80%。
  2. 此外本次修改还提供了为移动端设置弹框窗口宽度的属性mobileEndWidth,可通过该属性自定义移动端窗口的大小。
// /dialog/src/component.vue 修改内容
<script>
  export default {
    props: {
      // 添加移动端弹框宽度属性,默认为80%
      mobileEndWidth: {
        default: '80%',
        type: String
      },
    },
    data() {
      return {
        userAgentMobile: '', // 新增用户设备是移动端的属性
      }
    },
    computed: {
      style() {
        let style = {};
        if (!this.fullscreen) {
          style.marginTop = this.top;
          if (!this.userAgentMobile) { // pc端时
            if (this.width) { // 传入的width属性有值
              style.width = this.width; // 弹框宽度为width定义的宽度
            }
          } else { // 移动端
            style.width = this.mobileEndWidth // 移动端窗口宽度属性的值
          }
        }
        return style;
      }
    },
    created() {
      this.userAgentMobile = window.innerWidth <= 720 // 检测当前屏幕大小是移动端
    },
  }
</script>

popover组件

  1. 弹出款组件同dialog组件类似,提供了width属性让使用者可以自定义弹框窗口的宽度,将移动端弹框窗口宽度默认设置为70%。
  2. 本次修改还提供了为移动端设置弹框窗口宽度的属性mobileEndWidth,可通过该属性自定义移动端窗口的大小。
<!-- /popover/src/main.vue修改内容 -->
<template>
  <span>
    <!-- :style="{ width: width + 'px' }" 修改为 :style="style" -->
    <transition
      :name="transition"
      @after-enter="handleAfterEnter"
      @after-leave="handleAfterLeave">
      <div
        class="el-popover el-popper"
        :class="[popperClass, content && 'el-popover--plain']"
        ref="popper"
        v-show="!disabled && showPopper"
        :style="style"
        role="tooltip"
        :id="tooltipId"
        :aria-hidden="(disabled || !showPopper) ? 'true' : 'false'"
      >
        <div class="el-popover__title" v-if="title" v-text="title"></div>
        <slot>{{ content }}</slot>
      </div>
    </transition>
    <span class="el-popover__reference-wrapper" ref="wrapper" >
      <slot name="reference"></slot>
    </span>
  </span>
</template>
<script>
  export default {
    props: {
      // 添加移动端弹框宽度属性,默认为70%
      mobileEndWidth: {
        default: '70%',
        type: String
      }
    },
    computed: {
      // 新增style计算属性,定义弹出框的宽度
      style() {
        let style = {};
        if (window.innerWidth <= 720) {
          style.width = this.mobileEndWidth // 移动端的弹出框宽度
        } else {
          if (this.width) {
            style.width = this.width // pc端的自定义弹出框宽度
          }
        }
        return style;
      }
    }
  }
</script>

message组件

  1. message组件内置了最小宽度为380px,在移动端可能存在超出屏幕的情况,因此设置移动端时最小宽度大小为80%。
// message.scss修改内容
@include b(message) {
  // 添加媒体查询规则,设置当屏幕最大宽度为475时最小宽度设为80%
  @media screen and (max-width: 475px) {
    min-width: 80%;
  }
}

message-box组件

  1. message组件内置了宽度为420px,在移动端可能存在超出屏幕的情况,因此设置移动端时宽度大小为80%。
@include b(message-box) {
   // 添加媒体查询规则,设置当屏幕最大宽度为525px时宽度设为80%
  @media screen and (max-width: 525px) {
    width: 80%;
  }
}

cascader组件

  1. 该组件设置了每一级过滤框最小宽度为180px,在移动端可能存在超出屏幕的情况,因此设置pc端时最小宽度生效。
// cascader-panel.sccc 修改内容
@include b(cascader-menu) {
  // 修改min-width: 180px;为媒体查询规则,屏幕最小宽度为720px时方可设置该元素的最小宽度
  @media screen and (min-width: 720px){
    min-width: 180px;
  }
}

notification组件

  1. 该组件设置了宽度为330px,在移动端可能存在超出屏幕的情况,因此设置移动端时宽度大小为70%。
// notification.scss 修改内容
@include b(notification) {
  // // 添加媒体查询规则,设置当屏幕最大宽度为475px时宽度设为70%
  @media screen and (max-width: 475px) {
    width: 70%;
  }
}
  • 7
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值