Всем привет, я Шэнь Юань.
В прошлый раз, когда я опубликовал статью о рендеринге на стороне сервера, я получил много лайков и комментариев от больших парней, чему я очень рад. Через некоторое время кто-то спросил меня, почему я вдруг исчез из Наггетс. На самом деле, нет. Сообщество до сих пор обращает на это внимание. Но, что более важно, за этот период времени он исчез из поля зрения всех. чтобы начать накапливать некоторые технические данные, я рассмотрел и интегрировал некоторые технологические стеки, которые я изучил ранее, и некоторые мысли о разработке внешнего интерфейса Итак, я начал с идеи, которая у меня была давно, давайте сделаем музыкальное веб-приложение. Хотя таких веб-приложений было много, на самом деле, большинство версий Vue, даже если есть похожие проекты с React, прекратили поддержку, функция хуков не была обновлена вовремя, и весь метод разработки не то, что мне нравится. . Но будьте уверены, запуск такого проекта с открытым исходным кодом - это точно не шаблон для существующего проекта, я буду поддерживать его в течение длительного времени, и если вы можете прочитать эту статью или прочитать исходный код, вы можете увидеть совершенно другую разработку. идеи и методы разработки, узнал много сложного.
Ну а теперь официально представить этот проект.
(В настоящее время есть некоторые проблемы со стилем при открытии Nuggets, пожалуйста, сначала откройте его в браузере, спасибо за понимание)
Браузер хром на мобиле и ПК лучше есть :)
Исходный код прикреплен в конце, пожалуйста, проверьте его.
Введение в стек технологий
Передняя концевая часть:
-
react v16.8
Family Bucket (реагировать, реагировать-маршрутизатор): инфраструктура MVVM для создания пользовательских интерфейсов. -
redux
: знаменитый контейнер управления состоянием JavaScript. -
redux-thunk
: промежуточное ПО Redux, которое обрабатывает асинхронную логику. -
immutable
: библиотека для обработки персистентных структур данных, разработанная Facebook в течение трех лет. (Это артефакт в сочетании с memo и Redux. Компонент функции переноса memo имеет тот же эффект, что и PureComponent. Перед обновлением компонента выполняется неглубокое сравнение данных. Подробности см. в этой статье.Когда PureComponent встречает ImmutableJS) -
react-lazyload
: реагировать на ленивую загрузку библиотеки -
better-scroll
: известная библиотека для улучшения мобильного скольжения. -
styled-components
: Обрабатывать стили и отражать технические артефакты интерфейса css в js (подробности см. в моей предыдущей статье).styled-components: новая идея разделения внешних компонентов) -
axios
: данные, используемые для запроса внутреннего API
Бэкэнд часть:
- Внедрите API-интерфейс версии NetEase Cloud Music NodeJS, которая хорошо известна женщинам и детям на github.NeteaseCloudMusicApi, который предоставляет музыкальные данные.
разное:
- create-react-app: React scaffolding, быстрая сборка проектов
- eslint: известный инструмент проверки стиля кода
- iconfont: Библиотека иконок Alibaba
- fastclick: решить проблему задержки мобильного клика в 300 мс
2. Спецификации проекта
Прежде чем представить функцию проекта, мне необходимо подчеркнуть особенности разработки этого проекта и мой личный стиль кодирования.Сообщите мне заранее, что у меня есть на это свои причины, чтобы сделать проект максимально читабельным и удобным для сопровождения. Гао, я надеюсь, ты не удивишься, увидев некоторые странные операции позже.
1. Компоненты класса больше не используются, полностью охватывают хуки и единообразно используют функциональные компоненты.
2. Внутреннее состояние компонента обрабатывается хуками, а все бизнес-данные управляются в редуксе.
3. Конкретные коды запросов ajax и последующей обработки данных все помещаются в actionCreator и обрабатываются redux-thunk, чтобы максимально упростить код компонента.
4. Каждый компонент-контейнер имеет свой собственный независимый редуктор, который затем объединяется с глобальным хранилищем с помощью метода redux combReducer.
5. В именах переменных JS (включая имена функций) используется строчный верблюжий регистр, имена компонентов или имена контейнеров стилей, экспортируемых styled-components, используют большой верблюжий регистр, а все имена констант пишутся с заглавной буквы.
6. Все общепринятые имена классов CSS пишутся строчными буквами английского алфавита, слова соединяются символами подчеркивания, а слова в именах классов хуков анимации CSS соединяются символом -.
7. Все данные в пропсах должны быть деконструированы и назначены заранее в передней части компонента, а полученные имя свойства и имя метода должны быть объявлены отдельно. -redux также должен быть объявлен отдельно.
8. UseEffect пишется впереди и сразу следует за кодом назначения деструктурирования реквизита.
9. Все функции, отвечающие за возврат JSX, должны быть унифицированы в конце функции, а не перемежаться функциями обработки событий и прочей логикой.
10. В функции, возвращаемой mapDispatchToProps, имя функции имеет формат xxxDispatch, чтобы избежать конфликта с существующим именем действия.
3. Общая структура проекта и демонстрация
Примечание: этот проект относится к разработке интерфейса Android-приложения NetEase Cloud Music. Базовый компонент колеса не использует какую-либо структуру пользовательского интерфейса, что является сложной задачей для меня. В этом процессе я также получил большой опыт проектирования.
Поскольку загружать видео более проблематично, но изображения относительно однообразны и не могут отражать динамику этого веб-приложения, поэтому в следующем примере используется gif.
1. Рекомендуемая часть
Главная Рекомендуем:
Рекомендуемые сведения о плейлисте:Эффект врезки и вырезания в эфире, а также есть эффект выделения с заголовком и слайдом. Когда в списке воспроизведения слишком много песен, выполняется обработка постраничного проигрывания, и непрерывно выполняется подтягивающая загрузка по мере выполнения прокрутки, чтобы предотвратить зависание страницы из-за большого количества загрузок DOM.2. Партия певицы
Список певцов:
Здесь выполняется процесс асинхронной загрузки: вытягивание до конца для получения новых данных и вытягивание вниз для перезагрузки данных.Данные певицы:
3. Таблица лидеров
Страница со списком:
Детали списка:4. Игрок
Ядро плеера:
плейлист:
Будет тот же эффект отскока, что и в мобильном приложении.
5. Раздел поиска
4. Совместное использование некоторых модулей проекта
1. Используйте better-scroll, чтобы создать очень простой в использовании базовый компонент прокрутки.
import React, { forwardRef, useState,useEffect, useRef, useImperativeHandle } from "react"
import PropTypes from "prop-types"
import BScroll from "better-scroll"
import styled from 'styled-components';
import { debounce } from "../../api/utils";
const ScrollContainer = styled.div`
width: 100%;
height: 100%;
overflow: hidden;
`
const Scroll = forwardRef((props, ref) => {
const [bScroll, setBScroll] = useState();
const scrollContaninerRef = useRef();
const { direction, click, refresh, pullUpLoading, pullDownLoading, bounceTop, bounceBottom } = props;
const { pullUp, pullDown, onScroll } = props;
useEffect(() => {
const scroll = new BScroll(scrollContaninerRef.current, {
scrollX: direction === "horizental",
scrollY: direction === "vertical",
probeType: 3,
click: click,
bounce:{
top: bounceTop,
bottom: bounceBottom
}
});
setBScroll(scroll);
if(pullUp) {
scroll.on('scrollEnd', () => {
//判断是否滑动到了底部
if(scroll.y <= scroll.maxScrollY + 100){
pullUp();
}
});
}
if(pullDown) {
scroll.on('touchEnd', (pos) => {
//判断用户的下拉动作
if(pos.y > 50) {
debounce(pullDown, 0)();
}
});
}
if(onScroll) {
scroll.on('scroll', (scroll) => {
onScroll(scroll);
})
}
if(refresh) {
scroll.refresh();
}
return () => {
scroll.off('scroll');
setBScroll(null);
}
// eslint-disable-next-line
}, []);
useEffect(() => {
if(refresh && bScroll){
bScroll.refresh();
}
})
useImperativeHandle(ref, () => ({
refresh() {
if(bScroll) {
bScroll.refresh();
bScroll.scrollTo(0, 0);
}
}
}));
const PullUpdisplayStyle = pullUpLoading ? { display: "" } : { display: "none" };
const PullDowndisplayStyle = pullDownLoading ? { display: "" } : { display: "none" };
return (
<ScrollContainer ref={scrollContaninerRef}>
{props.children}
{/* 滑到底部加载动画 */}
<PullUpLoading style={ PullUpdisplayStyle }></PullUpLoading>
{/* 顶部下拉刷新动画 */}
<PullDownLoading style={ PullDowndisplayStyle }></PullDownLoading>
</ScrollContainer>
);
})
Scroll.defaultProps = {
direction: "vertical",
click: true,
refresh: true,
onScroll: null,
pullUpLoading: false,
pullDownLoading: false,
pullUp: () => {},
pullDown: () => {},
bounceTop: true,
bounceBottom: true
};
Scroll.propTypes = {
direction: PropTypes.oneOf(['vertical', 'horizental']),
refresh: PropTypes.bool,
onScroll: PropTypes.func,
pullUp: PropTypes.func,
pullDown: PropTypes.func,
pullUpLoading: PropTypes.bool,
pullDownLoading: PropTypes.bool,
bounceTop: PropTypes.bool,//是否支持向上吸顶
bounceBottom: PropTypes.bool//是否支持向上吸顶
};
export default React.memo(Scroll);
2. Компоненты динамической загрузки
import React from 'react';
import styled, {keyframes} from 'styled-components';
import style from '../../assets/global-style'
const dance = keyframes`
0%, 40%, 100%{
transform: scaleY(0.4);
transform-origin: center 100%;
}
20%{
transform: scaleY(1);
}
`
const Loading = styled.div`
height: 10px;
width: 100%;
margin: auto;
text-align: center;
font-size: 10px;
>div{
display: inline-block;
background-color: ${style["theme-color"]};
height: 100%;
width: 1px;
margin-right:2px;
animation: ${dance} 1s infinite;
}
>div:nth-child(2) {
animation-delay: -0.4s;
}
>div:nth-child(3) {
animation-delay: -0.6s;
}
>div:nth-child(4) {
animation-delay: -0.5s;
}
>div:nth-child(5) {
animation-delay: -0.2s;
}
`
function LoadingV2() {
return (
<Loading>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<span>拼命加载中...</span>
</Loading>
);
}
export default LoadingV2;
3. Ленивая загрузка модуля и разделение кода (CodeSpliting)
React официально предоставил соответствующее решение, которое можно дополнить Lazy и Suspense, которые поставляются с React. Операция выглядит следующим образом:
import React, {lazy, Suspense} from 'react';
const HomeComponent = lazy(() => import("../application/Home/"));
const Home = (props) => {
return (
<Suspense fallback={null}>
<HomeComponent {...props}></HomeComponent>
</Suspense>
)
};
......
export default [
{
path: "/",
component: Home,
routes: [
{
path: "/",
exact: true,
render: ()=> (
<Redirect to={"/recommend"}/>
)
},
{
path: "/recommend/",
extra: true,
key: 'home',
component: Recommend,
routes:[{
path: '/recommend/:id',
component: Album,
}]
}
......
]
},
];
V. Планирование будущего и перспективы
В настоящее время основная часть этого проекта завершена, но есть еще много возможностей для расширения.Текущий модуль эквивалентен только 60% завершенности. Что касается планов на будущее, вот что я организовал:
- Полная коллекция и функции истории игр в конце месяца
- Полная функция входа и модуль комментариев к октябрю
- Внедрить модуль MV к середине октября
- Параллельно я написал серию разборок на тему «Прикосновение рук, использование React для реализации веб-приложения NetEase Cloud Music».
- Дополнительные функции будут добавлены в будущем...
Поскольку есть другие проекты, которыми нужно заняться, выполнение этого проекта с открытым исходным кодом занимает большую часть моего свободного времени, но я думаю, что оно того стоит, в конце концов, это упражнение и вызов для меня. И значение этого проекта для меня состоит не только в том, чтобы выполнить эти функции, но и в том, чтобы сконденсировать мои собственные размышления о технологии и личную практику предыдущих идей. По правде говоря, когда проект застревает на одном месте, мое сердце просто разрывается, но, пройдя его, я понимаю, что многому научился, и я полон чувства выполненного долга.Это мой независимый открытый исходный код проект, более глубокое чувство.
Наконец, я хотел бы поблагодарить тех людей и проекты, которые помогли мне, так что у меня есть уверенность, чтобы начать этот проект и преодолевать трудности одну за другой.
Спасибо, мистер Хуан И.Практический курс по музыке Vue., позвольте мне освоить множество нативных навыков JS и навыков упаковки компонентов.
Спасибо, ДеллЛи.Реакция от вступления до короткометражного бояПозвольте мне начать работу с React, позвольте мне выработать привычку кодирования React-инжиниринга.
благодарныйReact проект с открытым исходным кодом манго-музыка,Хотя мой текущий проект полностью отличается от него с точки зрения концепции разработки и стиля кодирования, все еще есть некоторые анимационные эффекты, основанные на этом проекте с открытым исходным кодом, которые открыли мне глаза Большое спасибо, пожалуйста, не забудьте внести свой вклад к этому проекту Нажмите звезду, хотя крючки не используются, все же стоит изучить.
Наконец, этот проект ни в коем случае не является временным демо. Я буду поддерживать его в течение длительного времени. Я надеюсь, что каждый может активно отправлять PR и вопросы, чтобы сделать этот проект более совершенным, что может помочь большему количеству людей узнать, как реагировать в дополнение к официальная демонстрация Помимо практического применения, избегайте ям.
На самом деле, хотя эффект от этого проекта вполне закономерен, процесс разработки довольно мучителен, я продолжу делиться им позже, и поделюсь с вами проблемами, с которыми я столкнулся в процессе разработки. Наконец, не забудьте дать этому проекту звезду, спасибо за вашу поддержку.
Наконец, поместите мой публичный аккаунт WeChat: интерфейс одноклассников Sanyuan
Цикл статей по разборке будет выкладываться в паблик аккаунт, так что следите за обновлениями!