博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于vue-cli3.0构建功能完善的前端架子
阅读量:4085 次
发布时间:2019-05-25

本文共 5985 字,大约阅读时间需要 19 分钟。

上一篇文章写了vue和typescript的整合,发现很多小伙伴对vue-cli构建出来的项目很感兴趣,所以今天打算写写怎么在vue-cli3.0的架子上,在进一步完善,整合出具备基础功能的前端架子,主要包括以下几个功能点:

  1. webpack 打包扩展
  2. css:sass支持、normalize.css
  3. rem布局
  4. 路由设计:懒加载、前置检查、合法性校验
  5. api 设计
  6. 请求体设计-防重复提交
  7. vuex状态管理

webpack 打包扩展

vue-cli3 最大的特点就是零配置,脚手架把webpack相关的配置都隐藏在@vue\preload-webpack-plugin中,默认的配置可以满足大部分应用场景,优点是我们可以节省很多折腾配置的时间,webpack对于新手来说,还是有点门槛的,这样一来,新人上手可以更关注于vue的编码上。缺点也很明显,对于想自己进行自定义配置的时候,就会稍微麻烦些。

查看当前webpack的详细配置

使用 vue inspect 可以查看到详细的配置列表

扩展webpack配置

当我们想要修改或者扩展webpack配置项时,可以在根目录下新增 vue.config.js 文件,列举个我自己写的简单小栗子

// webpack 扩展module.exports = {    baseUrl: 'production' === process.env.NODE_ENV ?        '/production-sub-path/' :        '/',    chainWebpack: config => {        config.module            .rule('images')            .use('url-loader')            .tap(options => Object.assign(options, { limit: 500 }));    },    devServer: {        open: 'darwin' === process.platform,        // host: '0.0.0.0',        port: 8088,        https: false,        hotOnly: false,        // proxy: 'https://api.douban.com' // string | Object         proxy: 'http://localhost:3000' // string | Object     },    lintOnSave: false};复制代码

官网 的介绍非常详细,而且还有中文版,非常易懂,

sass支持

  1. 组件中这么写 <style lang="scss"></style> 就可以支持scss语法
  2. 在组件中import别的scss文件,写法如下
复制代码
  1. 在组件中使用自定义的 functions 和 mixin,我暂时没找到全局引用的办法,只能在需要使用的组件文件中手动引用,如下
复制代码
  1. 为了抹平各个浏览器间的差异,我们需要引入 normalize.css
// app.scss@import "./node_modules/normalize.css/normalize"; //引用第三方normalize@import "custom_normalize"; // 自定义的normalize复制代码

rem布局

在移动端下使用rem布局是个不错的选择,既然我们使用里的scss,那么可以使用函数来简化我们的重复计算的工作。设计给到的通常是2倍图,宽为750px,那么我们可以将基准设为 document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px'; 然后写个转换函数,如下:

// _functions.scss@function px2rem($px) {    $rem: 75px;    @return ($px/$rem) + rem;}复制代码

我们在使用的时候,就可以这么写

