需要
开发一个平台需要在PC端和移动端都有良好的体验。
思路
同时适配移动端和PC端一般主要有两种思路:
一组资源,根据是否是联通设备选择加载不同的css。 两套资源,一套PC端,一套移动端,分别维护,在入口处进入不同的路线。
两种方式的区别在于,前者在风格层面分为pc和mobile,后者在页面层面分为pc和mobile
这两种方法各自的特点:
1、前者适合两端交互、布局差异不大、交互比较简单的项目。 只有一套资源,代码量少,维护也比较简单。
2、后者适合两端交互方式、布局差异较大、设计要求高、扩展性要求高的项目。 两套资源代码量较大,前期配置相对复杂,但两端互不影响,开发时无需考虑太多。
一套资源解决方案
由于当前项目需要快速开发、快速落地,两端的设计稿布局相差不大。 所以采用第一种形式。 实现如下:
步骤1.确定终端设备类型。
在main.js中配置,用于在页面加载前判断终端设备类型。
navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)
2.拆分两组css文件。
PC使用px为单位,移动使用rem和vw组合,在移动端css文件中,设置item font-size,例如设计稿为375px的情况下,html {font-size: calc (100vw/37.5)} 当时联通设备可见窗口大小为375px时,html的font-size为10px,则1rem=10px。
styles的结构如下:css分为pc端和mobile端两套,每个开发者都有自己的两套css文件。
// mobile.scss
@import './mobile/hm-mobile.scss';
@import './mobile/tf-mobile.scss';
.no-mobile {
display: none;
}
html {
font-size: calc(100vw/37.5);
}
// pc.scss
@import './pc/hm-pc.scss';
@import './pc/tf-pc.scss';
.no-pc {
display: none;
}
3.加载两组css文件
通过判断终端类型,加载不同的css文件,
// main.js配置
import { _isMobile } from '@/utils/utils';
...
...
...
if (_isMobile()) {
require('./styles/mobile.scss');
console.log('mobile');
} else {
console.log('pc');
require('./styles/pc.scss');
}
越来越需要注意的是,样式都是写在全局样式文件中的。 多人协作开发时,需要指出命名约定,防止命名污染。 您可以参考**BEM命名规范**
为什么不使用媒体查询并依靠一套CSS来同时处理PC和移动设备呢? 笔者认为同一套CSS会让耦合度太高,后期维护两端会很麻烦,如果必须把两端的项目拆分开,成本就会降低。 因此网站模板电脑端,在两套CSS的前提下,一端可以实现响应式。 例如,可以为PC端做大、中、小屏的响应式,而不是直接从PC跨到移动端。
两套资源计划
基于两套资源的思想,虽然实现方式有很多种,
这几天网友为自己的项目提供的一套解决方案(两端分开配置):
核心是通过两套资源+判断客户端类型+路由守卫来进行
步骤 1. 限制路由的规范(路由防护的基础) 2. 路由防护
重定向的页面通过meta类型进行拦截,防止直接输入URL导致的跨端访问。 跨端访问时,强制拦截并跳转到属于本地类型的同一页面。 比如用手机访问p_index时,会跳转到m_index。 因此,不仅要设置meta网站模板电脑端,而且两端的页面路由也要有一定的规则。 这里可以做也可以不做,直接拦截跳转到这个终端的首页即可。
3.根据终端类型动态添加网页meta并使用第三方插件
// main.js
if (/Android|webOS|iPhone|iPod|BlackBerry|iPad/i.test(navigator.userAgent)) {
Vue.use(VueTouch, { name: 'v-touch' });
VueTouch.config.swipe = {
threshold: 50
};
var oMeta = document.createElement('meta');
oMeta.content = 'width=device-width, initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0, user-scalable=0';
oMeta.name = 'viewport';
document.getElementsByTagName('head')[0].appendChild(oMeta);
}
4.Postcss-pxtorem排除影响
由于项目需要,PC和联通均采用REM开发,均使用px转rem插件,但两端px转rem的转换基础不同,两端相互影响需要排除。
//vue.config.js
const config = {
// ...
css: {
extract: true,
loaderOptions: {
postcss: {
plugins: [
require('postcss-pxtorem')({
rootValue: 192,
exclude: /node_modules/vant|mobile/i, // 排除mobile和vant库
propList: ['*'],
selectorBlackList: ['.van-'] // 排除移动端使用了vant库
}),
require('postcss-pxtorem')({
rootValue: 37.5,
exclude: 'pc', // 排除pc
propList: ['*']
})
]
}
}
}
};
module.exports = config;