Краткое изложение разработки проекта веб-приложения, имитирующего туристическую станцию, с помощью Vue (часть 1)

внешний интерфейс JavaScript Vue.js CSS

Когда я пишу, я нахожу, что напишу много контента... Я чувствую, что это слишком много для чтения в одной статье, поэтому я разделю ее на две части...

Следующая статья закончена, заинтересованные друзья могут продолжать обращать внимание~ =>Краткое изложение разработки проекта веб-приложения, имитирующего туристическую станцию, с помощью Vue (ниже)

Советы

Эта статья — просто работа/идея, которую, я думаю, можно обобщить после завершения проекта.Друзья, которые контактировали с Vue, вскоре должны что-то получить. Этот проект также является вторым проектом Vue, созданным Mengxin. В нем используется инструмент создания лесов (vue-cli 2.x, а не 3). Если у вас есть время, чтобы прочитать его, если у вас есть время, пожалуйста, дайте больше рекомендаций! ~

Предварительный просмотр результатов

Реализуйте только страницу/логику домашней страницы проекта, страницы сведений о проекте и страницы со списком городов.

не бей меня

Инициализация проекта

Сначала используйте строительные леса для создания структуры проекта.

Поскольку мы делаем мобильную веб-страницу, у нас могут быть некоторые конфигурации:

Первый шаг — настроить метатег

Добавьте один в index.htmlmetaЭтикетка:

<meta name="viewport"content="width=device-width,initial-scale=1.0,
    minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">

В интернете<head>Добавление приведенного выше кода в тег может автоматически адаптировать ширину веб-страницы к ширине экрана мобильного телефона.

в:

width=device-width : указывает, что ширина равна ширине экрана устройства.

initial-scale=1.0 : указывает начальный масштаб

Minimum-scale=1.0 : указывает минимальный коэффициент масштабирования.

max-scale=1.0 : указывает максимальный коэффициент масштабирования.

user-scalable=no : указывает, может ли пользователь регулировать коэффициент масштабирования.

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

Второй шаг — инициализировать стиль по умолчанию.

В разных мобильных браузерах некоторые стили по умолчанию различаются и унифицируются. Нам нужно унифицировать стили инициализации этих разных мобильных телефонов.

Таким образом, вы можете ввестиreset.css

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

Если вы хотите увидеть/получить код, вы можете прийти ко мнеGithubВозьмите это: src/assets/styles/reset.css

Третий шаг - решить схему границы в 1 пиксель.

При разработке мобильных страниц частограница 1 пиксельЭта проблема.

Другими словами, некоторые мобильные телефоны имеют высокое разрешение экрана.Если мы напишем стиль границы снизу на странице, это приведет к тому, что граница 1px будет отображаться как граница 2px или граница 3px будет отображаться как несколько пикселей среди экраны мобильных телефонов с высоким разрешением.

Чтобы решить эту проблему с границей в 1 пиксель, мы ввелиborder.css(Похоже, какая команда придумала решение? Забыл его, просто знаю, как его использовать... но все равно спасибо. Есть и другие решения, это поищите сами.)

Не выложено более 200 строк, если хотите посмотреть/получить полный код, можете прийти ко мнеGithubВверху: src/assets/styles/border.css

Конкретное использование этого решения, товарищи, читавшие код border.css, обнаружат, что оно очень простое: добавить к элементам следующие имена классов в соответствии с желаемыми требованиями.

Просто воспринимайте это буквально.

Например, чтобы добавить к элементу нижнюю границу в один пиксель, добавьте имя класса напрямую:<div class="border-bottom>"Вот и все.

Чтобы добавить верхнюю и нижнюю границы в один пиксель к элементу, просто добавьте имя класса:<div class="border-topbottom">Вот и все.

Цвет бордюра тоже можно изменить, для примера в проекте меняем цвет по этому формату (если в примере в этой статье есть css код, то он в основном написан стилусом):

Соответствующая страница:

Четвертый шаг — представить библиотеку fastclick.

