10 советов по созданию больших проектов Vue.js

Vue.js

Ниже приведены мои рекомендации по разработке больших проектов Vue. Эти советы помогут вам разработать более эффективный, поддерживаемый и общедоступный код.

Работая фрилансером в этом году, у меня была возможность разработать несколько крупных приложений Vue. Проектов, о которых я говорю, в магазине Vuex более десяти и содержится большое количество компонентов (иногда сотни) и страниц просмотра. Для меня это был хороший опыт, потому что я нашел много интересных паттернов, позволяющих сделать код более масштабируемым. Мне также пришлось исправить некоторые плохие практики, которые привели к знаменитой дилемме спагетти-кода.

Итак, сегодня я собираюсь поделиться с вами 10 лучшими практиками, которые я рекомендую вам использовать, если вы имеете дело с большой кодовой базой.

1. Используйте слоты, чтобы сделать компоненты более мощными и понятными

Недавно я написал статью о слотах Vue.js, в которой рассказывается, как слоты облегчают повторное использование и обслуживание компонентов, и почему вы должны их использовать.

🧐 Но какое это имеет отношение к большим проектам Vue.js? Картинка обычно стоит тысячи слов, поэтому я собираюсь нарисовать вам картину, когда впервые пожалею, что не использовал их.

Однажды я собираюсь создать всплывающее окно. На первый взгляд ничего сложного, просто заголовок, описание и несколько кнопок. Итак, что я сделал, так это передал всю конфигурацию в качестве реквизита. В итоге я определил три реквизита для пользовательского компонента, который будет отправлять событие, когда пользователь нажимает кнопку. Так легко!

Однако по мере роста проекта команда попросила нас показать в нем больше других новшеств: поля форм, различные кнопки (в зависимости от того, на какой странице они отображались), карточки, футеры и списки. Я подумал, что было бы неплохо, если бы я продолжал использовать свойства для перебора компонента. Но, боже мой, я так ошибалась! Компоненты быстро становятся очень сложными и трудными для понимания, потому что они содержат бесчисленное количество подкомпонентов, используют слишком много свойств и отправляют кучу событий. Я начинаю сталкиваться с ужасными ситуациями, когда, когда вы вносите небольшое изменение, где-то еще на странице происходит сбой! Кажется, я построил выродка Франкенштейна вместо ремонтопригодного компонента! 🤖

Однако, возможно, было бы намного лучше, если бы я с самого начала полагался на слоты. В итоге я все переделал и получил этот маленький компонент: проще в обслуживании, быстрее для понимания, лучше масштабируется!

<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>

Я хочу сказать, что, исходя из опыта, проекты, созданные разработчиками, которые знают, когда использовать слоты, оказывают большое влияние на их будущую ремонтопригодность. Поскольку отправляется меньше событий, код легче понять и обеспечивает большую гибкость для отображения любого компонента.

️ Стучите по доске: как правило, когда вы начинаете дублировать свойства дочерних компонентов в родительских компонентах, вам следует подумать об использовании слотов.

2. Правильно организовать Vuex Store

Обычно новички в Vue.js начинают узнавать о Vuex, потому что сталкиваются с этими двумя проблемами:

  • Доступ к данным между компонентами, которые находятся слишком далеко друг от друга в структуре дерева компонентов
  • Данные должны быть сохранены после уничтожения компонента

Именно тогда они создают свой первый магазин Vuex, изучают модули и начинают организовывать их в приложении.

Проблема в том, что при создании модулей не существует единого шаблона. Однако я настоятельно рекомендую вам хорошенько подумать над тем, как их организовать. Из того, что я видел, большинство разработчиков предпочитают организовывать их по функциям. Например:

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

В моем случае мне легче понять, организовав их в соответствии с моделью данных, полученной из API. Например:

  • Users
  • Teams
  • Messages
  • Widgets
  • Articles

Как выбрать, решать вам. Единственное, что нужно иметь в виду, это то, что хорошо организованный магазин Vuex в долгосрочной перспективе делает команду более продуктивной. Кроме того, новичкам будет проще основывать свои идеи на вашем коде, когда они присоединятся к команде.

3. Используйте действия, чтобы инициировать вызовы API и отправлять данные

