构建Vue大型应用的10个最佳实践(小结)

这些是我构建大型Vue项目得出的最佳实践,这些技巧将帮助你更高效的编码,并且使其更容易维护和协作。

在我今年的自由职业生涯中我有幸开发了一些大型Vue程序。我所说的这些项目使用了大量Vuex stores 😰 ,很多Vue组件(有数百个)和很多视图(pages)😄。对我而言这是非常有意义的经历,我发现了很多使扩展的方法。同时我还需要修复一些乱七八糟的错误用法。🍝

所以我将分享我的10个最佳实践,如果你有大型项目需要开发推荐你使用他们。

1. 使用Slots可以使你的组件更强大和便于理解。

最近我写了一篇文章some important things you need to know regarding slots in Vue.js。 主要讲了为什么使用Slots可以提高组件复用且易于维护。

但是这和大型Vue项目有啥关系呢。我将描绘一个使用他们解决你痛点的蓝图。

假如我要开发一个popup。起初看起来没有什么难点,仅仅是包括标题,描述和一些按钮。 所以把所有东西都当作props不就完了吗。 我用了三个自定义props,并且click按钮的时候触发一个事件。 就是这么简单! 😅

随着项目的不断发展,业务需要显示许多其他新内容:表单字段,不同的按钮(取决于显示在哪个页面上)、卡片、页脚和列表。通过添加更多的props可以解决这个问题。😩但是随着业务发展,组件变的太复杂了。因为他包含了很多子组件,需要触发很多个事件。🌋我遇到了坑爹的问题,修改了一个功能后影响了其他page上的功能。我创造了一个怪物而不是一个可维护的组件!

但是,一开始使用slots可能会更好。最终我使小组件来重构这个组件。使他更容易维护、好理解、好扩展。

<template>
 <div class="c-base-popup">
  <div v-if="$slot.header" class="c-base-popup__header">
   <slot name="header">
  </div>
  <div v-if="$slot.subheader" class="c-base-popup__subheader">
   <slot name="subheader">
  </div>
  <div class="c-base-popup__body">
   <h1>{{ title }}</h1>
   <p v-if="description">{{ description }}</p>
  </div>
  <div v-if="$slot.actions" class="c-base-popup__actions">
   <slot name="actions">
  </div>
  <div v-if="$slot.footer" class="c-base-popup__footer">
   <slot name="footer">
  </div>
 </div>
</template>

<script>
export default {
 props: {
  description: {
   type: String,
   default: null
  },
  title: {
   type: String,
   required: true
  }
 }
}
</script>

根据经验在我看来,由熟练使用slots的开发人员构建项目对将来项目的可维护性有更重要的意义。

⚠️ 经验规则,当子组件中使用了父组件的props时,应该使用slots。

2.好好组织的你Vuex store

通常,一个新的Vue开发人员学习Vuex是因为两个问题:

  • 当一个组件需要重一个比较远的组件(嵌套层级或者兄弟组件:译者注)访问数据时。
  • 需要持有一个销毁组件的数据时。

这样他创建第一个Vuex store,学习moudles的用法并且组织程序时。💡
问题是创建modules时没有单一模式可循。我强烈建议一定要想清楚如何组织他们。据我所知,很多人更喜欢按照功能来组织他们(我也是:译者注)。例如:

  • Auth.
  • Blog.
  • Inbox.
  • Settings.

就我来说,用从API获得的数据模型组织更容易理解。例子:

  • Users
  • Teams
  • Messages
  • Widgets
  • Articles

用那个取决于自己,但是从长远来看组织良好的Vuex store更具生产力。这样也容易是新人融入并且继承你的初衷。

3.用Actions调用api和提交数据。

我的大部分(不是全部)API调用都在Vuex的actions中,你一定想知道为什么这样做。🤨

简单的说是因为拉取数据时需要在store中commit。还有就是他提供了我喜欢的封装和复用。其他原因就是:

  • 如果我在两个地方(blog和home page)获取第一个页面的数据。我只需使用不同的参数调用即可得到数据,初次之外没有重复的代码被调用。
  • 如果需要创建一些逻辑来避免重复拉取数据,只需要在一个地方拉取一次。除了给服务器减负以外,我还可以在任何地方使用这些数据。
  • 我可以在actions中最终Mixpanel事件,基于维护性使问题变的容易分析。我的代码中大部分action中只有一个Mixpanel调用,😂我不必关注数据和发送这种工作方式太爽了。

