Узнайте, как использовать Vue для создания пользовательских элементов, которые легко добавить в файлы Markdown вашего статического сайта.
вступление
Недавно я переделал Table to Markdown, преобразовав его из проекта Nuxt в статический сайт, созданный с помощью Blurry, предварительной версии генератора статических сайтов (SSG), над которым я работал. Я хотел простоты и производительности статического сайта, но мне все еще нужна была интерактивность.
Хотя я использую Blurry для создания статических сайтов, это руководство подойдет для любого генератора статических сайтов, например Hugo или Jekyll.
«Какая простота и производительность?» ты спрашиваешь? Что ж, одна проблема, с которой я столкнулся при работе с гибридной версией Table to Markdown от Nuxt.js, заключалась в том, что было трудно точно подсчитать просмотры страниц, поскольку иногда они отслеживались в коде на стороне сервера, а иногда — в коде на стороне клиента. — и мне не хотелось считать их дважды. У меня были те же проблемы с показами рекламы, и случайный подсчет их более одного раза мог привести к проблемам с любыми рекламными сетями, которые я использовал.
Со статическим сайтом эти просмотры страниц и показы рекламы не требовали никаких размышлений, потому что они срабатывали при загрузке HTML, вот и все.
Использование Vue для всего сайта привело к тому, что для вещей, для которых мне действительно не нужен был JavaScript, например для навигации по сайту, потребовалось довольно много JavaScript. Использование статического сайта означало, что я мог полагаться на обычную навигацию по гиперссылкам, не требуя ни одной строки JS, что означало более быструю загрузку страниц.
Но была одна загвоздка: мне по-прежнему нужна была интерактивность, которую я получил от Vue, поэтому я не мог заменить весь код Vue на статический сайт.
Веб-компоненты с Vue
Чтобы упростить интеграцию Vue с моим статическим сайтом, а не использовать Vue для управления всей страницей, я решил использовать Vue в одном пользовательском HTML-элементе через веб-компоненты.
Чтобы получить представление о том, к чему мы стремимся, вот фрагмент файла Markdown из таблицы в Markdown:
# Convert spreadsheet cells to Markdown <div class="custom-element-container"> <table-converter></table-converter> </div> Table to Markdown makes it easy to convert cells from Microsoft Excel, [...]<div class="custom-element-container"> <table-converter></table-converter> </div> Table to Markdown makes it easy to convert cells from Microsoft Excel, [...]
Веб-компоненты позволяют создавать собственные автономные HTML-элементы, которые могут использовать JavaScript, чтобы делать все, что вы хотите. Большим преимуществом является то, что после включения JS, в котором определены веб-компоненты, вы можете использовать их так же, как обычный HTML-элемент, например <p>
или <a>
.
Звучит хорошо, а? Почти слишком хорошо? Ну, с этим подходом есть некоторые недостатки, но мы не можем их сгладить.
Морщины
Изменение макета после загрузки веб-компонента
Если вы следите за этим блогом, вы наверняка заметили, что у меня есть интерес к показателям PageSpeed.
При использовании веб-компонентов следует помнить, что их высота не учитывается при рендеринге страницы.
Сопоставляя высоту ваших веб-компонентов и высоту оболочки веб-компонента, вы можете избежать сдвигов макета контента, которые мешают вашим посетителям:
/* Main stylesheet */ .custom-element-container { min-height: 300px; }
Вы можете использовать адаптивную высоту в контейнере настраиваемых элементов, чтобы ваш контент соответствовал размерам экрана посетителей.
Область действия CSS
Чтобы обеспечить единообразие стилей статического сайта и веб-компонентов, вы можете использовать один и тот же файл CSS в обоих местах. Просто импортируйте свой файл CSS в свой компонент Vue:
<style> @import('main.css') </style>
Сохраняйте этот CSS-файл как можно меньшего размера, поскольку его содержимое может быть загружено дважды. Включите только необходимые стили, а для повышения скорости страницы рассмотрите возможность встраивания этого CSS-файла в базовый файл шаблона вашего статического сайта.
Дочерний компонент CSS
Если ваш однофайловый компонент Vue использует другие компоненты Vue, не являющиеся пользовательскими элементами, с тегами <style>
, вы можете быть удивлены, увидев, что эти стили исчезают при использовании вашего пользовательского элемента.
Для некоторых обходных путей:
@import()
соответствующий CSS в ваших дочерних компонентах- Вместо определения области действия CSS (
<style scoped>
) в компоненте верхнего уровня определите правила CSS, которые также будут применяться к дочерним компонентам. - Создавайте классы, элементы или используйте пользовательские свойства (переменные) CSS во встроенных атрибутах
style=""
/:style="{}"
элементов в ваших дочерних компонентах.
Выполнение
Теперь, когда мы определили некоторые недостатки и способы их устранения, пришло время посмотреть, как преобразовать файл Vue в пользовательский элемент.
Конфигурация Vite
Во-первых, обновите плагин Vue для Vite, чтобы создавать веб-компоненты, и настройте Vite для размещения ваших встроенных компонентов там, где вы хотите:
import { fileURLToPath, URL } from 'node:url' import { resolve } from 'path' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ // Get Vue to output custom elements plugins: [vue({ customElement: true })], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } }, build: { // Specify a directory in your SSG's build directory outDir: 'dist/elements', rollupOptions: { // Improvement: loop through files in the elements directory to build this object input: { 'your-component': resolve(__dirname, 'src/elements/your-component.ts'), }, // Use predictable file names output: { entryFileNames(chunkInfo) { return `${chunkInfo.name}.js` }, }, } } })
Дополнительную информацию об использовании Vue для создания веб-компонентов см. в Документации по Vue.
Файл пользовательского элемента
В отдельном файле определите свой компонент Vue как пользовательский элемент, который сделает ваш компонент доступным для использования в HTML DOM:
// src/elements/your-component.ts import { defineCustomElement } from 'vue' import YourComponent from '@/components/YourComponent.vue' customElements.define('your-component', defineCustomElement(YourComponent))
Создание отдельного файла для каждого веб-компонента может помочь уменьшить размер пакетов JavaScript за счет включения только необходимого кода для этого компонента.
Вы также можете определить множество пользовательских элементов в одном файле. Дополнительную информацию и рекомендации по созданию библиотеки пользовательских элементов см. в документах Vue.
Включите JS и пользовательский элемент в свои файлы SSG.
Теперь все, что осталось сделать, это включить файл вашего пользовательского элемента .js
в соответствующий файл шаблона вашего SSG:
<script src="/elements/your-component.js" type="module"></script> <your-component></your-component>
Заворачивать
Это обертка.
Эта статья завершена как однофайловый компонент Vue в пользовательском элементе веб-компонента после выполнения вышеуказанных шагов.