.rem {    height: px2rem(300px); // 2倍图下的宽是300px,}复制代码

转换成css就是

.rem {    height: 4rem;}复制代码

路由设计

主要包括路由懒加载、路由前置检查、合法性校验逻辑,以下是我写的一个简单路由

import Vue from 'vue';import Router from 'vue-router';// 路由懒加载const getComponent = (name: string) => () => import(`./views/${name}.vue`);Vue.use(Router);const router = new Router({    routes: [        {            path: '/',            name: 'home',            component: getComponent('home')        },        {            path: '/about',            name: 'about',            component: getComponent('about'),            meta: {                auth: true            }        },        {            path: '*',            name: 'not_fount',            component: getComponent('notFount')        }    ]});/** * 路由前置检查 */router.beforeEach((to, from, next) => {    // 合法性校验    if (to.meta.auth) {        console.log('into auth');        next();    }    next();});export default router;复制代码

api 设计

新建service文件夹用于存放api脚本,根据业务模块来划分文件,如用户相关的api一个文件、购买相关的一个文件,api.ts是各模块api的集合,如下

// service/api.tsexport { userApi } from './user';export { buyApi } from './buy';// service/user.tsexport const userApi = {    /**     * 获取用户数据     */    userInfo: '/node_api/read/userInfo'};// service/buy.tsexport const buyApi = {    /**     * 购买     */    shoping: '/node_api/shop/buy'};复制代码

这么划分,是为了项目结构和业务结构都足够清晰,同时可以避免单文件过长的问题。

HTTP请求二次封装

发送http我使用的是非常流行的axios,我在其基础上,稍微进行简单的封装,然后暴露 request对象供调用。二次封装主要是为了解决以下几个问题

  1. 简化参数,把一些常用参数都赋默认值,简化外部的使用,使得更加通用和利于排查问题。

  2. 返回报文统一处理,我们通常需要对些高频的场景做相同的处理,如错误码、未登录等场景,可以在它提供的返回响应拦截器中,统一处理。

  3. 防止重复提交,因为网络、后端处理的因素,有时接口响应会较慢,那么用户可能会在非常短的时间内,反复点击按钮,在第一次请求未返回的情况下,会再次发起新的请求,那么我们可以在axios提供的前置拦截器中搞点事情。关于防止重复请求这东东,我在以前的一篇文章有写过, 感兴趣的小伙伴可以看看。

根据以上几点,下面是我封装的request文件,思路都比较简单,就不多说啦

import axios from 'axios';import qs from 'qs';const Axios = axios.create({    baseURL: '/',    timeout: 10000,    responseType: 'json',    withCredentials: true,    headers: {        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'    }});const CancelToken = axios.CancelToken;const requestMap = new Map();// 请求前置拦截器Axios.interceptors.request.use(    config => {        // 防重复提交        const keyString = qs.stringify(Object.assign({}, { url: config.url, method: config.method }, config.data));        if (requestMap.get(keyString)) {            // 取消当前请求            config.cancelToken = new CancelToken((cancel) => {                cancel('Please slow down a little');            });        }        requestMap.set(keyString, true);        Object.assign(config, { _keyString: keyString });        if (config.method === 'post' || config.method === 'put' || config.method === 'delete') {            // 序列化            config.data = qs.stringify(config.data);        }        return config;    },    error => {        return Promise.reject(error);    });// 返回响应拦截器Axios.interceptors.response.use(    res => {        // 重置requestMap        const config: any = res.config;        requestMap.set(config._keyString, false);        if (res.status === 200) {            return res.data;        }        // todo 弹窗提示等        console.log(`request error:${res}`);    },    error => {        return {            code: -1        };    });/** * @description * 请求 * @param url * @param data * @param method */const request = (url: string, data = {}, method = 'post') => {    return Axios({        method,        url,        data,        params: method.toUpperCase() === 'GET' && data    });};export { request };复制代码

vuex状态管理

这里我根据业务模块来划分文件结构,如下图

 

 

分为首页模块和用户模块,每个模块都有自己独立的 state mutations 等,在store.ts中,引入各模块的文件,如下

import Vue from 'vue';import Vuex from 'vuex';import index from './indexModule/index';import user from './userModule/user';Vue.use(Vuex);export default new Vuex.Store({    modules: {        user,        index    }});复制代码

大家注意到这里有个 store_types.ts 文件,这个文件主要是为了搭配ts使用的,文件内容如下

export enum UserType {    /**     * 模块名称     */    'MODULE_NAME' = 'user',    /**     * 增加次数     */    'ADD_COUNT' = 'addCount',    /**     * 计算属性-获取十倍的值     */    'GET_TEM_COUNT' = 'getTenCount'}复制代码

在看下组件中的使用方式:

复制代码

虽然这么写的确有点绕,但有个好处,我们可以通过注释清晰知道方法和属性的说明

小结

以上是我根据自己工作中常见的场景来设计的,希望能对小伙伴能有帮助,其中设计不当的地方,欢迎小伙伴们在留言区一起探讨哈~

作者:小黎也
链接:https://juejin.im/post/5bb73b816fb9a05ce17265c2
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的文章
pixhawk也可以用Airsim仿真
查看>>
《无人机电机与电调技术》可以看看
查看>>
我发现七月在线的GAAS课程基本都讲到了
查看>>
电机堵转
查看>>
carzepony也在想往FreeRTOS上迁移
查看>>
可以买个好点的电烙铁
查看>>
ACfly调参记录(包括ACfly-F330和ACfly-T265)
查看>>
一定记得每飞几次或者隔一天要把螺丝和浆帽拧一次,确实会松的
查看>>
《多旋翼无人飞行器嵌入式飞控开发指南》里基于FreeRTOS的无人机软件框架
查看>>
思岚A1的SDK其实很好读懂,每个函数清晰明了,可以直接调用
查看>>
pixhawk(PX4)的一些论坛网站(包括中文版的PX4用户手册和PX4开发手册)
查看>>
串级 PID 为什么外环输出是内环的期望?(和我之前对串级PID的总结一样)
查看>>
我刚刚才完全清楚GPS模块的那根杆子是怎么固定安装好的
查看>>
去github里面找找也没有别人无人机+SLAM的工程
查看>>
PX4与ROS关系以及仿真控制(键盘控制无人机)
查看>>
我对无人机重心高度的理解
查看>>
现在明白为什么无名博客里好几篇文章在讲传感器的滞后
查看>>
实际我看Pixhawk定高模式其实也是飞得很稳,飘得也不厉害
查看>>
Pixhawk解锁常见错误
查看>>
C++的模板化等等的确实比C用起来方便多了
查看>>