手把手教你根据postcss+axios+vue-router+mock+vuex搭建适配移动前端基础框架

0.588字数 2060阅读 1362

为了让大家更加简单明了,下面带大家从基础做起(ง •̀_•́)ง

使用Vue-cli来构建项目

开始项目之前,要先安装好Nodejs、NPM和Webpack。对于NodeJsNPMWebpack相关介绍,大家可以查阅其对应的官网。这里就不详解了。
首先全局安装vue-cli,并且现在不需要npm i 下载依赖

$ npm install -g vue-cli

如果安装好了,就使用命令
vue init webpack vw-layout-jl
创建项目
创建好了之后,切换到vw-layout-jl项目执行npm run dev

安装PostCSS插件

用vue-cli创建项目的根目录之下默认有.postcssrc.js文件,Vue-cli默认配置了下面述三个PostCSS插件postcss-import、postcss-url、autoprefixer

module.exports = {
  "plugins": {
    "postcss-import": {},
    "postcss-url": {},
    // to edit target browsers: use "browserslist" field in package.json
    "autoprefixer": {}
  }
}

Vue-cli默认配置了上述三个PostCSS插件,但我们要完成vw的布局兼容方案,或者说让我们能更专心的撸码,还需要配置下面的几个PostCSS插件:

npm i postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano --S

接下来在.postcssrc.js里面修改配置

module.exports = {
  "plugins": { 
    "postcss-import": {},
    "postcss-url": {},
    "postcss-aspect-ratio-mini": {},
    "postcss-write-svg": { utf8: false }, 
    "postcss-cssnext": {}, 
    "postcss-px-to-viewport": { 
     viewportWidth: 750,// (Number) 视窗的宽度,对应的是我们设计稿的宽度,一般是750 
      viewportHeight: 1334, // (Number) 窗的高度,根据750设备的宽度来指定,一般指定1334
      unitPrecision: 3, // (Number) 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
      viewportUnit: 'vw', // 指定需要转换成的视窗单位,建议使用vw 
      selectorBlackList: ['.ignore', '.hairlines'], // (Array) 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
      minPixelValue: 1, // (Number) 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
      mediaQuery: false // (Boolean) 允许在媒体查询中转换`px` 
      }, 
      "postcss-viewport-units":{},
      "cssnano": { 
        preset: "advanced", 
        autoprefixer: false, 
        "postcss-zindex": false 
      } 
    }
}

其中的# postcss-px-to-viewport是可以将px转换为vw、vw、vh、vmin或者vmax这样的视窗单位
比如你是这样写css

.class2 {
  border: 1px solid black;
  margin-bottom: 1px;
  font-size: 20px;
  line-height: 30px;
}

编译之后就变成这样

.class2 {
  border: 1px solid black;
  margin-bottom: 1px;
  font-size: 6.25vw;
  line-height: 9.375vw;
}

在不想要把px转换为vw的时候,首先在对应的元素(html)中添加配置中指定的类名.ignore.hairlines如下:

<div class="class2 ignore"></div>

写css的时候

.ignore { 
  margin: 10px; 
  background-color: red; 
} 
.class2{ 
  width: 180px;
  height: 300px;
 }

编译的时候

.class2{
   width: 24vw;
   height: 40vw; 
} 
.ignore { 
  margin: 10px; /*.box元素中带有.ignore类名,在这个类名写的`px`不会被转换*/
  background-color: red;
 }

到最后就是解决兼容性问题了
就是使用viewport的polyfill:Viewport Units Buggyfill。使用viewport-units-buggyfill主要分以下几步走:

引入JavaScript文件

viewport-units-buggyfill主要有两个JavaScript文件:viewport-units-buggyfill.jsviewport-units-buggyfill.hacks.js。你只需要在你的HTML文件中引入这两个文件。比如在Vue项目中的index.html引入它们:

<script src="https://cdn.bootcss.com/viewport-units-buggyfill/0.6.2/viewport-units-buggyfill.min.js"></script>
<script src="https://cdn.bootcss.com/viewport-units-buggyfill/0.6.2/viewport-units-buggyfill.hacks.min.js"></script>