В мобильной разработке на некоторых моделях и некоторых браузерах событие клика выполняется с задержкой в ​​300 мс.

Для решения этой проблемы мы вводим библиотеку fastclick

npm install fastclick --save

--save означает: независимо от того, тестируете ли вы в среде разработки или запускаете код онлайн, можно использовать установленные библиотеки. И после загрузки он автоматически сохраняется в свойстве зависимостей package.json, например, быстрый щелчок установки здесь:

Затем введите и используйте его в функции входа main.js:

import fastClick from 'fastclick',fastClick.attach(document.body)

Пятый шаг — настроить использование iconfont

доБиблиотека векторных иконок AlibabaСоздать проект

Затем купите его на iconfont, добавьте в корзину, добавьте в свой проект после выбора, а затем загрузите локально.

Просто используйте эти несколько вещей в загрузке:

Затем поместите iconfont.css в папку и импортируйте его в функцию входа main.js и используйте его глобально.

Как пример использования:

Обратите внимание, что iconfont должен быть добавлен к имени класса, а затем код, введенный в этот диапазон, является кодом выбранного вами значка:

Шаг 6 Настройте каталог

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

Настроено в webpack.base.conf.js в папке сборки, как показано на рисунке ниже, обведенные — это то, что я настроил в проекте.

После этой конфигурации вы можете использовать пользовательский каталог. Например, согласно моей конфигурации выше

import src/assets/styles/border.css

можно записать как

import styles/border.css.

Что я хочу записать в разработке главной страницы

плагин карусели

установка и использование

Вот vue-awesome-swiper.

Сначала установите: npm install vue-awesome-swiper --save
Тогда некоторые варианты использования можно найти в его документации:

Поскольку функцию карусели можно использовать на каждой странице, она вводится непосредственно в глобальный, то есть в файл входа main.js.

Затем используйте:

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

Здесь стоит упомянуть: если что-то под каруселью

Такой, как этот тест. Когда скорость сети медленно загружается, тест может сначала отображаться вверху, а затем возвращаться вниз, когда изображение растягивается.

Чтобы предотвратить это дрожание, лучше всего сделать это следующим образом:

Поместите слой оболочки класса div вне карусели, а затем задайте для div фиксированный размер. Например, в проекте соотношение сторон изображения-карусели здесь 364:97, что примерно 3,75, а высота составляет 26,6% от ширины.

Таким образом, отзывчивая разработка может стилизовать блок div следующим образом:

Теперь совместимость блоков vw на самом деле в порядке.

Существует очень совместимое решение:

overflow: hidden
width: 100%
height: 0
padding-bottom: 26.6%

Таким образом, высота также составляет 26,6% от ширины.

Фактически. . Этот компонент vue-aowsome-swiper до сих пор не имеет такой проблемы с джиттером. .

Также есть проблема с изменением цвета плагина по умолчанию.

Например, после настройки области кнопки плагина цвет кнопки по умолчанию — маленькая синяя точка.

Изучение элементов показывает, что:

Итак, мы добавляем стили, подобные этому, чтобы изменить строку?

Обычно не принято спрашивать...

Из-за ограниченной области действия свойства этого класса задаются для исходного компонента swiper, а не для компонента swiper, который мы установили здесь.

Он должен быть установлен следующим образом:

Это означает, что во всех классах .wrapper ищите класс .swiper-pagination-bullet-active.

>>>Оно имеет значение проникновения в рамки, проникновения в рамки других компонентов.

Если текст состоит из более чем одной строки, реализуйте эффект многоточия.

Например, вот тег p.

Если в теге P слишком много данных, я хочу отобразить ... многоточие.

Свойство text-overflow можно использовать следующим образом:

Для достижения эффекта генерации эллипсов при переполнении следует определить два стиля: принудительное отображение текста в одну строку (white-space:nowrap) и скрытие переливающегося содержимого (overflow:hidden). переполняющий текст будет отображаться как эффект многоточия.

отправить ajax-запрос

