移动端最强适配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 或者 height1px时 你会发现最终转换下页面看不到了 ;
解决如下

// 后面加个注释  /*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

posted @ 2019-01-25 15:15  会写代码的赖先生  阅读(1097)  评论(0编辑  收藏  举报