在HTML文件中调用viewport-units-buggyfill

<script>
 window.onload = function () { 
  window.viewportUnitsBuggyfill.init({ 
    hacks: window.viewportUnitsBuggyfillHacks 
  });
 }
 </script>

以上算是完成了适配的工作了,记住几个要点:
1.在.postcssrc.js里面配置postcss-zindex,如果不设置为false,z-index的值就会重置为1。这是一个天坑,记得将postcss-zindex设置为false
2.写css的时候,是按照设计图750宽度来进行样式书写,即设置viewportWidth为750px,所以没有样式图的话,如果想要16px字体,那就是就将字体*2,将字体设置font-size:32px;;如果要其他插件的话,如果其他插件是px为单位的,那就将viewportWidth为375px,设置样式的话,如果需要16px样式的,就设置font-size:32px;这样子,插件也可以将px修改为vw了

接下来,我们进行一个小项目练习,利用axios+vue-router+mock+vuex来做一个小平台把,以下分为几个步骤

安装配置axios

npm install axios

具体请看https://github.com/axios/axios
接下来,我们就可以了解它的两种基本用法了

axios.get('/user', {
    params: {
      ID: 654321
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
axios.post('/user' , {
  params: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
})
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

但是如果在比较中大型的项目下如果每个都要写这些请求,就会变得异常臃肿,代码不好管理
,而且不能统一处理错误信息;因此我们可以进行封装axios,统一处理异常、配置通用代码
我们知道在普通用法中,.then()处理响应,.catch()处理错误,通过拦截器,可以提前判断,并返回二者之一。我们可以在src里面创建文件夹common,再创建serviceHttp.js来统一处理

全局配置

axios.defaults.timeout=10000;//超时时间
axios.defaults.baseURL = '协议名://域名:端口号';//配置baseURL 

运用拦截器

// 请求时的拦截
axios.interceptors.request.use(function (config) {
    // 发送请求之前做一些处理
  if(true){
    //拦截器统一加上请求头
    config.headers['Authorization'] = '2132143432';
  }
    return config;
  }, function (error) {
    // 当请求异常时做一些处理
    return Promise.reject(error);
  });

// 响应时拦截
axios.interceptors.response.use(function (response) {
    // 返回响应时做一些处理
    return response;
  }, function (error) {
    // 当响应异常时做一些处理
    return Promise.reject(error);
  });

这里将响应或者错误返回到get/post请求的结果中,通过链式处理。

封装get,post方法

*基本配置
包括请求方法,基础url,相对url,参数,超时时间,请求头等。如果需要用到配置编译环境和线上环境之间的切换,在下文再叫大家修改
*checkStatus()
链式处理第一步,判断http状态码是否正常,和拦截器一样,请求正常则返回响应,请求异常则返回错误,最后返回结果给checkCode()。
*checkCode()
链式处理第二步,处理上一步的结果,分别处理网络异常,以及后端返回的异常
*调用方法的时候,可以根据async和wait来调用,如下:

methods:{
     fetchData:async()=>{
     let params = {
      }
      const res = await http.get('/abc/defgh', params)
        return res
     }
}
mounted: function () {
    this.fetchData().then(function(val){console.log(val)})
}

但Acsic/AsAcess是ECMAScript 2017的一部分,在Internet Explorer和旧浏览器中不支持,所以请谨慎使用。我们平时可以这样子来用:

mounted: function () {
    http.get('/abc/defg',{})
    .then(function(response) {
      console.log('response',response.data)
    });
  },

有些小伙伴提出,那我执行多个并发请求怎么做尼,也很简单,看着官网来做就好了哦,比如:

methods: {
    fetchData(){
      return http.get('/abc/defg',{});//记得这里是return哦!
    },
    fetchData1(){
      return http.get('/abc/defg',{})
    }
  },
  mounted: function () {
    var that=this;
    axios.all([that.fetchData(),that.fetchData1()])
    .then(axios.spread((acct,aaa)=>{
      // 两个请求现在都执行完成
      console.log('acct',acct)
    }));
  },

大家可能会有疑问,那如果我要修改某些请求的url,那岂不是每个文件夹都找一遍来修改嘛?那我们干脆把url统一放到一个文件夹来处理咯,新建api文件;这里就不啰嗦了,直接上例子:
在api.js里面

import http from './serviceHttp.js'
export default {
    fetchData:async(val)=>{
        const res = await http.get('/abc/defg', val)
        return res
    }
}

在组件里面引用
首先引用import api from '../common/api.js';
在mounted函数里面调用

api.fetchData({})
    .then((val)=>{
      console.log(val)
    })

如果还要其他的要求就不细说了。
一般项目里面都会用到编译环境和配置环境的切换请求,因为涉及的比较详细,我将它写到另一篇文章里面描述了,详情请移步:https://www.jianshu.com/p/a5f206ec6a3e
小的们( •̀ ω •́ )y,完成了以上的步骤,让我们继续来“深造”

安装vue-router

npm install vue-router

vue-router详情请看:https://router.vuejs.org/zh/installation.html
在src下面有router文件夹,里面的index.js是路由配置,如下:

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    }
  ]
})