Как правило, данные ajax-запроса отправляются в смонтированном хуке. Хотите узнать больше о жизненном цикле => Я написалстатья

Метод запроса зависит от вас, в этом проекте я написал методы axios и fetch.

настроить

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

Мы помещаем некоторые локальные данные моделирования в этот статический каталог и создаем папку для хранения данных самостоятельно. В этом проекте static/mock/index.json:

Эти данные являются локальными данными симуляции, мы не хотим одновременно передавать их в строку, их можно настроить в .gitignore следующим образом:

Теперь все, что находится в этой папке, не будет загружаться онлайн.

Конечно, он не будет отправлен в локальный репозиторий git.

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

Когда мы запускаем этот код, URL-адресу, который мы запрашиваем, желательно предшествовать «api», как показано в красном поле ниже: /api/index.json Это лучший способ.

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

В файле конфигурации есть скрипт index.js, который официально предоставляет нам элемент конфигурации proxyTable{}, мы можем настроить его следующим образом:

Это означает: когда мы запрашиваем API, он по-прежнему сопоставляется с локальным портом 8080, а затем, когда мы обращаемся к любому URL-адресу, начинающемуся с API, мы делаем замену пути, и прокси-сервер обращается к /static/mock.

На самом деле эту функцию предоставляет webpack-dev-sever.

После изменения конфигурационного файла необходимо перезапустить сервер, после перезагрузки запросить данные можно следующим образом:

На самом деле здесь осуществляется доступ к содержимому в static/mock/index.json.

оптимизация

По возможности, желательно локальнокорневой компонентЗапросите данные ajax один раз, а затем отправьте полученные данные из локального корневого компонента.перешел ккаждый местныйПодсборка, вместо отправки запроса ajax для каждого частичного дочернего компонента.

Что я хочу записать в развитие страницы со списком городов

Помните сценарий применения box-sizing: border-box

Вот такой css написан

Теперь при вводе текстовых символов поле ввода превышает размер поля ввода:

Эти двое будут держаться вместе, не так красиво. Если вы хотите добавить отступ к этому полю ввода, было бы лучше оставить небольшой зазор.

Но добавить строку непосредственно под вводом?

страница:

Поскольку div, оборачивающий поле ввода, не устанавливает ширину, то есть ширина устанавливается автоматически. Ширина поля ввода установлена ​​на 100%.

Если вы напрямую добавите отступ к вводу, он растянет ширину поля ввода. Так что переполнится.

Итак, как решить эту проблему?

Мы просто хотим установить левое и правое значение заполнения и не хотим изменять длину и ширину поля ввода. Итак, давайте добавим один под Input:box-sizing: border-box

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

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

Использовать сторонний плагин лучше - листайте в строке списка

Когда страница изначально разработана, на этом этапе, поскольку добавляется область, соответствующая большему количеству букв, когда на странице появляется полоса прокрутки:

Чтобы использовать библиотеку улучшенной прокрутки, нам нужно только позволить области списка отображаться в области, которая может отображаться при только что входе на страницу, и нет необходимости в полосах прокрутки. Таким образом, вы можете добавить поле div.list в самое внешнее поле, которое обертывает всю область списка.overflow: hiddenВот и все. (Вся страница списка относится к текущему городу от начала до конца на рисунке ниже, а поля выбора города и поля ввода написаны другими подкомпонентами)

Далее конкретное использование better-scroll описано в его документации на github, и каждый может обратиться к нему в зависимости от конкретной ситуации.

Логическая реализация идеи алфавита

В событии клика, когда нам нужно просмотреть нажатый контент, мы можем использовать событие кликаобъект события

В событии щелчка Vue, когда методы определяют метод щелчка, этот метод может получить параметр e, а e — это объект события, на который мы нажали.

Чтобы получить содержимое объекта события, на который мы нажали, мы можем сделать это:e.target.innerText

Возьмите пример в проекте для проверки:

Например, нажмите D F J на ​​странице в это время.

Требование 1

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

У стороннего плагина better-scroll есть способ выполнить это требование.Идея такова:

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

