如何更有效率和质量地开发Vue项目

前言

自总结完了上篇前端工程化的思想,并在vue全家桶的项目加以实践,趁热给大家总结一篇如何更有效率与质量地开发vue项目,以及其中踩过的一个个坑。。。

基于vue-cli的自定义模板(Custom Templates)

小伙伴们的vue项目应该都是用vue-cli初始化出来的,但是vue-cli只是满足了基础配置和功能,如果你有额外的配置需求或者要迎合团队的业务配置,每新建个项目都得重新安装额外配置,比如说vuex,sass,封装axios,以及相关的文件夹。为了解决上述问题,vue-cli出了一个自定义模板功能,你fork官方的模板下来然后进行修改,然后用 vue-cli 来调用。具体调用的场景有以下两种

  • 直接拉取git源:
    当你修改了模板并上传了repo上,可执行以下命令行来初始化
vue init username/repo my-project
  • 拉取本地的模板:
    当你clone了官方模板在本地修改,可执行以下命令行来初始化
vue init ~/fs/path/to-custom-template my-project

还可以编写meta.*(js,json)来选择安装哪些配置~
如果大家懒得去编写vuex,sass的配置,封装axios的话,可以来通过我配置完的脚手架来初始化完项目~
vue init duosanglee/vuejs-custom-template

这个模板在repo里ps:我的这个模板的代码风格是基于standard的

引入sass全局变量,mixin,function等

首先我们考虑下以下场景:当使用rem开发移动端的时候,你定义了一个方法pxToRem的方法来实现px对rem的转换,然后在工程里为每个.vue文件@import 'public.scss',得import很多很多很多次,万一public.scss路径变了的话。。。哭都来不及。
这时候sass-resources-loader就来拯救我们了,他可以省去重复性的引入还支持LESS,POSTCSS
具体用法如下:

  • npm install -D sass-resources-loader
  • 首先得找到项目里的build文件夹,找到util.js
    添加一下代码
function resolveResouce(name) {
return path.resolve(__dirname, '../src/style/' + name);
}
function generateSassResourceLoader() {
var loaders = [
 cssLoader, 
 // 'postcss-loader', 'sass-loader',
 {
     loader: 'sass-resources-loader',
     options: {
       // it need a absolute path
       resources: [resolveResouce('common.scss')]
     }
 }
    ];
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
   fallback: 'vue-style-loader'
 })
    } else {
return ['vue-style-loader'].concat(loaders)
    }
}

然后还是在当前文件里找到

return {
  css: generateLoaders(),
  postcss: generateLoaders(),
  less: generateLoaders('less'),
  sass: generateLoaders('sass', { indentedSyntax: true }),
  scss: generateLoaders('sass'),
  stylus: generateLoaders('stylus'),
  styl: generateLoaders('stylus')
}

替换成

return {
  css: generateLoaders(),
  postcss: generateLoaders(),
  less: generateLoaders('less'),
  sass: generateSassResourceLoader(),
  scss: generateSassResourceLoader(),
  stylus: generateLoaders('stylus'),
  styl: generateLoaders('stylus')
}

这样就可以在项目里使用sass全局变量,mixin,function了~~

在线 Mock 平台 easy-mock

现在讲都是前后端分离,前后端并行开发来提高开发效率,通过一个api文档来协作,所以一个好的mock工具对于提高效率也至关重要~
这里极力推荐easy-mock工具,支持团队协作编辑,生成模拟数据的在线 mock 服务,还支持导入swagger文档等功能,界面如下

定义全局变量

在项目会有需要使用全局变量的需求,来处理一些频繁的操作,大家都应该会绑定到window对象上,但是这种方式不适合服务端渲染,因为服务端没有 window 对象, 是 undefined, 当试图去访问属性时会报错.我总结了两个靠谱的方法

  • 代理到Vue的原型对象
    由于所有的组件都会从 Vue 的原型对象上继承它们的方法, 因此我们只要
Object.defineProperty(Vue.prototype, '$xxx', { value: xxx });

就可以在所有组件/实例中通过 this.$xxx: 的方式访问插件了而不需要定义全局变量或者手动的引入了

至于为什么要用Object.defineProperty这个方法,是因为通过Object.defineProperty绑定的属性是只读的,以防一起开发项目的协(zhu)作(dui)者(you)去重写或者覆盖该方法的值。

  • vuex大法
    vuex的出现就是vue为了集中式存储管理应用的所有组件的状态,所以说全局变量和方法都可以放到vuex当中~具体用法就不加阐述了,大家可仔细阅读vuex文档

组件设计

大家都知道组件化的思想就是分治,几乎任意类型的应用程序界面,都可以抽象为一个组件树,那我们该按照什么规则把应用抽象成组件,来应对复杂多变的业务需求呢。
我们从通信、黑箱,继承这几个角度来看看

  • 通信: vue的父子组件通信机制是props down,events up,尽量保持松耦合,一直保持单向数据流的特点,并加以强约束。需要注意的时候,尽可能减少跨组件通信,例如使用$parent,$root。
  • 继承: 当两个组件存在些许的共性,又存在足够的差异性的时候,就可以用到vue的继承---mixin,他允许你封装一块在应用的其他组件中都可以使用的函数。如果使用姿势正确,他们不会改变函数作用域外部的任何东西。而且mixin还有各种高阶用法,大家可自行查询(我也不会)。
  • 黑箱: 组件的黑箱状态既只暴露易变的接口和方法,渲染给入的数据,组件内部封装不变的逻辑。
  • 设计模式原则: 运用设计模式原则,比如单一职责原则,将组件拆分抽离成更细粒度,保证高内聚性;再如接口隔离原则,采用稳定的服务端接口,将变化模块分离,使得组件得以解耦;里氏替换原则、依赖倒置原则等等。

