移动端最强适配px2rem 以及 结合Vuex实现简单loading加载效果
关注公众号: 微信搜索 web全栈进阶
; 收货更多的干货
一、rem之px2rem适配
1、 相信许多小伙伴上手移动端时面对各式各样的适配方案,挑选出一个自己觉得简便、实用、高效的适配方案是件很纠结的事情。 深有体会...
2、 经过多个移动端项目从最初的 viewport
--> 百分比
--> rem
--> rem
的升级版px2rem
可谓是一步一个坑 ,在px2rem
之前总觉得之前的不够完美或者麻烦;
二、进入正题
进入正题: 首先 px2rem
也是基于 rem
适配的,但是他的好用之处在于灵活、简便、高效不用我们自己去换算、px2rem-loader
会帮我们换算转换成rem
适配各种机型;
1、安装 px2rem-loader
(webpack
构建的项目)
npm i px2rem-loader --save-dev
or
yarn add px2rem-loader
2、安装 lib-flexible
(移动端自适应)
npm i lib-flexible --save-dev
or
yarn add lib-flexible
3、main.js
引入lib-flexible
import 'lib-flexible'
4、Html
配置viewprot
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0,minimum-scale=1.0,maximum=scale=1.0">
5、build/utils.js
文件配置 px2rem-loader
// utils.js
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
/* px2rem */
const px2remLoader = {
loader: 'px2rem-loader',
options: {
remUnit: 75 // 设计稿宽度/10 remUnit的值自定义多少都无所谓,最终都会转换成相应的rem 设计稿参照iphone的话推荐75 或者100
}
};
/* 添加到loaders数组中 */
function generateLoaders(loader, loaderOptions) {
const loaders = [cssLoader, px2remLoader]
}
用法: 标注图即量即所得;设计稿量多少就可以写多少了;
最终显示时: px2remLoader
会转换成相应的 rem
代码: font-size: 40px
;
浏览器控制台: font-size: 0.533333rem
;
即:40/75
因为上面写的是75
完全不用自己去转换了!爽多了
6、小坑:当 border
或者 height
为1px
时 你会发现最终转换下页面看不到了 ;
解决如下
// 后面加个注释 /*no*/ 目的是告诉 px2remLoader 这个不用做转换
border: 1px solid #e6e6e6; /*no*/
三、结合Vuex
自定义loading
组件
1、这里只说如何实现,具体的vuex
怎么使用注册请看以往博文 https://www.cnblogs.com/ljx20180807/p/9838259.html
// loading.vue
<template>
<!--loading-->
<div class="comp-loading">
<div class="comp-loading-box">
<img src="@/assets/img/loading.png"/>
<p>Loading...</p>
</div>
</div>
</template>
<style lang="stylus" rel="stylesheet/stylus" scoped>
.comp-loading {
&-box {
z-index: 10000;
position: fixed;
top: 40%;
left: 50%;
width: 160px;
margin-left: -80px;
padding: 30px 0;
border-radius: 10px;
background-color: rgba(0,0,0,.7);
img {
display: block;
width: 60px;
height: 60px;
margin: 0 auto;
animation: comp-loading-spin 1200ms infinite linear;
}
p {
font-size: 26px;
color: #fff;
text-align: center;
line-height: 26px;
padding-top: 14px;
}
}
}
@keyframes comp-loading-spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
App.vue
<template>
<!-- App.vue -->
<div id="app">
<!--loading-->
<Loading v-show="showHttpLoading"></Loading>
<router-view v-wechat-title="$route.meta.title"></router-view>
</div>
</template>
<script>
import Loading from './components/loading'
import error from './services/error'
export default {
name: 'App',
data () {
return {
showHttpLoading: false
}
},
components: {
Loading
},
watch: {
// 监听 showHttpLoading 触发loading效果
'$store.state.showHttpLoading' (val) {
// set loading
this.showHttpLoading = val
}
}
}
</script>
在哪里调用呢
;我项目是在所有请求的时候和路由跳转的时候调用;
请求成功则关闭loading
;具体效果可根据你公司需求确认
2、编写显示、隐藏规则 config.js
// config.js
import Vue from 'vue'
import axios from 'axios'
import store from '../store'
import router from '../router/index'
import { Toast } from 'cube-ui'
Vue.use(Toast)
const init = function () {
// 请求拦截器
axios.interceptors.request.use(function (config) {
// 触发loading
store.commit('UPDATE_SHOW_HTTP_LOADING', true)
.......
}, function (err) {
// 抛出错误
store.commit('UPDATE_SHOW_HTTP_LOADING', false)
.....
})
// 响应拦截器 Add a response interceptor
axios.interceptors.response.use(function (response) {
// 请求成功关闭loading
store.commit('UPDATE_SHOW_HTTP_LOADING', false)
.........
}, function (error) {
store.commit('UPDATE_SHOW_HTTP_LOADING', false)
.......
})
// 前置守卫 只为触发loading效果觉得不需要则去掉
router.beforeEach((to, from, next) => {
if (to.matched && to.matched.length && to.matched[0].path) {
// 已授权情况 触发loading
store.commit('UPDATE_SHOW_HTTP_LOADING', true)
next()
}
})
// 后置守卫 只为关闭loading 不用loading则去掉
router.afterEach((to, from) => {
// 关闭loading
store.commit('UPDATE_SHOW_HTTP_LOADING', false)
})
3、 调用注意的是需要在main.js
里引入config.js
并初始化去 config.init()
import config from '@/utils/config.js'
// 初始化
config.init()
四、效果
效果图不存在卡顿,看起来稍微有些卡顿是录制gif
图工具的原因。
五、 结尾
文章来源: 自己博客文章 https://www.cnblogs.com/ljx20180807/p/10319776.html