展示 element-ui 项目中移动端适配组件及代码修改
页面布局组件
通过col和row实现对页面进行24栏栅格布局,但在移动端,栅格会出现过小的现象,因此限制span和gutter以及flex等属性在pc端有效。 分栏偏移会使得移动端布局超出屏幕,因此也限制了offset以及响应式布局的属性等在pc端有效。
export default {
computed : {
userAgentMobile ( ) {
return window. innerWidth <= 720 ;
}
} ,
render ( h ) {
return h ( this . tag, {
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} ` : ''
] ,
style : ! this . userAgentMobile ? this . style : { }
} , this . $slots. default) ;
}
}
export default {
computed : {
userAgentMobile ( ) {
return window. innerWidth <= 720 ;
}
} ,
render ( h ) {
let classList = [ ] ;
let style = { } ;
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表单组件
form 表单组件默认的label和content是左右结构,如果label过长,在移动端就会导致content过小,因此将form表单在移动端(屏幕宽度小于720px)改为上下结构。由于form表单为我们提供了label与content相对位置为上下结构的样式和属性,因此只需要在移动端将label改为top模式即可。 form表单提供了inline行内表单样式,在移动端会由于inline-block的设置导致form表单项错乱。因此将移动端的行内样式取消。
< template>
< 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 : {
labelPositionMobile ( ) {
return this . userAgentMobile ? 'top' : this . labelPosition
}
} ,
created ( ) {
this . userAgentMobile = window. innerWidth <= 720
}
}
</ script>
< script>
export default {
computed : {
labelStyle ( ) {
const ret = { } ;
if ( this . form. labelPositionMobile === 'top' ) return ret;
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;
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组件
dialog组件提供了width属性让使用者可以自定义弹框窗口的宽度,但是在移动端,该属性可能导致弹框窗口超出移动端屏幕的现象,因此将移动端弹框窗口宽度默认设置为80%。 此外本次修改还提供了为移动端设置弹框窗口宽度的属性mobileEndWidth,可通过该属性自定义移动端窗口的大小。
< script>
export default {
props : {
mobileEndWidth : {
default : '80%' ,
type : String
} ,
} ,
data ( ) {
return {
userAgentMobile : '' ,
}
} ,
computed : {
style ( ) {
let style = { } ;
if ( ! this . fullscreen) {
style. marginTop = this . top;
if ( ! this . userAgentMobile) {
if ( this . width) {
style. width = this . width;
}
} else {
style. width = this . mobileEndWidth
}
}
return style;
}
} ,
created ( ) {
this . userAgentMobile = window. innerWidth <= 720
} ,
}
< / script>
popover组件
弹出款组件同dialog组件类似,提供了width属性让使用者可以自定义弹框窗口的宽度,将移动端弹框窗口宽度默认设置为70%。 本次修改还提供了为移动端设置弹框窗口宽度的属性mobileEndWidth,可通过该属性自定义移动端窗口的大小。
< template>
< span>
< 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 : {
mobileEndWidth : {
default : '70%' ,
type : String
}
} ,
computed : {
style ( ) {
let style = { } ;
if ( window. innerWidth <= 720 ) {
style. width = this . mobileEndWidth
} else {
if ( this . width) {
style. width = this . width
}
}
return style;
}
}
}
</ script>
message组件
message组件内置了最小宽度为380px,在移动端可能存在超出屏幕的情况,因此设置移动端时最小宽度大小为80%。
// message.scss修改内容
@include b ( message) {
// 添加媒体查询规则,设置当屏幕最大宽度为475时最小宽度设为80%
@media screen and ( max-width : 475px) {
min-width : 80%;
}
}
message-box组件
message组件内置了宽度为420px,在移动端可能存在超出屏幕的情况,因此设置移动端时宽度大小为80%。
@include b ( message-box) {
// 添加媒体查询规则,设置当屏幕最大宽度为525px时宽度设为80%
@media screen and ( max-width : 525px) {
width : 80%;
}
}
cascader组件
该组件设置了每一级过滤框最小宽度为180px,在移动端可能存在超出屏幕的情况,因此设置pc端时最小宽度生效。
// cascader-panel.sccc 修改内容
@include b ( cascader-menu) {
// 修改min-width : 180px; 为媒体查询规则,屏幕最小宽度为720px时方可设置该元素的最小宽度
@media screen and ( min-width : 720px) {
min-width : 180px;
}
}
notification组件
该组件设置了宽度为330px,在移动端可能存在超出屏幕的情况,因此设置移动端时宽度大小为70%。
// notification.scss 修改内容
@include b ( notification) {
// // 添加媒体查询规则,设置当屏幕最大宽度为475px时宽度设为70%
@media screen and ( max-width : 475px) {
width : 70%;
}
}