Порекомендуйте шаблон быстрой разработки H5 на основе Vue.

Vue.js
Порекомендуйте шаблон быстрой разработки H5 на основе Vue.

Шаблон построен на основе vue-cli4 и Vant-ui, а также лучший план разработки крупномасштабного проекта H5, давайте узнаем

адрес шаблонаДвигай своей милой маленькой ручкой, чтобы зажечь однуstar

Структура проекта

Этот проект создал для вас полную структуру разработки.Ниже представлена ​​структура каталогов всего проекта.

├── .github                    # git log
├── plop-templates # 基本模板
├── public # 静态资源
│ │── favicon.ico # favicon图标
│ └── index.html # html模板
├── src # 源代码
│ ├── assets # 静态资源
│ ├── components # 全局公用组件
│ ├── constants # 常量
│ ├── core # 分层
│ ├── enum # 枚举
│ ├── filters # 全局 filter
│ ├── icons # 项目所有 svg icons
│ ├── lang # 国际化 language
│ ├── layout # 全局 layout
│ ├── router # 路由
│ ├── store # 全局 store 管理
│ ├── styles # 全局样式
│ ├── utils # 全局公用方法
│ ├── pages # pages 所有页面
│ ├── pwa # 渐进式Web应用
│ ├── App.vue # 入口页面
│ ├── main.js # 入口文件 加载组件 初始化等
│ └── permission.js # 权限管理
├── tests # 测试
├── .editorconfig # 代码风格
├── .env.xxx # 环境变量配置
├── .eslintrc.js # eslint 配置项
├── .sentryclirc.js # 前端异常日志监控配置
├── .babel.config # babel 配置
├── plopfile.js # 基本模板配置
├── vue.config.js # vue-cli 配置
├── postcss.config.js # postcss 配置
└── package.json # package.json
...

Установить

# 克隆项目
git clone https://github.com/push-over/vue-h5-template.git

# 进入项目目录
cd vue-h5-template

# 安装依赖
npm install

# 建议不要用 cnpm 安装 会有各种诡异的bug 可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npm.taobao.org

# 本地开发 启动项目
npm start

TIP

Настоятельно не рекомендуется использовать cnpm для прямой установки, будут всякие странные баги, решить проблему медленной установки npm можно перепрошивкой реестра. Если это все еще не работает, вы можете использоватьyarnальтернативаnpm.

Если установка не удалась для пользователей Windows, велика вероятность того, чтоnode-sassустановка не удалась,решение.

Также из-заnode-sassзависитpythonОкружающая среда, если вы не установили и не настроили ее раньше, вам необходимо самостоятельно ознакомиться с соответствующим руководством по установке.