Это сделает область прокрутки лучшей прокрутки автоматической прокруткой к элементу. Этому методу нужно передать DOM элемента, который мы прокрутили до элемента.

Используя эту идею, требование 1 может быть достигнуто.

Требование 2

Перетащите алфавит пальцем, последует список, соответствующий буквесвязьэкспонат.

Идеи:

Используйте события touchstart, touchmove, touchend и дайте ограничение (touchStatus) для выполнения некоторых операций только при движении пальца по экрану. Затем используйте массив букв для хранения всех букв алфавита, где буквы, вероятно, ['A','B','C'...], и пусть страница v-для этой буквы отобразит соответствующий содержание. Причина хранения этих букв в массиве также заключается в достижении основной идеи этого требования:Найдите соответствующую букву по нижнему индексу.

Затем используйте offsetTop, чтобы найти высоту буквы A в алфавите от вершины, которая ее оборачивает. Красное поле внизу.

74 здесь представляет собой высоту красного прямоугольника.

Затем получите высоту пальца при движении, эта высота и есть высота клиента, используйте clientY. Событие touchmove имеет объект события, в объекте события есть массив касаний, а touches[0] содержит информацию о текущем пальце, включая свойство clientY.

Получить положение нашего пальца в режиме реального времени.

Мы хотим получить высоту из блока обертки =>, то есть высоту clientY за вычетом высоты области заголовков и области поиска, высота этих двух областей равна 79px.

Затем вычислить нижний индекс буквы, на которую переместился палец в массиве по логике (touchY - startY)/высота каждой буквы, а затем округлить результат в меньшую сторону.

Наконец, передайте букву, соответствующую индексу в массиве letter, компоненту, где находится требование 1, чтобы использовать идею требования 1. (Передача значения здесь включает передачу значения между одноуровневыми компонентами. В настоящее время страница относительно проста, и не рекомендуется использовать vuex. Вы можете использовать шину событий/найти тот же родительский компонент в качестве среды для передачи значения. конкретный метод — Baidu.)

Окончательный код логики в моем проекте написан так:

Наконец, рекомендуется использовать оператор if, чтобы обеспечить значение index.

оптимизация производительности

первое место

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

Итак, здесь необходимо оптимизировать, например:

Инициализировать startY значением 0 в данных

Затем используйте обновленный хук жизненного цикла, чтобы выполнить оператор, назначенный startY.

Зачем использовать обновленный хук здесь? Когда компонент алфавитаalpha.vue впервые визуализируется в проекте, значение, переданное из его родительского компонента City.vue, является пустым объектом. Когда ajax в City.vue динамически получает данные, значение, переданное из City в алфавит, изменяет данные из исходного пустого объекта. После обновления данных срабатывает обновленный хук.В это время значение, присвоенное startY, — это все значения, и оно будет назначено только один раз.

Второе место: функция дросселирования

Уменьшите частоту выполнения handleTouchMove() за счет регулирования функции (поскольку эта функция выполняется очень часто, когда наш палец скользит).

Как сделать функцию дросселя?

пройти черезтаймера такжеочистить таймерреализовать.

Сначала инициализируйте таймер для нулевых данных, а затем используйте его следующим образом.

Таким образом, если для регулирования функции используется таймер:

Если он уже делает это, я позволю ему задержать 16 мс перед его выполнением. Предположим, вы выполняете еще одну прокрутку пальцем в течение этих 16 мс, затем он очистит последнюю операцию, которую вы хотите выполнить (clearTimeout), а затем повторно выполните то, что вы хотите сделать на этот раз (эквивалентно скольжению с последним местоположением пальца). ).

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

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

localStorage

Может быть небольшая вероятность того, что пользователь отключит функцию локального автоматического хранения.Как правило, когда мы используем localStorage, мы должны использовать блок кода try catch, чтобы даже если пользователь выключил функцию локального автоматического хранения, вся код не сможет работать, просто без этой функции localStorage.

Возьмем пример из проекта:

Последняя часть закончена, продолжение следует...