目录结构

-- src
    -- assets                      # 私有资源
    -- common                      # 通用组件
    -- components                  # 业务组件
    -- api.js                      # 请求文件      
    -- config                      # 环境变量配置
        -- env.js                  # 环境变量文件
        -- http.js                 # 封装axios文件
    -- pages                       # 页面维度
        -- pageA                   # 页面A
            -- pageA.vue           # 页面A单文件
            -- pageA-components    # 页面A下的一个组件
            -- children            # 子页面
    -- router                      # 路由
        -- index.js                # 路由入口
        -- routes.js               # 路由配置信息
    -- store                       # vuex
        -- modules                 # vuex模块
        -- index.js                # vuex入口
    -- utils                       # js通用方法
    -- app.vue                     # 顶层单文件
    -- main.js                     # 入口

大家可以从目录结构中看出我整个项目分割的思维
首先我把组件分为通用组件和业务组件两大类。

  1. 通用组件是与业务耦合低,是有简单状态或者无状态的,数据几乎全部依赖于输入,它只负责渲染给入的数据。比如按钮是一个组件,可能有一个参数决定了它的尺寸,一个参数决定了它是否可以点击,但是点击这个按钮之后会发生什么,就不是按钮这个组件需要知道的事情了。

  2. 业务组件是与业务耦合高,可以由多个通用组件和其他的业务组件组成,会拥有一些方法,用来修改持有的数据,对内来看,它自己持有一些数据和方法,用来决定内容的渲染,对外又是一个简单的props接受数据。可以理解为组件树的非叶子节点,通过自身数据变化,进而操纵子组件的内容。

然后config文件夹放置了环境变量文件env.js和封装http库文件http.js

env.js

http.js

然后我把路由里的routes.js和api.js请求文件都单独抽离了出来。

自动生成雪碧图

前端项目中自动生成雪碧图节省了我们很多的时间,我们只要把图片扔到文件夹里,webpack-spritesmith就能按照我们设定的规则自动合成css-sprite,安装配置如下:

var SpritesmithPlugin = require('webpack-spritesmith');
...
module.exports = {
  ...
  plugins: [
    new SpritesmithPlugin({
      src: {
        cwd: './src/assets/sp/',
        glob: '*.png'
      },
      target: {
        image: './src/assets/sprite/sprite.png',
        css: './src/assets/sprite/sprite.css'
      },
      apiOptions: {
        cssImageRef: './sprite.png'
      },
      spritesmithOptions: {
        algorithm: 'top-down',
        padding: 100
      }
    })
  ]
}

自动修复eslint格式错误

这个功能的建立在小伙伴的开发工具是vscode情况下~
首先在vscode扩展里面安装vscode的eslint插件,然后settings.json里添加如下配置

"eslint.validate": [
    "javascript",
    "javascriptreact",
    {
        "language": "html",
        "autoFix": true
    },
    {
        "language": "vue",
        "autoFix": true
    }
],
"eslint.autoFixOnSave": true,

然后会在save文件的时候eslint插件自动根据项目下的.eslintrc来设置代码格式~
sf不支持播放gif..具体效果大家只能自行查看

跨域

在浏览vue-cli的官方文档时候发现了vue-cli自带了API proxy,解决了在项目中后端联调的时候的跨域问题。具体安装配置如下:
首先我们找到config文件下的index.js,再找到dev对象下的proxyTable属性,然后把以下代码添加进去

proxyTable: {
  '/api': {
    target: '网站名',
    pathRewrite: {
      '^/api': ''
    }
  }
}

然后重启本地服务器,这样你发送的/api/a就会代理发送到"网站名/a"了~

开发利器emmet

之所以称emmet为前端开发利器是因为他可以根据我们所输入的缩写来得到相应的内容,大大节省我们的开发html和css的时间,例:

  • 输入ul>li*2>span 按下扩展键
<ul>
<li><span></span></li>
<li><span></span></li>
</ul>
  • 输入m0-a-0-0+posa+bgc 按下扩展键
margin: 0 auto 0 0;
position: absolute;
background-color: #fff;

更多方法请看官方文档emmet
这篇文章到此就已经结束了感谢大家能够关注此文章如果这篇文章能帮助到大家的话,麻烦请帮我点个赞~~~
大家有啥想法可在下面评论,也可以加我QQ:757592499来讨论~

原文:如何更有效率和质量地开发Vue项目

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • 项目地址:TwinklingRefreshLayout 本文分析版本:0a9b613 1.简介 以下是 Twin...
    Tyler阅读 1,325评论 0 6
  • 文/艺莫拍摄/艺莫 下班正往大门方向 刚到转角旁 遇见快要西坠的夕阳 美的让人痴狂 你看它灼热的脸庞 犹如天边点起...
    艺莫阅读 404评论 0 13