После завершения запуска браузер автоматически откроется для доступа к [http://localhost:9000. Если вы видите следующую страницу, это означает, что операция прошла успешно.

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

Общие команды

# 项目打包
npm run build:xxx

# 自动创建
npm run new

# 规范Git提交
npm run git-cz

# 生成CHANGELOG
npm run genlog

Многоуровневая архитектура

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

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

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

  • ...

В ответ на проблемы, с которыми столкнулись выше, мы поясним следующую архитектурную диаграмму:

вПросмотр слоя/видаЭто наиболее контактируемый всеми, я думаю, что все хорошо его знают, поэтому я не буду его здесь представлять, а сосредоточусь на значениях других слоев:

Слой сервисов

Уровень служб используется для работы с базовыми технологиями, такими как инкапсуляция.AJAXзапрос, работа в браузереCookie,LocaStorage,IndexedDB, работатьNativeОбеспечить возможность (например, вызов камеры и т. д.) и установитьWebsocketВзаимодействие с бэкендом и т.д.

Пакет Аксиос

.....

export default async function(options) {
const { url } = options
const requestOptions = Object.assign({}, options)

try {
const { data, data: { errno, errmsg }} = await instance.request(requestOptions)
if (errno) {
errorReport(url, errmsg, requestOptions, data)
throw new Error(errmsg)
}
return data
} catch (err) {
errorReport(url, err, requestOptions)
throw err
}
}

IndexedDB

...

export class DBRequest {
instance

static getInstance() {
if (!this.instance) {
this.instance = new DBRequest()
}
return this.instance
}
async create(options = {}) {
const { name, data } = options
const db = await indexDB(name)
return await db.add(name, data)
}
...
}

.......

Слой сущностей

Сущность Сущность является основной концепцией предметно-ориентированного проектирования, она является носителем доменных услуг, она определяет свойства и методы человека в бизнесе. Различение того, является ли объект сущностью, в основном зависит от того, имеет ли он уникальный идентификатор (например, id)

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

Не все сущности должны быть инкапсулированы в класс, как указано выше.Если сущность сама по себе имеет простую бизнес-логику, нет необходимости ее инкапсулировать.Например, в этом шаблонеTestПросто для демо.

Слой интеракторов

Уровень Interactors — это уровень, отвечающий за обработку бизнес-логики, в основном состоящий из бизнес-прецедентов.

import { Request } from '@/utils/request'
import { CARDS } from '@/constants/api/test'

class TestHttpInteractor {
service
constructor(service) {
this.service = service
}
async getTest() {
try {
const options = { url: CARDS }
return await this.service.get(options)
} catch (error) {
throw error
}
}
async createTest(data) {
try {
const optons = { url: CARDS, data }
await this.service.post(optons)
} catch (error) {
throw error
}
}

...
}

const testHttpInteractor = new TestHttpInteractor(Request.getInstance())
export default testHttpInteractor

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

Кроме того, уровень Interactors также может получать классы сущностей, предоставляемые уровнем Entities, и интегрировать бизнес-логику, тесно связанную с сущностями, предоставляемыми классами сущностей, и бизнес-логику уровня Interactors со слоем View, например:

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

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

макет

Общий макет страницы — это самая внешняя структура фрейма продукта, где vue-router используется для вложения маршрутов, поэтому, как правило, добавление или изменение страниц влияет только наapp-mainэто основная область. другая конфигурация вlayoutТакое содержимое, как: нижняя навигация, не изменится при изменении вашей главной страницы.

/foo                                  /bar
+------------------+ +-----------------+
| layout | | layout |
| +--------------+ | | +-------------+ |
| | foo.vue | | +------------> | | bar.vue | |
| | | | | | | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+

здесь, вapp-mainвнешне завернутыйkeep-aliveВ основном для кэширования, вы можете удалить его самостоятельно, если он вам не нужен.

стиль

CSS Modules

В процессе разработки стиля есть две важные проблемы:

  • Глобальное загрязнение — селекторы в файлах CSS действуют глобально, селекторы с одинаковыми именами в разных файлах, в соответствии с порядком в сгенерированных файлах после сборки, более поздние стили перезапишут предыдущие;
  • Селектор сложен — во избежание вышеперечисленных проблем приходится быть внимательным при написании стиля, имя класса будет помечено с ограниченной областью видимости, которая будет становиться все длиннее и длиннее, и легко вызвать путаницу в стиль именования, когда несколько человек разрабатывают. , количество селекторов, используемых для элемента, также может увеличиться, что в конечном итоге затруднит его обслуживание.

К счастью, vue предоставляет намscopedВышеуказанные проблемы могут быть легко решены. Он добавляет концепцию домена в CSS, как следует из его названия.

/* 编译前 */
.example {
color: red;
}

/* 编译后 */
.example[_v-f3f3eg9] {
color: red;
}

просто добавьstyle scopedТаким образом, css будет действовать только на текущий компонент.

TIP

С областью действия стили из родительских компонентов не будут проникать в дочерние компоненты. Однако на корневой узел дочернего компонента влияет как CSS с областью действия его родителя, так и CSS с областью действия дочернего компонента. Это сделано для того, чтобы родительский компонент мог настроить стиль корневого элемента своего дочернего компонента с точки зрения макета.

Структура каталогов

vue-h5-templateВсе глобальные стили находятся в@/src/stylesнастройки каталога

├── styles
│ ├── _animation # 全局动画
│ ├── index.scss # 全局通用样式
│ ├── _mixin.scss # 全局mixin
│ ├── _transition.scss # 过渡效果
│ └── _variables.scss # 全局变量

Полноценное взаимодействие с серверной частью

существуетvue-h5-template, полное взаимодействие интерфейсного пользовательского интерфейса с потоком обработки на стороне сервера выглядит следующим образом:

  1. Взаимодействие компонентов пользовательского интерфейса
  2. Вызовите функцию запроса службы единого API-интерфейса управления.
  3. Отправить запрос, используя инкапсулированный request.js
  4. Получить возврат сервера
  5. обновить данные

request.js

в,@/src/utils/request.jsЭто вторичная инкапсуляция http на основе каталога сервера, что удобно для унифицированной обработки POST, GET и других методов запроса. Подробности смотрите в коде проекта.

...
export class Request {
instance

static getInstance() {
if (!this.instance) {
this.instance = new Request()
}
return this.instance
}

async post(options = {}) {
const { data } = await service({
method: 'post',
...options
})
return data
}
...
}

пример

Определить унифицированное управление адресами интерфейсовsrc/constants/api/test.js

export const CARDS = '/admin/cards'

метод запросаsrc/core/interactors/test-interactor.js

async getTest() {
try {
const options = { url: CARDS }
return await this.service.get(options)
} catch (error) {
throw error
}
}

метод запросаsrc/utils/request.js

async get(options = {}) {
const { data } = await service({
method: 'get',
...options
})
return data
}

TIP

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

использование страницыsrc/pages/test/index.vue

# 生命周期
async created() {
if (this.id) {
await this.handleGetTest()
}
}

# 请求
async handleGetTest() {
try {
const test = await testInteractor.getTest(this.id)
this.addressInfo = Object.assign({}, test)
} catch (error) {
console.log(error)
}
}

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

Сгенерировать необходимые файлы

В процессе разработки добавляем ли мы страницы или добавляем компоненты и так далее. нужно продолжать строить.vueфайлы (или другие фреймворки или файлы html/js/css)

Взяв в качестве примера проект Vue, когда мы создаем новый компонент или представление, нам нужно создать новый файл .vue, а затем написать<template>、<script>、<style>. Наконец, напишите наш бизнес-код. Если вы используете стиль класса для написания Vue, вам также необходимо представить Vue и Component на каждой странице.

Так как это повторяющаяся работа и нет реальных сложностей в работе, мы не можем ничему научиться. Есть ли способ попрощаться с ручным стуком? Вот плагин для вас.plop, его использование относительно простое, я не буду вводить здесь слишком много, вы можете проверить документацию или напрямую получить этот шаблон для справки.

В этом проекте я настроил 5 элементов, что они представляют?

module.exports = function(plop) {
plop.setGenerator('page', pageGenerator) // Page
plop.setGenerator('component', componentGenerator) // 组件
plop.setGenerator('store', storeGenerator) // vuex
plop.setGenerator('interactor', interactorGenerator) // 业务逻辑
plop.setGenerator('db-interactor', dbInteractorGenerator) //db业务逻辑
}

TIP

Команда создания шаблона - это npm run new, не забудьте принадлежать каталогу или имени файла.

DSBridge

Ключевые особенности DSBridge

  • DSBridge действительно кроссплатформенный и официально поддерживает как iOS, так и Android.
  • DSBridge поддерживает синхронные вызовы.
  • Дружественный к трем терминалам; будь то на iOS, Android или в Интернете, он очень прост и элегантен в использовании, что просто искусство по сравнению с WebViewJavascriptBridge.
  • DSBridge — китайский проект с подробной китайской документацией и каналами обратной связи по проблемам.

Связь между страницей H5 и Native

  • Кроссплатформенность, поддерживает как iOS, так и Android.
  • Двусторонний вызов; js может вызывать натив, натив может вызывать js
  • Не только поддерживает асинхронные вызовы, но и страницы поддерживают синхронные вызовы (dsbridge — единственный мост javascript, который поддерживает синхронные вызовы).
  • Поддержка обратного вызова прогресса, возврат несколько раз (обычно используется для прогресса загрузки файла, таймера и т. д.)
  • Android поддерживает ядро ​​​​Tencent x5
  • Простота использования на трех терминалах; будь то внешний интерфейс, Android или ios, он очень прост в использовании, что значительно снижает стоимость интеграции/обучения.

Переменные среды и файлы конфигурации

env

# 移动端控制台  开(yes) | 关(no)
VCONSOLE=no

# 标题
VUE_APP_TITLE=CHINA-GOODS-H5

# 端口号
DEVSERVERPORT=9000

# 错误监控平台
SENTRY_ENABLED=yes
SENTRY_DSN='https://b84aa04e3def4784a471f8032dc62fd4@sentry.io/3619515'
SENTRY_PLUGIN_ENABLED=no

settings

export const TITLE = ''      			// 标题
export const TOKEN_KEY = '' // token-key
export const LANGUAGE_KEY = 'language' // 国际化
...

ESLint .editorconfig

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

Все файлы конфигурации ESLint находятся в.eslintrc.jsсередина. Базовая спецификация этого проекта основана на официальных правилах eslint vue.eslint-config-vueСделал несколько модификаций. Вы можете настроить конфигурацию в соответствии с вашими потребностями.

Стиль кода находится в .editorconfig, и вы можете настроить его в соответствии со своими личными предпочтениями.

Значок SVG

Если вы не нашли нужную иконку в иконке этого проекта, вы можете перейти наiconfont.comВыберите и создайте собственную библиотеку бизнес-иконок, а затем используйте ее. Или другие веб-сайты с иконками svg, просто скачайте svg и поместите его в папку.

Сгенерировать код библиотеки иконок

Сначала ищите и находите нужную иконку и собираете ее в корзину, в корзине можно добавить выбранную иконку в проект (если нет, то создать новую), а сгенерированные позже ресурсы/коды будут быть проектно-ориентированным.

Теперь этот проект поддерживает и рекомендует введение и использование экспорта svg отдельно. Способ загрузки следующий:

После завершения загрузки поместите загруженный файл .svg в@/icons/svgПосле этого папка будет автоматически импортирована.

Оптимизируйте свой собственный svg еще больше

Команда настроена, просто выполните соответствующую команду:

npm run svgo

Как пользоваться

<svg-icon icon-class="password" /> // icon-class 为 icon 的名字

глобализация

Этот проект представляет собой набор интернационализированных решений i18n. пройти черезvue-i18nи осознать.

Поскольку пользовательский интерфейс этого проекта используетVant UI, поэтому его следует интернационализировать одновременно с интернационализацией. В то же время текущийlangязык существуетcookieСреди них, чтобы открыть страницу в следующий раз, можно запомнить последнюю языковую настройку.

export const VueVantLocales = (lang = getLocale()) => {
switch (lang) {
case 'zh':
Locale.use('zh-CN', vantZhLocale)
break
case 'en':
Locale.use('en-US', vantEnLocale)
break
}
}

export default new VueI18n({
locale: getLocale(),
fallbackLocale: getLocale(),
messages
})

использовать

Использование HTML:

// $t 是 vue-i18n 提供的全局方法
$t('heoll')

Используется в Js:

const options = [
{
value: '1',
label: this.$t('i18nView.one')
},
{
value: '2',
label: this.$t('i18nView.two')
}
]

Адаптация стиля

Поскольку этот шаблон является шаблоном разработки H5, должна быть адаптация стиля. Для этого текущие основные решения vw и rem Давайте использовать инструмент, который поможет нам завершить экранную адаптацию.postcss-px-to-viewport, после установки нам нужно толькоpostcss.config.jsВы можете настроить его. Пожалуйста, обратитесь к документации за конкретными инструкциями по настройке.

консоль отладки

Что касается отладки, этот проект используетvconsoleВ качестве панели отладки на мобильном телефоне эта функция эквивалентна открытию консоли ПК, которая может легко просматривать ключевую информацию об отладке, такую ​​как консоль, сеть, элемент, хранилище и т. д.

Платформа мониторинга ошибок

Я мало что знаю о других платформах мониторинга ошибок, я просто помню, что писал в то времяPHPиспользуется, когдаsentry, поэтому в этом проекте она настроена как платформа мониторинга ошибок. В то же время используйте плагин этого большого парняПлагин babel, который автоматически добавляет функцию сообщения об ошибках, чтобы попытаться поймать во время компиляции., соответствующая конфигурация находится в.sentryclircВ этом файле конкретная соответствующая конфигурация будет запрашиваться при ее создании. Если вы не уверены, см.настроить часового

[defaults]
url=https://sentry.io
org=组织名
project=项目名

[auth]
token=token

Стиль фиксации GIT

Запись фиксации кода является хорошим журналом модификации кода. Стандартные записи отправки кода чрезвычайно важны в обычном процессе разработки и сопровождения кода, а также при обнаружении ошибок или откате версий.

Связанные инструкции

npm run git-cz

Подробное описание

1. Select the type of change that you're committing
选择您要提交的更改类型

2. What is the scope of this change (e.g. component or file name): (press enter to skip)
更改的范围是什么(例如,组件或文件名):(按Enter跳过)

3. Write a short, imperative tense description of the change (max 61 chars)
撰写简短的命令式时态描述(最多61个字符)

4. Provide a longer description of the change: (press enter to skip)
提供更改的详细说明:(按Enter跳过)

5. Are there any breaking changes?
有重大变化吗?

6. Does this change affect any open issues?
此更改会影响任何未解决的问题吗?

- feat 新功能
- fix Bug 修复
- docs 文档更新
- style 代码的格式,标点符号的更新
- refactor 代码重构
- perf 性能优化
- test 测试更新
- build 构建系统或者包依赖更新
- ci CI 配置,脚本文件等更新
- chore 非 src 或者 测试文件的更新
- revert commit 回退

Создать CHANGELOG.md

Также были настроены соответствующие директивы:

npm run genlog

Появится формат файла, подобный этому:

### Features

* 国际化 拦截器 完善模板 ([379b452](https://10.6.30.204/front/china-goods-h5/commits/379b4522f9c0c0a1c282281af68c92c1cca10858))
* 飞入购物车 ([f1a5f2d](https://10.6.30.204/front/china-goods-h5/commits/f1a5f2db2fe6e67e3b5801c26563ba9f089e470b))

PWA

PWA — это английская аббревиатура от Progressive Web App, что переводится как прогрессивно улучшаемое веб-приложение.Это концепция, предложенная Google в 2016 году, и веб-технология, внедренная в 2017 году. Цель состоит в том, чтобы использовать предоставленную стандартизированную структуру на мобильном терминале для реализации прогрессивного веб-приложения с пользовательским интерфейсом, аналогичным собственному приложению в веб-приложении.

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

Последние строительные леса Vue интегрированыpwaплагин, который будетpwaРеализация становится более простой, просто нужноvue.config.jsконфигурация в файлеpwaсвойства могут автоматически генерировать соответствующиеservice-worker.jsФайл конфигурации не будет здесь подробно описан.

Конфигурация веб-пакета

некоторые инструкции по настройке

# PWA
pwa: {
name: VUE_APP_TITLE,
workboxPluginMode: 'InjectManifest',
workboxOptions: {
swSrc: resolve('src/pwa/service-worker.js')
}
}

# 别名
configureWebpack: {
name: VUE_APP_TITLE,
resolve: {
alias: {
'@': resolve('src')
}
}
},

# 在样式引入时,对于变量的引入,需要在每个文件里都要引入一遍,为了避免每次使用时都需要单独引入一遍的问题,采用了style-resources-loader
pluginOptions: {
'style-resources-loader': {
preProcessor: 'scss',
patterns: [
resolve('src/styles/_variables.scss'),
resolve('src/styles/_mixins.scss')
]
}
},

# vconsole
config.plugin('VConsolePlugin')
.use(new VConsolePlugin({
filter: [],
enable: DEV && VCONSOLE === 'yes'
}))
.end()

# 引入 lodash 在页面可以直接使用 _.isString() ...
config.plugin('ProvidePlugin')
.use(new webpack.ProvidePlugin({
_: 'lodash'
}))
.end()

# 设置 svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()

# 提交 map 文件
config.plugin('sentryPlugin')
.use(new SentryPlugin({
release: version,
include: path.join(__dirname, './dist/static/js'),
urlPrefix: '~/vue-h5-template/statis/js',
ignore: ['node_modules']
}))
.end()

Связанные плагины

  • vconsole-webpack-plugin

  • @sentry/webpack-plugin

  • lodash-webpack-plugin

...

Некоторые детали также обрабатываются в проекте.Для получения подробной информации, пожалуйста, потяните проект для просмотра, спасибо за просмотр. Я думаю, это хорошо, чтобы дать звездуадрес шаблона, будет продолжать обновляться, если у вас есть какие-либо вопросы, вы можете оставить сообщение или добавить меня в WeChatgao1336650475