4.使用mapState、mapGetters、mapMutations和mapAction精简代码。

当你在组件中访问state/getters或者调用actions/mutations时通常需要创建多个计算属性。使用mapState,mapGetters,mapMutations和mapActions可以将来自store modules中的数据集中在一个地方,这样可以精简代码并且更好理解。

// NPM
import { mapState, mapGetters, mapActions, mapMutations } from "vuex";

export default {
 computed: {
  // Accessing root properties
  ...mapState("my_module", ["property"]),
  // Accessing getters
  ...mapGetters("my_module", ["property"]),
  // Accessing non-root properties
  ...mapState("my_module", {
   property: state => state.object.nested.property
  })
 },

 methods: {
  // Accessing actions
  ...mapActions("my_module", ["myAction"]),
  // Accessing mutations
  ...mapMutations("my_module", ["myMutation"])
 }
};

你想要的这里都有Vuex官方文档

5. 快使用API Factories

我通常会创建this.$api助手,可以在任何地方访问我的API入口。我的项目根目录有一个api文件夹有我的所有类(如下)。

api
├── auth.js
├── notifications.js
└── teams.js

每一个都是一类接口的分组,这是我在Nuxt应用中使用插件的方式初始化。(和标准Vue应用程序中的过程非常相似)。

// PROJECT: API
import Auth from "@/api/auth";
import Teams from "@/api/teams";
import Notifications from "@/api/notifications";

export default (context, inject) => {
 if (process.client) {
  const token = localStorage.getItem("token");
  // Set token when defined
  if (token) {
   context.$axios.setToken(token, "Bearer");
  }
 }
 // Initialize API repositories
 const repositories = {
  auth: Auth(context.$axios),
  teams: Teams(context.$axios),
  notifications: Notifications(context.$axios)
 };
 inject("api", repositories);
};
export default $axios => ({
 forgotPassword(email) {
  return $axios.$post("/auth/password/forgot", { email });
 },

 login(email, password) {
  return $axios.$post("/auth/login", { email, password });
 },

 logout() {
  return $axios.$get("/auth/logout");
 },

 register(payload) {
  return $axios.$post("/auth/register", payload);
 }
});

这样我可以方便的在组件或Vuex操作中调用他们,如下:

export default {
 methods: {
  onSubmit() {
   try {
    this.$api.auth.login(this.email, this.password);
   } catch (error) {
    console.error(error);
   }
  }
 }
};

6. 使用$config访问环境变量(模板中特别有用)。

项目中定义了一些全局配置变量:

config
├── development.json
└── production.json

我通常使用this.$config获取,尤其是当我在模板中时。 一如既往扩展Vue对象非常容易:

// NPM
import Vue from "vue";

// PROJECT: COMMONS
import development from "@/config/development.json";
import production from "@/config/production.json";

if (process.env.NODE_ENV === "production") {
 Vue.prototype.$config = Object.freeze(production);
} else {
 Vue.prototype.$config = Object.freeze(development);
}

7.遵守一个commit命名规则。

在项目发展的过程中,经常需要关注组件的变更历史。如果团队中有人没有遵守commit惯例,那么将很难理解他们所做的事情。

我总是使用并推荐Angular commit message guidelines。我所有的项目中都会使用他,通常团队中的其他人也会发现他的好处。

遵守这些规则使commit更加可读,在查看项目历史时使得commit更加容易追踪。简言之,他是这样用的:

git commit -am "<type>(<scope>): <subject>"

# Here are some samples
git commit -am "docs(changelog): update changelog to beta.5"
git commit -am "fix(release): need to depend on latest rxjs and zone.js"

看他们的README file更新更多。

8.始终在生产环境中冻结Package的版本。

我知道...所有软件包都应遵循 the semantic versioning rules.。但实际情况并非如此。😅

为了避免一个依赖影响了整个项目在半夜被拖起来,冻结所有程序包的版本可以使你一觉睡到天明并且工作愉快。 😇

