С бурным развитием интернета все больше и больше традиционных сервисов переходят в онлайн, торговцам срочно нужен официальный сайт для представления своих товаров и повышения их популярности. Поэтому «создание веб-сайта» стало жесткой потребностью. В этой статье представлены решения о том, как реализовать веб-приложение с помощью Vue.js.
Как фронтенд-инженер, я считаю, что все написали много сайтов и приложений, я просто делю сайты на «презентационные» и «операционные». Типом производительности может быть веб-сайт с представлением продукта, а типичным представителем типа операции является управленческий фон. Не так давно у меня была возможность участвовать в проектировании и разработке проекта по созданию веб-сайта.Он относится к веб-сайтам рабочего типа, но требует более глубокого уровня абстракции.Это «сайт для создания веб-сайтов». В этой статье делается попытка спроектировать и реализовать такое приложение на основе платформы Vue.js.Пользователи могут создавать веб-сайты, перетаскивая модули. Я надеюсь, что, представляя эту статью, я смогу показать вам другую точку зрения.
нужно
Получение требований — первый шаг в запуске проекта. Вообще говоря, большинство конструкторов сайтов предоставляют следующие функции:
- предоставить шаблоны
- цвет темы
- Богатые функциональные модули, такие как картинки, карусели, фотоальбомы и т.д.
- Модули можно перетаскивать и настраивать по мере необходимости
- Веб-сайты, поддерживающие создание нескольких страниц
- Страница может быть разделена на столбцы и разделы с некоторыми изменениями макета.
- Сайт поддерживает портативные устройства
анализ спроса
Прежде чем мы начнем, мы можем сначала проанализировать требования.
Из требований можно извлечь несколько ключевых слов: «шаблон», «цвет темы», «модуль», «страница», «колонка». Уточнение значения этих ключевых слов поможет нам в следующем дизайне.
-
Страницы: веб-сайт состоит из одной или нескольких страниц (страниц).
-
Столбцы/разделы: страница состоит из различных функциональных областей, таких как представление компании, истории успеха, контакты и т. д. Они могут располагаться вертикально, а могут располагаться колонками слева и справа, возьмем более подходящее название «раздел».
-
Модуль: каждый блок содержит один или несколько компонентов, которые объединяются для достижения одной и той же цели. Например, в разделе «Введение в компанию» вы можете использовать текстовый модуль, чтобы представить общую ситуацию в компании, и использовать карусельный модуль, чтобы отобразить основные продукты компании. Упомянутый здесь модуль равен знакомому «компоненту» (Component), который является наименьшей функциональной единицей, которую мы хотим реализовать.
-
Шаблоны: Шаблоны могут иметь множество определений. Здесь мы можем понимать это как макет страницы, аналогичный макету столбца, который может выбрать пространство QQ. Шаблоны определяют блоки, которые содержит страница.количествои каждый блокГоризонтальное соотношение.
-
Цвет темы: у каждого сайта должен быть свой стиль. Это можно просто считать: стиль = шаблон + цвет темы, разные шаблоны и разные цвета темы формируют разные стили веб-сайтов.
Представление данных веб-сайта
Итак, вопрос в том, как мы должны хранить наш веб-сайт? Другими словами, какая структура данных существует в базе данных? Это негабаритная строка, содержащая HTML? Не волнуйтесь, основываясь на приведенных выше определениях ключевых слов, мы можем резюмировать:
- Сайт содержит несколько страниц, страница содержит несколько блоков, а блок содержит несколько модулей. Видно, что это древовидная структура, см. рисунок ниже.
В формате JSON это можно представить как:
{
"id": 1,
"name": "xxx公司"
"type": "site",
"children": [{
"type": "page",
"name": "首页",
"children": [{
"type": "section",
"name": "公司简介",
"children": [{
"type": "paragraph"
}, {
"type": "carousel"
}]
}]
}]
}
-
Тогда модуль является листовым узлом в дереве.Требование требует, чтобы модуль можно было настроить.Мы можем разделить конфигурацию на две части: контент (content) и настройку (config). Например, контент в модуле карусели хранит URL-адреса нескольких картинок, а в конфиге может быть анимационный эффект переключения карусели, включать ли автоматическое воспроизведение и т. д.
-
Как и модули, сайт, страница и раздел являются узлами в дереве, и контент и конфигурация могут быть добавлены к узлам по мере необходимости. Просто для этих типов узлов контент фактически дочерний, только атрибут config.
-
Цвет темы — это элемент конфигурации узла веб-сайта, который можно найти в
site.configувеличить вthemeColorсвойства для представления. -
Как поддерживать портативные устройства? Как упоминалось ранее, шаблон определяет горизонтальную пропорцию пластины, поэтому горизонтальную пропорцию пластины разных размеров можно настроить в свойстве конфигурации пластины. Если вы используете 12-колоночную сетку Bootstrap, вы можете легко достичь цели, установив класс. Например, в конфиге раздела
class="col-xs-12 col-sm-6 col-md-3"Это означает, что под мобильным телефоном планшет находится на 100% горизонтально, под планшетом — 50%, а под ПК — 25%.
Подводя итог, веб-сайт можно полностью представить в виде дерева JSON. Это дерево содержит содержимое и конфигурацию всех страниц, разделов и модулей.
От данных к сайту
У нас уже есть представление данных веб-сайта, поэтому следующий вопрос — как отобразить веб-сайт из данных и представить его пользователю? На самом деле нам просто нужно найти способ отобразить это дерево JSON.
Два шага:
- Напишите код для каждого узла, каждый узел принимает
nodeсвойства иthemeColor - Пройдите по дереву JSON и отобразите соответствующий узел в соответствующей позиции (то есть отношение включения между родительским и дочерним узлами).
Первый шаг — «физическая работа».Вот пример текстового модуля из одного абзаца:
<!-- Paragraph.vue -->
<template>
<div>
<h1 :style="{color: themeColor}">{{node.content.title}}</h1>
<small v-if="node.config.showSubTitle">{{node.content.subTitle}}</small>
<p>{{node.content.detail}}</p>
</div>
</template>
<script>
export default {
name: 'paragraph',
props: ['node', 'themeColor']
}
</script>
После написания всего кода узла на втором этапе нам нужно написать компонент, похожий на «рендерер», для рекурсивного рендеринга дерева JSON. Основная идея состоит в том, что компонент сначала визуализирует себя, затем визуализирует своих потомков, и каждый потомок повторяет этот процесс визуализации, таким образом визуализируя все дерево.
Здесь он должен быть основан на узлеtypeСвойство также является строкой для получения соответствующего определения компонента. К счастью, такие динамические компоненты уже существуют во Vue.js.Component, этот компонентisСвойство принимает строку. Исходя из этого, наш компонент рендеринга можно записать так:
<!-- render.vue -->
<tempplate>
<component :is="node.type" :node="node" :theme="themeColor">
<render v-for="child in node.children" :key="child.id" :node="child" :theme="themeColor" />
</component>
</tempplate>
<script>
// 导入JSON 树中所涉及的所有节点
import Page from './Page.vue'
import Section from './Section.vue'
import Paragraph from './Paragraph.vue'
export default {
name: 'render',
props: ['node', 'themeColor'],
components: {
Page,
Section,
Paragraph
}
}
</script>
Примечание. Если Vue.js не предоставляет динамические компоненты компонентов, мы также можем использовать Vue.js вcreateElementМетод реализует сам компонент, как подробно описано в этой сути (gist.GitHub.com/GitHub-случай пациента…).
На данный момент мы разработали представление данных веб-сайта и рендеринг данных на страницу. Так откуда взялось это дерево JSON?
Изменить и сохранить
Чтобы создать веб-сайт, пользователь будет выполнять такие операции, как выбор станции-шаблона, настройка цветового тона, перетаскивание модулей, редактирование содержимого и конфигурации модуля и сохранение в фоновом режиме. Стоит отметить, что выбранный пользователем сайт-шаблон здесь несколько отличается от определения шаблона в начале статьи. Если шаблон является скелетом веб-сайта, то станция платы представляет собой шаблон, заполненный исходными данными (цвета по умолчанию, модули, включенные в доску, и содержимое по умолчанию для модулей).
С точки зрения данных становится яснее, как шаги постепенно генерируют это дерево.
| работа интерфейса | Данные о воздействии |
|---|---|
| Выберите шаблон (Sample Station) | Начальное дерево, определенное этим шаблоном, содержащее оттенки и модули по умолчанию. |
| Выберите оттенок | возобновитьsite.config.themeColor
|
| Перетащите модули в область | в соответствующемsection.childrenпоместите узел компонента в массив |
| Сортировка модулей по регионам | в соответствующемsection.childrenсбросить индекс узла компонента в массиве |
| Редактировать содержимое и конфигурацию модуля | Обновите атрибуты в содержании и конфигурации соответствующего модуля |
| сохранить сайт | Сохраните дерево JSON в базе данных для сохранения |
Теперь, когда мы выбрали Vue.js, мы можем выбрать официально рекомендуемый Vuex (vuex.vuejs.org/en/) для управления государством.
Сначала создайте экземпляр Vuex, который содержит объект сайта и некоторые операции на узле:
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
site: {}
},
mutations: {
changeThemeColor () {},
addModule () {},
sortModule () {},
removeModule () {},
updateModule () {}
},
actions: {
getSite () {},
saveSite () {}
}
})
Теоретически с помощью этих методов мы уже можемпрограммаДерево было обновлено, но в качестве фона редактирования нам также необходимо предоставить некоторые элементы интерфейса, чтобы пользователи могли редактировать дерево.
То есть нам нужноВизуализация редактируемого веб-сайта в фоновом режиме редактирования и визуализация веб-сайта только для чтения после запуска веб-сайта., т. е. одно и то же дерево JSON необходимо отрисовывать дважды. Поскольку рендерер визуализирует соответствующий компонент в соответствии с типом узла, для фона редактирования нам нужно взять другой тип для каждого узла, например, равномерно добавить префикс.edit-. Например, компонент редактирования компонента Paragraph можно записать следующим образом:
<!-- EditParagraph.vue -->
<template>
<edit-wrapper>
<paragraph :node="node" :themeColor="themeColor" />
</edit-wrapper>
</template>
<script>
// EditWrapper提供统一的编辑入口,内部仍需要渲染一次 Paragraph 便于实时预览编辑结果
import EditWrapper from './EditWrapper.vue'
import Paragraph from './Paragraph.vue'
import { mapMutations } from 'vuex'
export default {
name: 'edit-paragraph',
props: ['node', 'themeColor'],
methods: { ...mapMutations(['updateModule']) }
}
</script>
Пользователи могут редактировать модуль «Абзац» через запись интерфейса этого компонента (здесь опущена).edit-wrapperНа самом деле редактирование компонентов может осуществляться через всплывающие окна и формы, а может быть удобнее встроенное редактирование).
Таким образом, каждый модуль имеет соответствующий модуль редактирования, и при двойном рендеринге происходит процесс преобразования. Предполагая, что дерево, доступное только для чтения, хранится в базе данных, когда дерево получено в фоновом режиме редактирования, его необходимо преобразовать в редактируемое дерево для отображения веб-сайта с записью редактирования, а при сохранении его необходимо преобразовать. в доступное только для чтения дерево для сохранения. Процесс преобразования на самом деле очень прост, просто добавьте или удалите префикс атрибута типа каждого узла.
Функция перетаскивания
Мы используем перетаскивание, чтобы добавлять модули в область и сортировать модули. Существует множество библиотек с открытым исходным кодом, которые помогают нам реализовать перетаскивание и даже упаковку Vue.js. рекомендуется здесьVue.Draggable(GitHub.com/sortableJS/…) Эта библиотека представляет собой слой инкапсуляции на основе Sortable.js. Его типичные сценарии применения следующие:
<draggable v-model="myArray" :options="{group:'people'}" @start="drag=true" @end="drag=false">
<div v-for="element in myArray">{{element.name}}</div>
</draggable>
В нашем сценарии как раз вdraggableслушать на компонентеaddа такжеsortСобытие может вызвать соответствующий метод в хранилище.
Как описано в таблице в этом разделе, перетаскивание — это только метод операции в интерфейсе, который, по сути, представляет собой операцию добавления и корректировки индекса элементов в массиве.
обнаружение изменений
Чтобы вовремя сохранять изменения пользователя, мы можем автоматически сохранять, когда пользователь изменяет цвет темы, редактирует модули, удаляет модули и т. д. По сути, вам нужно обнаруживать изменения состояния сайта в магазине. Плагины в Vuex могут выполнять некоторые операции, такие как ведение журнала и сохранение изменений.Для этого мы можем написать плагин автосохранения.
// store.js
const autoSave = (store) => {
store.watch(
state => state.site,
(newV, oldV) => {
store.dispatch('saveSite')
},
{ deep: true }
)
}
const store = new Vuex.Store({
state: {
site: {}
},
plugins: [autoSave]
})
До сих пор мы использовали Vue.js и связанные с ним технологии для выполнения требований веб-приложения, перечисленных в начале статьи.
Эпилог
В этой статье представлены проблемы и общие идеи, с которыми можно столкнуться при написании веб-приложения с помощью Vue.js из анализа требований, разработки решения и реализации кода. Видно, что статья посвящена данным, включая дизайн формата данных, манипулирование данными и обнаружение изменений данных. Это связано с тем, что платформа Vue.js помогает нам выполнять рендеринг данных в интерфейс и обновлять интерфейс после изменения данных.Что нам нужно сделать, так это управлять данными. Фреймворк Vue.js разделяет нашу работу, повышает эффективность разработки и позволяет нам сосредоточиться на разработке бизнес-логики, что также является отражением ценности фреймворка.
Примечания
- демонстрационный адрес:GitHub.com/GitHub — случай пациента…
автор:Тан Хеджун
Введение: Front-end инженер People.com.cn.Эта статья является лишь личной точкой зрения автора и не отражает позицию People's Network.
Эта статья была впервые опубликована в общедоступной учетной записи WeChat «Технической группы People's Network», отсканируйте код и немедленно подпишитесь: