Понять практику разработки проекта Vue | 16 аспектов углубленных навыков разработки интерфейсов "Часть 2"

Vue.js
Понять практику разработки проекта Vue | 16 аспектов углубленных навыков разработки интерфейсов "Часть 2"

предисловие

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

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

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

mixinОн имеет мощные функции и предъявляет высокие требования к организации повторного использования кода.Это продвинутая техника для более поздней разработки Vue.

рендеринг на стороне сервераЭто может быть последняя позиция для изучения Vue, важная веха для платформы SPA.

Наконец, чтобы обобщить то, что я использую при использовании VueНавыки и опыт

Регулярная работа, ставь лайк и смотри первым! Ваши лайки - одна из мотиваций для моего творчества!

Резюме

Я расскажу о некоторых методах и принципах процесса разработки Vue с 16 аспектов. Если вы не читали предыдущую статью, вы можете перейти к

Обзор этой статьи

Жизненный цикл Vue

Каков жизненный цикл Vue?

Жизненный цикл Vue примерно таков: процесс от создания экземпляра Vue до уничтожения компонента.

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

Фазы жизненного цикла и крючки

Давайте разберем и классифицируем эти хуки жизненного цикла и разделим их на 4 основных этапа для удобства запоминания:

Для удобства читательской памяти попробуйте использовать значки здесь:

Видно, что названия хуков на каждом этапе хорошо запоминаются и используются до начала этапа.beforeXxx, используется после окончания фазыxxxed

кроме этого8основные крючки, плюс3новые функциональные хуки, в настоящее время в общей сложности11крюк Кстати это3функция крючка

  1. кеш компонентов,activatedа такжеdeactivated, эти два крючка также являются парой, соответственно указывая на то, чтоkeep-aliveВызывается при активации и деактивации кэшированного компонента.
  2. Перехват ошибок компонента,errorCaptured, который меньше используется для обработки ошибок исключений в компонентах.

Графический жизненный цикл

Давайте взглянем на официальную диаграмму в разделе примеров учебника по Vue.Перейти непосредственно к официальному руководству

Официальная иллюстрация

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

Основной процесс исходного кода Vue

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

Мы можем ясно видеть, что в процессе создания экземпляра Vue, монтажа компонентов и рендеринга есть очевидные узлы цикла.

Упрощенная текстовая иллюстрация

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

Практическая проверка жизненного цикла

отправить вопросы

Ниже мы задаем несколько вопросов:

  1. Когда был создан Эль?
  2. Когда монтировать данные?
  3. В течение какого периода можно получить доступ к дому?
  4. Когда будут обновлены компоненты? Является ли обновление синхронным или асинхронным?
  5. Когда компонент будет уничтожен?
  6. К чему еще можно получить доступ после уничтожения компонента?

Написать код

  1. Сначала напишите небольшую демонстрацию, чтобы распечатать информацию о ключевых компонентах.
<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>
  1. Добавьте 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Добрый

  1. datamixin: использовать текущее значение компонента в качестве последнего значения
  2. Хуки жизненного цикла: сохранить все хуки, сначала выполнить примеси, а затем выполнить текущий компонент.
  3. 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, что переводится как то, что мы часто называем рендерингом на стороне сервера.

Кратко о причинах существования ССР

  1. SPA-фреймворк SEO-решения
  2. Улучшить скорость загрузки первого экрана

Но у него все еще есть следующие проблемы

  • Некоторые крючки жизненного цикла не могут быть использованы (ранее упомянутые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

  1. Установитьprerender-spa-plugin
yarn prerender-spa-plugin
  1. Измените конфигурацию веб-пакета, выполнить настройку относительно просто.
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 дней заземления. Надеюсь в будущем уделять больше внимания!