这很简单:避免以^开头的版本:

{
 "name": "my project",

 "version": "1.0.0",

 "private": true,

 "dependencies": {
  "axios": "0.19.0",
  "imagemin-mozjpeg": "8.0.0",
  "imagemin-pngquant": "8.0.0",
  "imagemin-svgo": "7.0.0",
  "nuxt": "2.8.1",
 },

 "devDependencies": {
  "autoprefixer": "9.6.1",
  "babel-eslint": "10.0.2",
  "eslint": "6.1.0",
  "eslint-friendly-formatter": "4.0.1",
  "eslint-loader": "2.2.1",
  "eslint-plugin-vue": "5.2.3"
 }
}

9. 显示一个大的数据时应该使用Vue虚拟滚动条。

在页面中显示多行或需要循环大量数据时,你已经注意到该页面渲染速度很快变慢。 要解决此问题,您可以使用vue-virtual-scoller

npm install vue-virtual-scroller

他只渲染列表中的可见项并且复用组件和dom元素,以使其尽可能高效。 如此简单就像一个魔法! ✨

<template>
 <RecycleScroller
  class="scroller"
  :items="list"
  :item-size="32"
  key-field="id"
  v-slot="{ item }"
 >
  <div class="user">
   {{ item.name }}
  </div>
 </RecycleScroller>
</template>

10.追踪第三方程序包的大小

多人合作一个项目时,如果没人关注安装的依赖包数量很快变的难以置信。为了避免程序变慢(尤其是在移动网络环境),我这VSC中使用import cost package这样就可以编辑器中看到导入的包有多大,并且找出大的原因。

例如在最近的项目中,导入了整个lodash库(压缩后24kB)。 有啥子问题? 仅仅使用cloneDeep方法。 通过import cost package找到了问题,我们通过以下方式解决了该问题:

npm remove lodash
npm install lodash.clonedeep

在使用的地方导入:

import cloneDeep from "lodash.clonedeep";

