предисловие
Первые две статьи обобщают большую часть навыков и содержания разработки Vue, а последняя статья подводит итоги.
В этой статье давайте поговорим о некоторых проблемах, которые требуют немного большего понимания и практики Vue.
прежде всегоЖизненный циклЭтот фрагмент содержания, с большей практикой, чем больше его значение, тем глубже понимание
mixinОн имеет мощные функции и предъявляет высокие требования к организации повторного использования кода.Это продвинутая техника для более поздней разработки Vue.
рендеринг на стороне сервераЭто может быть последняя позиция для изучения Vue, важная веха для платформы SPA.
Наконец, чтобы обобщить то, что я использую при использовании VueНавыки и опыт
Регулярная работа, ставь лайк и смотри первым! Ваши лайки - одна из мотиваций для моего творчества!
Резюме
Я расскажу о некоторых методах и принципах процесса разработки Vue с 16 аспектов. Если вы не читали предыдущую статью, вы можете перейти к
- 16 аспектов углубленных навыков разработки фронтенда "Часть 1"
- Углубленные навыки разработки переднего плана в 16 аспектах
Обзор этой статьи
Жизненный цикл Vue
Каков жизненный цикл Vue?
Жизненный цикл Vue примерно таков: процесс от создания экземпляра Vue до уничтожения компонента.
В частности, мы разделены на несколько основных этапов, и на каждом этапе есть набор функций-ловушек для выполнения нужного нам кода.
Фазы жизненного цикла и крючки
Давайте разберем и классифицируем эти хуки жизненного цикла и разделим их на 4 основных этапа для удобства запоминания:
Для удобства читательской памяти попробуйте использовать значки здесь:
Видно, что названия хуков на каждом этапе хорошо запоминаются и используются до начала этапа.
beforeXxx
, используется после окончания фазыxxxed
кроме этого8
основные крючки, плюс3
новые функциональные хуки, в настоящее время в общей сложности11
крюк
Кстати это3
функция крючка
-
кеш компонентов,
activated
а такжеdeactivated
, эти два крючка также являются парой, соответственно указывая на то, чтоkeep-alive
Вызывается при активации и деактивации кэшированного компонента. -
Перехват ошибок компонента,
errorCaptured
, который меньше используется для обработки ошибок исключений в компонентах.
Графический жизненный цикл
Давайте взглянем на официальную диаграмму в разделе примеров учебника по Vue.Перейти непосредственно к официальному руководству
Официальная иллюстрация
Официальная иллюстрация не объясняет картину в деталях. Я думаю, с одной стороны, причина в том, что все детали, связанные с этой картинкой, отражены в исходном коде vue, и это не так просто объяснить. С другой стороны, я надеюсь, что мы сможем лучше понять смысл на практике.
Основной процесс исходного кода Vue
Чтобы понять приведенную выше картинку, нам нужно разобраться в исходном коде Vue, чтобы понять его по-настоящему. Вероятно, исходя из имеющегося исходного кода, я разобрал общий процесс:
Мы можем ясно видеть, что в процессе создания экземпляра Vue, монтажа компонентов и рендеринга есть очевидные узлы цикла.
Упрощенная текстовая иллюстрация
В сочетании с приведенным выше процессом исходного кода и соответствующими практиками упростите период, выполняемый на каждом этапе, и состояние компонента в каждом хуке.
Практическая проверка жизненного цикла
отправить вопросы
Ниже мы задаем несколько вопросов:
- Когда был создан Эль?
- Когда монтировать данные?
- В течение какого периода можно получить доступ к дому?
- Когда будут обновлены компоненты? Является ли обновление синхронным или асинхронным?
- Когда компонент будет уничтожен?
- К чему еще можно получить доступ после уничтожения компонента?
Написать код
- Сначала напишите небольшую демонстрацию, чтобы распечатать информацию о ключевых компонентах.
<template>
<div>
<div class="message">
{{message}}
</div>
</div>
</template>
<script>
export default {
data() {
return {
message: '1'
}
},
methods: {
printComponentInfo(lifeName) {
console.log(lifeName)
console.log('el', this.$el)
console.log('data', this.$data)
console.log('watch', this.$watch)
}
}
}
</script>
- Добавьте 8 хуков жизненного цикла в ядро и вызовите метод печати соответственно.
// ...
beforeCreate() {
this.printComponentInfo('beforeCreate')
},
created() {
this.printComponentInfo('created')
},
beforeMount() {
this.printComponentInfo('beforeMount')
},
mounted() {
this.printComponentInfo('mounted')
},
beforeUpdate() {
this.printComponentInfo('beforeUpdate')
},
updated() {
this.printComponentInfo('updated')
},
beforeDestroy() {
this.printComponentInfo('beforeDestroy')
},
destroyed() {
this.printComponentInfo('destroyed')
},
// ...
создать сцену
beforeCreate
серединаmethods
Метод в методе напрямую сообщает об ошибке и не может быть доступен, прямой доступel
а такжеdata
назад
найдено только доступноеwatch
,el
а такжеdata
не могу получить доступ
created
периодel
Не могу дотянуться, но могу дотянутьсяdata
охватывать
горная сцена
beforeMount
доступный вdata
Но все еще не могу получить доступel
mounted
можно получить вel
охватывать
Когда страница загружается в первый раз, фаза обновления и фаза уничтожения не запускаются для хука.
этап обновления
Добавляем строчку кода
this.message = this.message + 1
Если увеличитьcreated
Этап, найденupdate
Крючок все еще не стреляет, ноel
а такжеdata
значение стало2
Если увеличитьmounted
стадия, найденоupdate
Крючок на этот раз вызван
фаза разрушения
Как активировать крючок уничтожения? наверное есть несколько способов
- вызов вручную
$destory
-
v-if
а такжеv-for
инструкция,(v-show
нет) - Переключение маршрута и закрытие или обновление браузерамы в
mounted
Добавьте строку кода в хук, чтобы вручную уничтожить текущий компонент или перейти к маршруту
this.$destory('lifecycle')
ОбнаружитьbeforeDestory
а такжеdestoryed
срабатывают, иel
,data
то же самое все еще может быть доступно
Распространенные сценарии использования хуков жизненного цикла
beforeCreate будьте осторожны с этим
beforeCreate
не могу дотянутьсяthis
серединаdata
,method
// 错误实例
beforeCreate() {
// 允许
console.log('ok')
// 不允许
this.print() // 报错找不到
this.message = 1 // 报错找不到
}
Запрос должен быть помещен в созданный хук
created
Может получить доступ к этому, но не может получить доступ к dom, dom не смонтирован
created() {
// 允许并推荐
this.$http.get(xxx).then(res => {
this.data = res.data
})
// 不允许
this.$el
this.$ref.demo
const a = document.getElementById('demo')
}
Код операции должен быть установлен DOM крючки
mounted
смонтированныйdom
, может получить доступthis
mounted() {
// 允许
this.$el
this.$ref.demo
let a = document.getElementById('')
}
Демонстрационный код, связанный с жизненным циклом, см.github-lifecycle-demo
Понимайте и используйте миксины с умом
Что такое миксин
Когда компонент использует миксин, все параметры миксина будут «смешаны» с собственными параметрами компонента. Общий принцип заключается в том, чтобы каким-то образом сочетать иностранные компоненты и методы. Правила слияния немного похожи на наследование и расширение.
Когда компоненты и примеси содержатОдин и тот же вариант имени, эти параметры будут "объединены" соответствующим образом
Давайте посмотрим, что может быть объединено в компоненте
// mixins/demo
export default {
data() {
return {}
},
mounted() {},
methods: {},
computed: {},
components: {},
directives: {}
}
data
,methods
,computed
,directives
,components
крючки жизненного цикла
Да, их можно смешивать
import demoMixin form '@/mixins/demo'
export default {
mixins: [demoMixin]
}
Таким образом, мы можем напрямую извлечь повторяющийся код многих страниц.
Или инкапсулировать как публичный миксин
Например, когда мы делаем страницы H5, в SMS-проверке есть много встроенной логики, но нам нужно получить доступ кthis
. Конечно, не используя служебные функции.
В настоящее время вы можете рассмотреть возможность использования миксина и инкапсулировать его в адаптивный модуль. Вводить там, где это необходимо.
правила миксина
прежде всегоприоритетВопрос о том, какой из них выбрать в качестве конечного результата при дублировании вариантов имени
Правила по умолчанию делятся на3
Добрый
-
data
mixin: использовать текущее значение компонента в качестве последнего значения - Хуки жизненного цикла: сохранить все хуки, сначала выполнить примеси, а затем выполнить текущий компонент.
-
methods
,computed
,directives
,components
Эта форма пары ключ-значение, одно и то же имяkey
, все основано на текущих компонентах
Конечно, если вы хотите изменить правила, вы также можете изменить правила через конфигурацию.
Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {
// 返回合并后的值
}
Преимущества миксинов
Мы знаем, что наиболее повторно используемый код в Vue — этокомпоненты. В общем, проходимprops
Для управления компонентами исходные компоненты инкапсулируются в компоненты HOC более высокого порядка. контролируяprops
Код, генерирующий разные функции, по-прежнему пишется в базовом компоненте.
<template lang="pug">
div.dib
van-button.btn(
@click="$emit('click')"
:class="getClass" v-bind="$attrs"
:style="{'width': size === 'large' ? '345px': '', 'backgroundColor': getBgColor, borderColor: getBgColor, color: getBgColor}")
slot
</template>
<script>
import { Button } from 'vant'
import Vue from 'vue'
import { getColor } from '@/utils'
Vue.use(Button)
export default {
name: 'app-button',
props: {
type: {
type: String,
default: 'primary'
},
theme: {
type: String,
default: 'blue'
},
size: {
type: String,
default: ''
}
}
}
Возьмите этот компонент в качестве примера,Мы по-прежнему общие внутренние компоненты по логике, чтобы изменить поведение компонента.
Однако использование примесей предлагает другую идею. Мы пишем публичный миксин везде, где нужно его использовать. Осуществляем слияние расширений, и настраиваем параметры в текущем компоненте, то есть расширения, которые отличаются от общедоступных параметров миксина.Наша новая логика написана в текущем компоненте, а не в общедоступных миксинах..
Нарисуйте картинку, чтобы понять:
Наконец, суммируйте преимущества mixin
- Код повторного использования, отдельная общая логика
- может получить доступ
this
, может манипулировать реактивным кодом - Миксины больше похожи на расширения, чем на компоненты
Сказав все это, что такого плохого в миксинах?
Во-первых, не злоупотребляйте глобальными миксинами, так как они повлияют на все компоненты с несколькими дочерними компонентами.
Во-вторых, из-за неотъемлемого влияния стратегии слияния миксинов в некоторых крайних случаях она может не достичь желаемого эффекта..
Например: у меня есть присутствиеmixins
, у меня также есть некоторые методы на моей странице, я хочу представитьmixins
Требуется много изменений, чтобы убедиться, что мой код работает так, как я хочу.
страницаdata
есть одинmessage
стоимость,mixins
Внутри тоже есть один.
По умолчанию,mixins
внутриmessage
будет включено в страницуmessage
покрытие. Но эти двоеmessage
Он может представлять разные значения, и все они должны существовать. Тогда мне нужно изменить один из них, если дело слишком глубокое, может быть, этоmessage
Не так хорошо, как хотелось бы.
Иногда эти вопросы необходимо учитывать, что приводит к использованиюmixins
Увеличит нагрузку на разработку. Конечно, эти проблемы также можно обойти с помощью спецификаций.
Понимать и использовать SSR
SSR — это сокращение от Serve Side Render, что переводится как то, что мы часто называем рендерингом на стороне сервера.
Кратко о причинах существования ССР
- SPA-фреймворк SEO-решения
- Улучшить скорость загрузки первого экрана
Но у него все еще есть следующие проблемы
- Некоторые крючки жизненного цикла не могут быть использованы (ранее упомянутые
activated
а такжеdeactivated
так далее) - много дополнительных настроек
- Требования к ресурсам сервера
В общем, SSR необходим, но не достаточен. Для SEO SPA нет лучшего решения. Для сайтов с большим спросом в этом плане SSR действительно необходим.
Принцип ССР
Из приведенного выше рисунка мы можем получить несколько точек
- Пишется только один набор общего бизнес-кода.
- Получите доступ к экземпляру Vue, открыв входы клиента и сервера.
- Два пакета упаковываются инструментом сборки, а серверный пакет отображается в браузере через узел-сервер. Клиент получается путем доступа к ресурсу, как и раньше.
Есть 3 способа реализации SSR
1. Соберите SSR в соответствии с руководством на официальном сайте, шаг за шагом, вот подробностируководство, немного хлопотно, но можно прочувствовать процесс сборки и углубиться в детали. Использование для учений и модернизации существующих проектов
2. Используйте демонстрацию для преобразования, демонстрацию с открытым исходным кодом, удобную и экономящую время, подходящую для изучения кода.vue-ssr-demo
3. Использование nuxt, SSR и предварительный рендеринг предустановлены для новых проектов, требующих SSR.
Попробуйте построить SSR этими тремя способами
Пять простых шагов, чтобы понять SSR
Основная цель здесь - углубить понимание, vue-cli3+ реализует базовую SSR.
Шаг 1: Установите зависимости
- vue-server-renderer (зависимость ядра, версия должна совпадать с версией vue)
- webpack-merge (для слияния конфигурации webpack)
- webpack-node-externals (для изменений конфигурации webpack)
- экспресс (для рендеринга на стороне сервера)
Шаг 2: Постройте вход и преобразите его
разделен на2
вход, будетmain.js
Установить как общую запись и добавить дополнительнуюentry-client.js
а такжеentry-serve.js
два
1. Преобразуйте основную запись и создайте фабричную функцию
// main.js
import Vue from 'vue'
import App from './App.vue'
import { createRouter } from "./router"
// app、router
export function createApp () {
const router = createRouter()
const app = new Vue({
router,
render: h => h(App)
})
return { app, router }
}
2. Вход клиента
// client.js
import { createApp } from './main'
// 客户端特定引导逻辑
const { app } = createApp()
app.$mount('#app')
3. Вход на сервер
// serve.js
import { createApp } from "./main";
export default context => {
// 因为有可能会是异步路由钩子函数或组件,所以我们将返回一个 Promise
return new Promise((resolve, reject) => {
const { app, router } = createApp();
// 设置服务器端 router 的位置
router.push(context.url);
// 等到 router 将可能的异步组件和钩子函数解析完
router.onReady(() => {
const matchedComponents = router.getMatchedComponents();
// 匹配不到的路由,执行 reject 函数
if (!matchedComponents.length) {
return reject({
code: 404
});
}
// Promise 应该 resolve 应用程序实例,以便它可以渲染
resolve(app);
}, reject);
});
};
Шаг 3: Измените конфигурацию vue.config
const VueSSRServerPlugin = require("vue-server-renderer/server-plugin");
const VueSSRClientPlugin = require("vue-server-renderer/client-plugin");
const nodeExternals = require("webpack-node-externals");
const merge = require("webpack-merge");
const TARGET_NODE = process.env.WEBPACK_TARGET === "node";
const target = TARGET_NODE ? "server" : "client";
module.exports = {
configureWebpack: () => ({
entry: `./src/entry-${target}.js`,
devtool: 'source-map',
target: TARGET_NODE ? "node" : "web",
node: TARGET_NODE ? undefined : false,
output: {
libraryTarget: TARGET_NODE ? "commonjs2" : undefined
},
externals: TARGET_NODE
? nodeExternals({
whitelist: [/\.css$/]
})
: undefined,
optimization: {
splitChunks: undefined
},
plugins: [TARGET_NODE ? new VueSSRServerPlugin() : new VueSSRClientPlugin()]
}),
//...
};
Шаг 4: Измените маршрутизатор
export function createRouter(){
return new Router({
mode: 'history',
routes: [
//...
]
})
}
Шаг 5. Используйте код экспресс-запуска сервера
Этот шаг в основном предназначен для того, чтобы позволить серверу узла отвечать на HTML для доступа к браузеру.
const Vue = require('vue')
const server = require('express')()
const renderer = require('vue-server-renderer').createRenderer()
server.get('*', (req, res) => {
const app = new Vue({
data: {
url: req.url
},
template: `<div>访问的 URL 是: {{ url }}</div>`
})
renderer.renderToString(app, (err, html) => {
if (err) {
res.status(500).end('Internal Server Error')
return
}
res.end(`
<!DOCTYPE html>
<html lang="en">
<head><title>Hello</title></head>
<body>${html}</body>
</html>
`)
})
})
server.listen(8080)
Новый опыт
Простые шаги, чтобы испытать nuxt
После установки
После краткого просмотра исходного кода nuxt инкапсулирует все важные преобразования, о которых мы упоминали ранее, в.nuxt
в папке
Запустите dev и обнаружите, что есть два конца, конец clinet и конец сервера.
Наконец, проверьте эффект, весь процесс очень шелковистый. Структура каталогов также больше соответствует моему стилю, новые проекты нуждаются в SSR, рассмотрит возможность использования nuxt.
Предварительная визуализация с помощью плагина webpack
Является ли SSR единственным решением проблем SEO? На самом деле пререндеринг тоже можно делать, в первую очередь
Разница между использованием SSR и предварительным рендерингом
- Проблема, решаемая рендерингом на стороне сервера, заключается не только в отправке HTML-страниц в браузер, но, что более важно, после обработки динамической логики и JS-кода полный HTML-код после рендеринга отправляется в браузер, а процесс рендеринга происходит на сервере. сторона.
- Предварительный рендеринг заключается в использовании инструмента сборки для создания статического HTML в веб-пакете непосредственно в браузере, а процесс рендеринга является локальным.
- Есть два типа плагинов пререндеринга, которые нельзя использовать: большое количество маршрутов, динамический контент
Простой предварительный рендеринг с помощью prerender-spa-plugin
- Установить
prerender-spa-plugin
yarn prerender-spa-plugin
- Измените конфигурацию веб-пакета, выполнить настройку относительно просто.
const path = require('path')
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
module.exports = {
plugins: [
//...
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, 'dist'),
outputDir: path.join(__dirname, 'prerendered'),
indexPath: path.join(__dirname, 'dist', 'index.html'),
routes: [ '/', '/about', '/some/deep/nested/route' ],
postProcess (renderedRoute) {
renderedRoute.route = renderedRoute.originalPath
renderedRoute.html = renderedRoute.html.split(/>[\s]+</gmi).join('><')
if (renderedRoute.route.endsWith('.html')) {
renderedRoute.outputPath = path.join(__dirname, 'dist', renderedRoute.route)
}
return renderedRoute
},
minify: {
collapseBooleanAttributes: true,
collapseWhitespace: true,
decodeEntities: true,
keepClosingSlash: true,
sortAttributes: true
},
renderer: new Renderer({
inject: {
foo: 'bar'
},
maxConcurrentRoutes: 4
]
}
Резюме навыков разработки Vue
Улучшение с 5 основных точек зренияЭффективность разработкиа такжеопыт,красивый кода такжекачество кода,Пользовательский опыт
5 большой угол подъема
повторное использование кода
- Компонентная разработка, эффективность кода
* n
- использовать
mixins
Извлечение общей логики, эффективность кода* n
- Вспомогательные функции, использование
filter
Эффективность кодирования+ -
sass
Мультиплексcss
, опыт программирования, эффективность+
качество кода
- статическая проверка кода
eslint + prettier
, стиль кода+, основная синтаксическая ошибка- - контроль типа данных
typescript
, качество кода+ - Интерфейсное тестирование
test
, качество кода+
Оптимизация кода
- добросовестное использование
vue
, производительность рендеринга+ - добросовестное использование
vuex
Уменьшите количество запросов, используйте ленивую загрузку изображений, загрузите производительность+ - Разумное использование функциональных компонентов, производительность компонентов +
- Разумный каркасный экран, переход маршрутизации, пользовательский опыт +
Эффективность разработки
- Используйте обновленные леса
vue-cli4
,webpack
Эффективность конфигурации+ - Используйте настроенный шаблон каркаса
vue-h5-template
,vue
Эффективность конфигурации+ - Использование более компактного шаблона
pug
,HTML
Эффективность письма+ - использовать более мощный
css
записыватьsass
,CSS
Эффективность письма+ - Использование фиктивных данных
mock
, из-за эффективности внутренней разработки+ - Упаковка компонентов с открытым исходным кодом
HOC
, Разработка компонентов, Эффективность написания страниц+
Разрешение узких мест
- маршрутизация
history
Использование, конфигурация сервера,URL
красивый+ - решить
SEO
С загрузкой первого экрана, рендеринг на стороне сервераSSR
основное решение
постскриптум
Автор столкнулся с двойным ударом, будучи «безработным» и «заземленным» дома, и все же настоял на завершении последней статьи в этой серии.
Если он может помочь вам, это его величайшая ценность. смотри здесь еще нетподобно, слишком много, чтобы пойти! 😄
В связи с ограниченным техническим уровнем, если в статье есть какая-либо ошибка, укажите ее в комментариях, спасибо!
После этого автор должен закрепить базовые знания и запланировать написание «Серии археологических статей», с одной стороны, для укрепления своего фундамента и облегчения интервью. С другой стороны, я хочу успокоиться и выдержать оставшиеся 10 дней заземления. Надеюсь в будущем уделять больше внимания!