看到这里,你是不是觉得需要配置文件之类的开始写项目啦,先别急哦,咱们的vuex还没有下载尼!为啥还要这个尼,小宝贝们别急,以后会用到哈!( •̀∀•́ )

下载vuex

npm install vuex

呼~~下载好之后,新建文件夹及其子文件,如图


image.png

好了,先教大家基础的,后续复杂的再写上(ง •̀_•́)ง
在store里的index.js里面写上基础的

import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'
import actions from './action'
import getters from './getters'

Vue.use(Vuex)
const state = {
    message111:'aaa',
}

export default new Vuex.Store({
    state,
    getters,
    actions,
    mutations,
})

再在main.js里面引用,如:

import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
import store from './store/'
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

-----------vuex的就暂告一个段落了----------------
说好的用mock尼,哈哈哈,先让大家来了解以下什么是mock

mock.js基础了解

1)能生成随机数据,拦截ajax,前后端分离,让前端攻城师独立于后端进行开发。
2)开发无侵入,不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据。
3)数据类型丰富,支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等。
4)增加单元测试的真实性,通过随机数据,模拟各种场景。
5)用法简单,符合直觉的接口。
6)方便扩展,支持支持扩展更多数据类型,支持自定义函数和正则。

开始安装mock.js

npm install mockjs

呼~~~~安装好了~~在src下面新建mock文件夹,在文件夹下面新建homepage.js,我一般在里面是这样子写的

let data = [
    {
        "roomId": 1010201,
        "roomName": "A栋 705",
        "cardType": 1,
        "name": "张三",
        "phone": "18888888888",
        "timestamp": "2018-09-09"
    },
    {
        "roomId": 1010201,
        "roomName": "A栋 705",
        "cardType": 1,
        "name": "张三",
        "phone": "18888888888",
        "timestamp": "2018-09-09"
    }    
  ]
  
  const Mock = require('mockjs');
  Mock.mock(
    /abc\/def\/ghi\/jk/,//请求的url,需要\来转义
    {
      code: "0",
      msg: "ok",
      data: data
    }
  );

然后再main.js里面引用js就可以了:import './mock';
其他的就不用管了,只要你请求的url跟在mock里面写的url一致就好了,是不是很简单尼?
------------------------这会真的是暂告一段落了-------------------------
因为最最基础的搭好了哦,这会某些宝宝是不是(才)不(那么)开(一)心(点)了,别急哈,因为其他的细节方面显得太啰嗦了,后续会有文章出来的,喜欢的点个爱心(≧▽≦)/
参考文章:https://www.w3cplus.com/PostCSS/using-postcss-for-minification-and-optimization.html

推荐阅读更多精彩内容