Большинство (если не все) моих вызовов API выполняются внутри действий Vuex. Вы спросите: зачем это делать? 🤨 🤷‍♀️ В двух словах, большинство полученных от них данных необходимо отправить в магазин. Кроме того, они обеспечивают уровень инкапсуляции и возможности повторного использования, что мне нравится. Некоторые другие причины заключаются в следующем:

  • Если мне нужно получить первую страницу статьи в двух местах (скажем, страница блога и домашняя страница), мне достаточно вызвать соответствующий диспетчер с правильными параметрами. За исключением вызовов диспетчера, выборка данных, фиксация для сохранения и возврат могут выполняться без повторения кода.

  • Если мне нужно написать какую-то логику, чтобы избежать повторного получения первой страницы, я могу сделать это в одном месте. Это не только снижает нагрузку на сервер, но и повышает мою уверенность в коде.

  • Я могу отслеживать большинство этих действий на событиях Mixpanel (инструмент анализа поведения пользователей веб-сайта), что делает код анализа очень простым в обслуживании. У меня есть несколько приложений, в которых все вызовы Mixpanel выполняются только в действиях. Мне не нужно знать, какие данные отслеживаются, какие нет и когда эта информация отправляется. Радость такой работы не передать словами.

4. Упростите свой код с помощью mapState, mapGetters, mapMutations и mapActions.

Часто вам не нужно создавать несколько вычисляемых свойств или методов, просто получайте доступ к состоянию/геттерам или вызывайте действия/мутации внутри компонента. использоватьmapState,mapGetters,mapMutations и mapActions  Может помочь вам упростить код, сгруппировать данные из модулей хранилища и сделать ваш код более понятным.

// 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

Обычно я люблю писатьthis.$apiПомощник для вызова в любом месте, чтобы получить ресурсы внутреннего API. В корневом каталоге моего проекта естьapiпапка, содержащая все связанные классы. следующим образом (только частично):

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

Каждый файл группирует все ресурсы API в своей категории. Вот как я инициализирую этот шаблон с помощью плагина в приложении 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. Следуйте соглашению об именах коммитов кода

По мере роста вашего проекта вам может потребоваться периодически просматривать историю компонента. Если ваша команда не следует тому же соглашению по именованию своих коммитов, будет намного сложнее понять каждый коммит.

Я всегда рекомендую использоватьРуководство по информации о коммитах Angular. Я следую ему в каждом проекте, и во многих случаях другие члены команды быстро обнаруживают преимущества следования ему.

Следование этим рекомендациям приводит к более удобочитаемой информации, что упрощает отслеживание коммитов при просмотре истории проекта. Короче говоря, это работает так:

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

# 举例
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-файлУзнайте больше, чтобы узнать больше об этом и связанных соглашениях.

8. Исправить версию пакета после выхода проекта в сеть

Я знаю, что все пакеты должны следоватьСемантические правила управления версиями. Но реальность такова, что некоторые вообще не соблюдают.

Чтобы не просыпаться среди ночи из-за того, что зависимость сломала весь проект, блокировка всех версий пакета может сделать вашу утреннюю работу менее напряженной.

Его смысл прост: избегайте использования^Номер версии с префиксом:

{
  "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 Virtual Scroller при отображении больших объемов данных

Когда вам нужно отобразить большое количество строк на определенной странице или нужно прокрутить большой объем данных, вы, возможно, заметили, что страница может очень быстро стать очень медленной. Чтобы исправить это, вы можете использовать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. Отслеживайте размер сторонних пакетов

Когда много людей работает над одним и тем же проектом, если никто не обращает внимания на количество установленных пакетов, оно быстро увеличивается. Чтобы приложение не тормозило (особенно если мобильная сеть медленная), я использовал в VS Codeплагин стоимости импорта. Таким образом, я могу видеть в своем редакторе, насколько велика импортированная библиотека модулей, и могу проверить наличие проблем, когда она становится слишком большой.

Например, в недавнем проекте была импортирована вся библиотека lodash (около 24 КБ в сжатом виде). В результате используется только метод cloneDeep. Эта проблема находится через плагин стоимости импорта, и мы решаем ее следующим образом:

npm remove lodash
npm install lodash.clonedeep

Функцию cloneDeep можно импортировать при необходимости:

import cloneDeep from "lodash.clonedeep";

️ Для дальнейшей оптимизации вы можете использоватьWebpack Bundle Analyzer , визуализируйте размер файла с помощью интерактивной масштабируемой карты.


Webpack Bundle Analyzer

Есть ли у вас какие-либо другие передовые методы работы с большими кодовыми базами Vue, которыми вы могли бы поделиться? Добро пожаловать, чтобы оставить сообщение в области комментариев.

оригинальный

общаться

Добро пожаловать в общедоступную учетную запись WeChat «Станция перевода 1024», чтобы предоставить вам больше технических сухих товаров.

公众号:1024译站