Введение
Это мобильная платформа, основанная на vue-cli4, которая включает в себя общую конфигурацию, упаковку компонентов и методы оптимизации веб-пакетов для проектов, которые можно использовать для быстрой разработки.
Стек технологий: vue-cli4 + webpack4 + vant + axios + less + postcss-px2rem
исходный кодGitHub.com/Майкл-Ли Чжиган…
// 安装依赖
npm install
// 本地启动
npm run dev
// 生产打包
npm run build
Год-два назад vue-cli3 уже дошел до версии 3.0+, но так как старые проекты привыкли к использованию скаффолдинга vue-cli2, то я и раньше писал статью.Создайте шаблон разработки vue-cli для мобильных устройств H5.Краткий обзор некоторых навыков мобильной разработки.
Недавно я обновил скаффолдинг vue-cli и обнаружил, что он был обновлен до версии 4.0+.Я чувствую, что необходимо использовать vue-cli4 для разработки в новых проектах.Кроме того, в последнее время я лучше разбираюсь в webpack, поэтому Я комбинирую vue-cli4 и webpack, создавая мобильную среду для работы из коробки. В основном включают следующие технические моменты:
- строительные леса vue-cli4
- вант вводится по требованию
- Адаптация мобильного терминала
- пакет перехвата axios
- Инкапсуляция функции класса утилиты
- конфигурация vue-маршрутизатора
- Проверка разрешения на вход
- Конфигурация нескольких переменных среды
- конфигурация vue.config.js
- пакет компонентов тостов
- инкапсуляция компонента диалога
- Настройки междоменного прокси
- Визуальный анализ упаковки webpack
- Оптимизация ресурсов CDN
- оптимизация упаковки gzip
- Домашняя страница добавить экран скелета
Дополнительные методы оптимизации веб-пакета см.GitHub.com/Майкл-Ли Чжиган…
Настроить Vant.
vant — это легкая и надежная библиотека мобильных компонентов Vue, которая очень подходит для мобильной разработки на основе стека технологий vue. Долгое время в прошлом я использовал фреймворк мобильного пользовательского интерфейса vux. Позже, поскольку vux не поддерживал vue-cli3, я переключился на vant.Должен сказать, что vant намного лучше, чем vux, с точки зрения интерактивности и логики кода, а у vant меньше ям.
Для сторонних компонентов пользовательского интерфейса, если все они будут введены, например, размер пакета будет слишком большим, а время загрузки домашней страницы будет слишком долгим, поэтому очень необходимо загружать по требованию. vant также предоставляет способ загрузки по запросу.babel-plugin-import
Это подключаемый модуль Babel, который автоматически преобразует метод импорта в метод импорта по запросу в процессе компиляции.
1. Установите зависимости
npm i babel-plugin-import -D
2. Настройте файл .babelrc или babel.config.js.
// 在.babelrc 中添加配置
{
"plugins": [
["import", {
"libraryName": "vant",
"libraryDirectory": "es",
"style": true
}]
]
}
// 对于使用 babel7 的用户,可以在 babel.config.js 中配置
module.exports = {
plugins: [
['import', {
libraryName: 'vant',
libraryDirectory: 'es',
style: true
}, 'vant']
]
};
3, введение по запросу
Вы можете напрямую импортировать компоненты Vant в код, и подключаемый модуль автоматически преобразует код в форму импорта по требованию в методе 2.
import Vue from 'vue'
import { Button } from 'vant'
Vue.use(Button)
рем-адаптация
Адаптация мобильного терминала — это то, с чем приходится сталкиваться в процессе разработки. Здесь мы используем px2rem-loader в postcss, чтобы преобразовать px в нашем проекте в rem в определенной пропорции, чтобы мы могли записать px в аннотацию на синем озере.
Мы выставляем html слово и шрифт в 100px, и многие выбирают установить его в 375px, но я думаю, что рем, преобразованный таким образом, недостаточно точен, и когда мы отлаживаем код на консоли, мы не можем быстро вычислить его оригинал значение пикселей. . Если мы установим 1rem=100px, 0,16rem и 0,3rem, которые мы видим, будут быстро рассчитаны как 16px и 30px.
Конкретные шаги заключаются в следующем;
1. Установите зависимости
npm install px2rem-loader --save-dev
2. Настройте следующее в vue.config.js.
css: {
// css预设器配置项
loaderOptions: {
postcss: {
plugins: [
require('postcss-px2rem')({
remUnit: 100
})
]
}
}
},
3. Установите html и размер шрифта в main.js
function initRem() {
let cale = window.screen.availWidth > 750 ? 2 : window.screen.availWidth / 375
window.document.documentElement.style.fontSize = `${100 * cale}px`
}
window.addEventListener('resize', function() {
initRem()
})
обертка запроса axios
1. Установите перехват запроса и перехват ответа
const PRODUCT_URL = 'https://xxxx.com'
const MOCK_URL = 'http://xxxx.com'
let http = axios.create({
baseURL: process.env.NODE_ENV === 'production' ? PRODUCT_URL : MOCK_URL,
})
// 请求拦截器
http.interceptors.request.use(
(config) => {
// 设置token,Content-Type
var token = sessionStorage.getItem('token')
config.headers['token'] = token
config.headers['Content-Type'] = 'application/json;charset=UTF-8'
// 请求显示loading效果
if (config.loading === true) {
vm.$loading.show()
}
return config
},
(error) => {
vm.$loading.hide()
return Promise.reject(error)
}
)
// 响应拦截器
http.interceptors.response.use(
(res) => {
vm.$loading.hide()
// token失效,重新登录
if (res.data.code === 401) {
// 重新登录
}
return res
},
(error) => {
vm.$loading.hide()
return Promise.reject(error)
}
)
2. Инкапсулируйте методы запроса get и post
function get(url, data, lodaing) {
return new Promise((resolve, reject) => {
http
.get(url)
.then(
(response) => {
resolve(response)
},
(err) => {
reject(err)
}
)
.catch((error) => {
reject(error)
})
})
}
function post(url, data, loading) {
return new Promise((resolve, reject) => {
http
.post(url, data, { loading: loading })
.then(
(response) => {
resolve(response)
},
(err) => {
reject(err)
}
)
.catch((error) => {
reject(error)
})
})
}
export { get, post }
3. Подключите методы get и post к экземпляру vue.
// main.js
import { get, post } from './js/ajax'
Vue.prototype.$http = { get, post }
Инкапсуляция функций класса инструмента
1. Добавьте методы в цепочку прототипов экземпляра vue.
export default {
install (Vue, options) {
Vue.prototype.util = {
method1(val) {
...
},
method2 (val) {
...
},
}
}
2. Зарегистрируйтесь через Vue.use () в main.js
import utils from './js/utils'
Vue.use(utils)
конфигурация vue-маршрутизатора
Обычно многие люди могут настроить путь и компонент для конфигурации vue-router и реализовать скачок маршрутизации. На самом деле, vue-router может многое, например:
- Конфигурация ленивой загрузки маршрута
- Изменить заголовок одностраничного приложения
- Проверка разрешения на вход
- Конфигурация кэша страниц
Конфигурация ленивой загрузки маршрута
3 способа реализации маршрутизации загрузки по требованию (маршрутизация ленивой загрузки) в проектах Vue:
// 1、Vue异步组件技术:
{
path: '/home',
name: 'Home',
component: resolve => reqire(['../views/Home.vue'], resolve)
}
// 2、es6提案的import()
{
path: '/',
name: 'home',
component: () => import('../views/Home.vue')
}
// 3、webpack提供的require.ensure()
{
path: '/home',
name: 'Home',
component: r => require.ensure([],() => r(require('../views/Home.vue')), 'home')
}
В этом проекте используется второй метод, оптимизированный для последующей упаковки веб-пакетов.
Изменить заголовок одностраничного приложения
Так как одностраничное приложение имеет только один html, заголовок всех страниц не изменится по умолчанию, но мы можем добавить соответствующие атрибуты в конфигурацию маршрутизации, а затем изменить заголовок страницы через js в роутгарде
router.beforeEach((to, from, next) => {
document.title = to.meta.title
})
Проверка разрешения на вход
В приложении обычно есть следующие сценарии, такие как торговый центр: некоторые страницы могут быть доступны без входа в систему, например, домашняя страница, страница сведений о продукте и т. д., которые могут быть видны пользователю в любой ситуации; но есть также некоторые страницы, которые требуют входа в систему только после доступа, такие как личный центр, корзина и так далее. На этом этапе вам необходимо контролировать доступ к странице.
Кроме того, для некоторых проектов, которым необходимо записывать информацию о пользователе и статус входа в систему, также требуется проверка разрешения на вход, чтобы люди со скрытыми мотивами не могли открыть страницу путем прямого доступа к URL-адресу страницы.
В настоящее время. Охранники маршрутизации могут помочь нам выполнить проверку входа. детали следующим образом:
1. Настройте атрибут auth метаобъекта маршрута
const routes = [
{
path: '/',
name: 'home',
component: () => import('../views/Home.vue'),
meta: { title: '首页', keepAlive: false, auth: false },
},
{
path: '/mine',
name: 'mine',
component: () => import('../views/mine.vue'),
meta: { title: '我的', keepAlive: false, auth: true },
},
]
2. Оцените главную страницу маршрутизации. когдаto.meta.auth
дляtrue
(требуется логин), и нет кеша информации для входа, вам нужно перенаправить на страницу входа
router.beforeEach((to, from, next) => {
document.title = to.meta.title
const userInfo = sessionStorage.getItem('userInfo') || null
if (!userInfo && to.meta.auth) {
next('/login')
} else {
next()
}
})
Конфигурация кэша страниц
В проекте всегда есть некоторые страницы, которые мы хотим кэшировать после загрузки, поэтому в это время используется keep-alive. keep-alive — это абстрактный компонент, предоставляемый Vue, который используется для кэширования компонентов для сохранения производительности.Поскольку это абстрактный компонент, он не будет отображаться в элементе DOM после рендеринга v-страницы.
1. Определите, нужно ли кэшировать страницу, настроив значение атрибута keepAlive метаобъекта маршрута.
const routes = [
{
path: '/',
name: 'home',
component: () => import('../views/Home.vue'),
meta: { title: '首页', keepAlive: false, auth: false },
},
{
path: '/list',
name: 'list',
component: () => import('../views/list.vue'),
meta: { title: '列表页', keepAlive: true, auth: false },
},
]
2. Выполните оценку кеша в app.vue
<div id="app">
<router-view v-if="!$route.meta.keepAlive"></router-view>
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
</div>
Конфигурация нескольких переменных среды
Прежде всего, давайте посмотрим на переменные среды.В общем, наш проект будет иметь три среды, локальную среду (разработка), тестовую среду (тест) и производственную среду (производство).Мы можем построить три конфигурации среды в корневом каталоге проекта.файл переменных.env.development
,.env.test
,.env.production
Файл переменных среды содержит только пары «ключ=значение» для переменных среды:
NODE_ENV = 'production'
VUE_APP_ENV = 'production' // 只有VUE_APP开头的环境变量可以在项目代码中直接使用
За исключением пользовательского VueAPP*В дополнение к переменным доступны еще две переменные:
- NODE_ENV : один из вариантов «разработка», «производство» или «тест». Точное значение зависит от режима, в котором работает приложение.
- BASE_URL: соответствует параметру publicPath в vue.config.js, который является базовым путем, по которому будет развернуто ваше приложение.
Приступим к настройке переменных окружения.
1. Создайте новый .env.* в корневом каталоге проекта.
- .env.development конфигурация локальной среды разработки
NODE_ENV='development'
VUE_APP_ENV = 'development'
- Конфигурация тестовой среды env.staging
NODE_ENV='production'
VUE_APP_ENV = 'staging'
- env.production официальная конфигурация среды
NODE_ENV='production'
VUE_APP_ENV = 'production'
Чтобы настроить больше переменных в разных средах, мы создаем новую конфигурацию/индекс в файле src.
// 根据环境引入不同配置 process.env.NODE_ENV
const config = require('./env.' + process.env.VUE_APP_ENV)
module.exports = config
Создайте новый в том же каталогеenv.development.js
,env.test.js
,env.production.js
, и настройте в нем необходимые переменные.
Возьмите env.development.js в качестве примера.
module.exports = {
baseUrl: 'http://localhost:8089', // 项目地址
baseApi: 'https://www.mock.com/api', // 本地api请求地址
}
2. Настройте команду упаковки
скрипты в package.json Пакетные команды для разных сред
- Запустите локально с помощью npm run serve
- Пакетные тесты с npm run test
- Формально упаковано через сборку npm run
"scripts": {
"dev": "vue-cli-service serve",
"build": "vue-cli-service build",
"test": "vue-cli-service build --mode test",
}
конфигурация vue.config.js
Начиная с vue-cli3, новый каркас требует от нас настройки нашего проекта в vue.config.js. в основном включает
- Место вывода файла после упаковки
- Закройте исходную карту производственной среды
- настроить rem для преобразования px
- Настроить псевдоним псевдоним
- Удалить консоль производственной среды
- Настройки междоменного прокси
Кроме того, существует множество конфигураций, оптимизированных для упаковки, которые будут перечислены позже.
module.exports = {
publicPath: './', // 默认为'/'
// 将构建好的文件输出到哪里,本司要求
outputDir: 'dist/static',
// 放置生成的静态资源(js、css、img、fonts)的目录。
assetsDir: 'static',
// 指定生成的 index.html 的输出路径
indexPath: 'index.html',
// 是否使用包含运行时编译器的 Vue 构建版本。
runtimeCompiler: false,
transpileDependencies: [],
// 如果你不需要生产环境的 source map
productionSourceMap: false,
// 配置css
css: {
// 是否使用css分离插件 ExtractTextPlugin
extract: true,
sourceMap: true,
// css预设器配置项
loaderOptions: {
postcss: {
plugins: [
require('postcss-px2rem')({
remUnit: 100,
}),
],
},
},
// 启用 CSS modules for all css / pre-processor files.
modules: false,
},
// 是一个函数,允许对内部的 webpack 配置进行更细粒度的修改。
chainWebpack: (config) => {
// 配置别名
config.resolve.alias
.set('@', resolve('src'))
.set('assets', resolve('src/assets'))
.set('components', resolve('src/components'))
.set('views', resolve('src/views'))
config.optimization.minimizer('terser').tap((args) => {
// 去除生产环境console
args[0].terserOptions.compress.drop_console = true
return args
})
},
// 是否为 Babel 或 TypeScript 使用 thread-loader。该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。
parallel: require('os').cpus().length > 1,
devServer: {
host: '0.0.0.0',
port: 8088, // 端口号
https: false, // https:{type:Boolean}
open: false, // 配置自动启动浏览器 open: 'Google Chrome'-默认启动谷歌
// 配置多个代理
proxy: {
'/api': {
target: 'https://www.mock.com',
ws: true, // 代理的WebSockets
changeOrigin: true, // 允许websockets跨域
pathRewrite: {
'^/api': '',
},
},
},
},
}
Упаковка основных компонентов
В процессе разработки проекта обычно используется множество компонентов со схожими функциями и дизайном, тосты и диалоговые компоненты в основном используются в каждом мобильном проекте. Чтобы лучше соответствовать стилю дизайна пользовательского интерфейса нашей компании, мы не использовали напрямую тосты и диалоговые компоненты Vant, а сами инкапсулировали аналогичные компоненты, которые можно вызывать напрямую, например:
this.$toast({ msg: '手机号码不能为空' })
this.$toast({
msg: '成功提示',
type: 'success',
})
this.$dialog({
title: '删除提示',
text: '是否确定删除此标签?',
showCancelBtn: true,
confirmText: '确认',
confirm(content) {
alert('删除成功')
},
})
Схема эффекта выглядит следующим образом
всплывающий входящий параметр
Props
name | type | default | description |
---|---|---|---|
msg | String | '' | всплывающее окно |
type | String | '' | Тип всплывающего окна: success (подсказка об успехе), fail (подсказка об ошибке), warning (предупреждение), loading (загрузка) |
Диалог входящих параметров
Props
name | type | default | description |
---|---|---|---|
title | String | '' | заглавие |
text | String | '' | текстовое содержание |
type | String | '' | Обычный текст по умолчанию, ввод (поле ввода) |
maxlength | Number | 20 | Максимальное количество введенных символов |
confirmText | String | Конечно | правая кнопка |
cancelText | String | Отмена | левая кнопка |
Events
name | params | description |
---|---|---|
confirm | null | обратный звонок после выбора |
cancel | ull | Обратный звонок после отмены |
визуальный анализ веб-пакета
Отсюда мы начинаем с упаковки, оптимизированной для webpack. Сначала давайте проанализируем узкое место в производительности упаковки webpack, выясним проблему, а затем пропишем правильное лекарство. На данный момент используется webpack-bundle-analyzer. 1. Установите зависимости
npm install webpack-bundle-analyzer -D
2. Настройте в vue.config.js
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
configureWebpack: (config) => {
if (process.env.NODE_ENV === 'production') {
config.plugins.push(new BundleAnalyzerPlugin())
}
}
После упаковки мы можем увидеть вот такой график зависимости
Из приведенного выше интерфейса мы можем получить следующую информацию:
- Что входит в упакованный файл и зависимости между модулями
- Доля размера каждого файла в общем, узнайте файлы большего размера, подумайте, есть ли альтернатива, не содержит ли она ненужных зависимостей?
- Есть ли повторяющиеся зависимости и как это можно оптимизировать?
- Сжатый размер каждого файла.
Оптимизация ресурсов CDN
Полное название CDNContent Delivery Network
, сеть распространения контента. CDN — это сеть распространения контента, построенная в сети, опирающаяся на пограничные серверы, развернутые в разных местах, с помощью балансировки нагрузки, распределения контента, планирования и других функциональных модулей центральной платформы, чтобы пользователи могли получать желаемый контент поблизости, уменьшать сеть. перегрузки и улучшить доступ пользователей Скорость отклика и частота попаданий. Ключевые технологии CDN в основном включают технологии хранения и распространения контента.
По мере того, как проект становится все больше и больше, он зависит от все большего количества сторонних пакетов npm, и файлы после сборки также будут становиться все больше и больше. В сочетании с одностраничным приложением это может привести к длительным белым экранам при низкой скорости интернета или ограниченной пропускной способности сервера. На этом этапе мы можем использовать метод CDN для оптимизации скорости загрузки сети.
1. будетvue、vue-router、vuex、axios
Все ресурсы этих корзин семейства vue получены через ссылки CDN.index.html
Вставьте соответствующую ссылку.
<body>
<div id="app"></div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.min.js"></script>
<script src="https://cdn.bootcss.com/vuex/3.1.0/vuex.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/element-ui/2.6.1/index.js"></script>
</body>
2. Вvue.config.js
Настройте свойство externals
module.exports = {
···
externals: {
'vue': 'Vue',
'vuex': 'Vuex',
'vue-router': 'VueRouter',
'axios':'axios'
}
}
3. Удалите пакет связанных зависимостей npm.
npm uninstall vue vue-router vuex axios
На этом этапе вы можете запустить проект и запустить его. В консоли мы можем обнаружить, что проект загружает указанные выше четыре ресурса CDN.
Тем не менее, есть много голосов, говорящих, что загрузка ресурсов CDN в корзину семейства vue не очень полезна, а общедоступные ресурсы CDN не так стабильны, как пакеты npm.Это вопрос мнения. Поэтому я делаю эту оптимизацию во вновь созданной ветке в исходном коде. Когда проект небольшой, оптимизация CDN не рассматривается.
Конечно, при внедрении других более крупных сторонних ресурсов, таких как echarts, AMAP (Амап), по-прежнему необходимо использовать ресурсы CDN.
ускоренная оптимизация gZip
Все современные браузеры поддерживают сжатие gzip. Включение сжатия gzip может значительно уменьшить размер передаваемых ресурсов, тем самым сокращая время загрузки ресурсов, сокращая время до появления первого пустого экрана и улучшая взаимодействие с пользователем.
gzip лучше всего работает с текстовыми форматами файлов (например, CSS, JavaScript и HTML), часто достигая 70–90% сжатия при сжатии больших файлов, а также для уже сжатых ресурсов (например, изображений). очень плохой.
const CompressionPlugin = require('compression-webpack-plugin')
configureWebpack: (config) => {
if (process.env.NODE_ENV === 'production') {
config.plugins.push(
new CompressionPlugin({
// gzip压缩配置
test: /\.js$|\.html$|\.css/, // 匹配文件名
threshold: 10240, // 对超过10kb的数据进行压缩
deleteOriginalAssets: false, // 是否删除原文件
})
)
}
}
Домашняя страница добавить экран скелета
С постепенной популярностью SPA во внешнем мире одностраничные приложения неизбежно увеличивают нагрузку на загрузку домашней страницы, и в настоящее время решающее значение имеет хороший пользовательский интерфейс домашней страницы. Многие приложения используют метод «скелетного экрана» для отображения незагруженного контента, предоставляя пользователям совершенно новый опыт.
Так называемый скелетный экран использует некоторую графику, чтобы занимать место, когда содержимое страницы не загружено, а затем заменяет ее после загрузки содержимого. Во время этого процесса пользователь заметит, что содержимое постепенно загружается и вот-вот будет отображено, что снижает негативное впечатление от «белого экрана».
В этой статье используется подключаемый модуль vue-skeleton-webpack-plugin для внедрения каркасных экранов в одностраничные приложения.
1. Skeleton1.vue и Skeleton2.vue создаются в общей папке src.Специфическая структура и стиль разработаны сами по себе, и здесь опущено 10 000 слов. . . .
2. Создайте новую запись-skeleton.js в том же каталоге.
import Vue from 'vue'
import Skeleton1 from './Skeleton1'
import Skeleton2 from './Skeleton2'
export default new Vue({
components: {
Skeleton1,
Skeleton2
},
template: `
<div>
<skeleton1 id="skeleton1" style="display:none"/>
<skeleton2 id="skeleton2" style="display:none"/>
</div>
`
})
Настройте плагин в vue.config.js
const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin')
configureWebpack: (config) => {
config.plugins.push(
new SkeletonWebpackPlugin({
webpackConfig: {
entry: {
app: path.join(__dirname, './src/common/entry-skeleton.js'),
},
},
minimize: true,
quiet: true,
router: {
mode: 'hash',
routes: [
{ path: '/', skeletonId: 'skeleton1' },
{ path: '/about', skeletonId: 'skeleton2' },
],
},
})
)
}
В этот момент перезагрузите страницу, чтобы увидеть наш каркасный экран.Примечание. Обязательно настройте извлечение разделения стилей: true
рекомендуемая статья
Подпишитесь на мою официальную учетную запись, чтобы время от времени делиться передовыми знаниями и добиваться прогресса вместе с вами!