为了进一步优化,我们还可以使用Webpack Bundle Analyzer包通过树状图来可视化Webpack输出文件的大小。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 新手vue构建单页面应用实例代码

    本文介绍了新手vue构建单页面应用实例代码,分享给大家,具体如下 步骤: 1.使用vue-cli创建项目 2.使用vue-router实现单页路由 3.用vuex管理我们的数据流 4.使用vue-resource请求我们的node服务端 5.使用.vue文件进行组件化的开发 一.目录结构: 二.搭建项目 先安装 vue-cli: sudo npm install -g vue-cli 使用vue-cli构建初始化项目:vue init webpack project(创建webpack项目并下载

  • vue2.0构建单页应用最佳实战

    前言 我们将会选择使用一些vue周边的库 vue-cli , vue-router , vue-resource , vuex 1.使用vue-cli创建项目 2.使用vue-router实现单页路由 3.用vuex管理我们的数据流 4.使用vue-resource请求我们的node服务端 5.使用.vue文件进行组件化的开发 PS:本文node v6.2.2 npm v3.9.5 vue v2.1.0 vue-router v2.0.3 vuex v2.0.0 最终我们将会构建出一个小demo

  • 用vue构建多页面应用的示例代码

    最近一直在研究使用vue做出来一些东西,但都是SPA的单页面应用,但实际工作中,单页面并不一定符合业务需求,所以这篇我就来说说怎么开发多页面的Vue应用,以及在这个过程会遇到的问题. 这是我放在GitHub上的项目,里面有整个配置文件,可以参看一下:multiple-vue-page 准备工作 在本地用vue-cli新建一个项目,这个步骤vue的官网上有,我就不再说了. 这里有一个地方需要改一下,在执行npm install命令之前,在package.json里添加一个依赖,后面会用到. 修改w

  • 详解vue-cli快速构建vue应用并实现webpack打包

    Vue是什么,是一套构建用户界面的渐进式框架(官网解释),什么叫渐进式框架呢,简单回答就是主张最少,这些概念只能自己去看,自己去理解,一千个读者一千个哈姆雷特,不过多的解释.Vue官方文档很全面的. Vue两大核心思想,组件化和数据驱动,组件化就是将一个整体合理拆分为一个一个小块(组件),组件可重复使用,数据驱动是前端的未来发展方向,释放了对DOM的操作,让DOM随着数据的变化自然而然的变化(尤神原话),不必过多的关注DOM,只需要将数据组织好即可. 一.什么是vue-cli vue-cli是由

  • 使用vue构建移动应用实战代码

    在移动应用中很多功能都是必不可少的,使用vue构建移动应用自然也就需要实现这些功能.之所以写这篇文章,是希望大家能更多的将注意力放在项目的核心业务上,而不是过多的关注通用功能. 基础设置 使用vue-cli搭建项目框架 在index.html文件中添加<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"&

  • 使用typescript构建Vue应用的实现

    一.Vue项目初始化-引入typescript 使用typescript构建Vue应用和使用js一样,都是通过vue-cli去初始化并创建一个vue项目,只不过使用typescript构建的时候要在脚手架问卷操作的时候勾选上typescript选项. 二.typescript Vue项目比较 使用typescript构建的Vue项目发生了一些变化: ① main.js变成了main.ts,但是main.ts中的内容和main.js的内容是一模一样的. ② router.js变成了router.t

  • vue构建单页面应用实战

    1. 为什么要 SPA? SPA: 就是俗称的单页应用(Single Page Web Application). 在移动端,特别是 hybrid 方式的H5应用中,性能问题一直是痛点. 使用 SPA,没有页面切换,就没有白屏阻塞,可以大大提高 H5 的性能,达到接近原生的流畅体验. 2. 为什么选择 vue? 在选择 vue 之前,使用 reactjs 也做过一个小 Demo,虽然两者都是面向组件的开发思路,但是 reactjs 的全家桶方式,实在太过强势,而自己定义的 JSX 规范,揉和在

  • 使用 vue.js 构建大型单页应用

    前置条件: 熟悉使用 Javascript + HTML5 + css3. 理解 ES2015 Module 模块(export.import.export-default). 了解 nodejs 基础知识,npm 常用命令,以及 npm script 使用 (vue 项目中使用 npm 进行包管理). 了解 webpack 打包工具 (常用配置选项以及 loader 概念).(webpack webpack.github.io/ 是一个模块打包工具.它将一堆文件中的每个文件都作为一个模块,找出

  • 构建Vue大型应用的10个最佳实践(小结)

    这些是我构建大型Vue项目得出的最佳实践,这些技巧将帮助你更高效的编码,并且使其更容易维护和协作. 在我今年的自由职业生涯中我有幸开发了一些大型Vue程序.我所说的这些项目使用了大量Vuex stores

  • 建立和维护大型 Vue.js 项目的 10 个最佳实践

    目录 1.使用插槽(slot)使组件更易于理解并且功能更强大 2.正确组织您的 Vuex 存储 3.使用操作(Vuex Actions)进行 API 调用和提交数据 4.使用 mapState,mapGetters,mapMutations 和 mapAction 简化代码库 5.使用 API 工厂 6.使用 $config 访问您的环境变量(在模板中特别有用) 7.遵循一个约定来写提交注释 8.始终在生产项目时冻结软件包的版本 9.显示大量数据时使用 Vue 虚拟滚动条 10.跟踪第三方程序包

  • 了不起的11个JavaScript代码重构最佳实践小结

    模式和重构之间有着一种与生俱来的关系.从某种角度来看,设计模式的目的就是为许多重构行为提供目标. 1.提炼函数 在JavaScript开发中,我们大部分时间都在与函数打交道,所以我们希望这些函数有着良好的命名,函数体内包含的逻辑清晰明了.如果一个函数过长,不得不加上若干注释才能让这个函数显得易读一些,那这些函数就很有必要进行重构. 如果在函数中有一段代码可以被独立出来,那我们最好把这些代码放进另外一个独立的函数中.这是一种很常见的优化工作,这样做的好处主要有以下几点. 避免出现超大函数. 独立出

  • React 条件渲染最佳实践小结(7种)

    在 React 中,条件渲染可以通过多种方式,不同的使用方式场景取决于不同的上下文. 在本文中,我们将讨论所有可用于为 React 中的条件渲染编写更好的代码的方法. 条件渲染在每种编程语言(包括 javascript)中都是的常见功能. 在 javascript 中,我们通常使用if else 语句,switch case语句和三元运算符编写条件渲染. 以上所有这些方法都适用于 React. 但是问题是,我们如何才能有效地使用它们? 像你知道的那样,React 具有 JSX 标记,通常我们需要

  • Vue开发高德地图应用的最佳实践

    目录 前言 异步加载 封装组件 使用组件 自定义界面最佳实践 总结 前言 之前做不过不少关于地图交互的产品系统,目前国内主流的地图应用 SDK 只有几家:高德.百度和腾讯.所以个人觉得在 PC 应用上高德地图开发相对好一些,至少体验起来没有很明显的坑.这篇文章算是总结下开发地图应用总结吧. 异步加载 因为使用 js sdk 应用,脚本文件本身体积很大,所以要注意下加载的白屏时间,解决用户体验问题,目前绝大部分产品应用都是 SPA 单页面应用系统,所以我封装一个异步加载的方法: const loa

  • jquery提升性能最佳实践小结

    将jquery对象缓存起来在 for循环中,不要每次都要访问数组的length属性,我们应该先将对象缓存进一个变量然后再操作,如下所示: 复制代码 代码如下: var myLength = myArray.length; for (var i = 0; i < myLength; i++) { // 要做的事 } 在循环外使用append 进行DOM操作是有代价的,如果需要往DOM中添加大量元素,你应该一次批量完成,而不是一次一个. 复制代码 代码如下: // 别这样 $.each(really

  • 15条JavaScript最佳实践小结

    本文档整理大部分公认的.或者少有争议的JavaScript良好书写规范(Best Practice).一些显而易见的常识就不再论述(比如要用对象支持识别判断,而不是浏览器识别判断:比如不要嵌套太深).条目顺序按重要级粗略的从高到低排列. 把外部JavaScript文件放在HTML底部 我们的目标是相同的:为用户尽可能快地显示内容.当载入一个脚本文件的时候,HTML会停止解析,直到脚本载入完毕.因此,用户可能会长时间对着一个空白的屏幕,看上去什么都没有发生.如果你的JavaScript代码只是增加

  • 构建大型 Vue.js 项目的10条建议(小结)

    下面是我在开发大型 Vue 项目时的最佳实践.这些技巧将帮助你开发更高效.更易于维护和共享的代码. 今年做自由职业的时候,我有机会开发了一些大型 Vue 应用程序.我所说的这些项目,Vuex store 超过十个,包含大量的组件(有时候几百个)和视图页面.对我来说这是个很有益的经验,因为我发现了很多有意思的模式,可以让代码拥有更好的伸缩性.我还必须修正一些导致著名的意大利面条式代码困境的错误实践. 因此,今天我将与你分享10个最佳实践,如果你正在处理大型代码库,我建议你参考这些方法. 1. 使用

  • 2014年10个最佳的PHP图像操作库

    Thomas Boutell 以及众多的开发者创造了以GD图形库闻名的一个图形软件库,用于动态的图形计算. GD提供了对于诸如C, Perl, Python, PHP, OCaml等等诸多编程语言的支持. 除了生成HTML输出之外, 你还可以使用php以众多的像 PNG, JPEG, GIF, WBMP,以及 XPM这样的图形文件格式来创建和计算图形文件. 并且,php的使用还能让你可以直接向一个浏览器输出图像流. 为了做到这一点,你需要借助于GD库图像功能的使用来编译php. 在这篇文章中,你

  • 分析Lua观察者模式最佳实践之构建事件分发系统

    目录 一.前言 二.观察者模式 三.事件分发系统 四.使用事件分发系统解决问题 五.注册监听事件接口 六.反注册事件监听接口 七.事件派发接口 八.更多 一.前言 试想这样一个问题,当某个事件发生时,比如在游戏中A模块修改了用户的金币数,而B模块和C模块提供的功能都依赖于用户的金币数,那么,A模块在修改金币数的同时,就需要通知B模块和C模块.常规的方法就是A模块持有B模块和C模块的对象,然后分别通过调用对象接口的方式告诉它们,"嘿,我修改了用户的金币数,改成了10金币". 但这样就带来

随机推荐