{"id":27306101,"url":"https://github.com/lengxien/react-music-webapp","last_synced_at":"2025-04-12T03:40:57.429Z","repository":{"id":39422905,"uuid":"202650002","full_name":"LenGxien/react-music-webApp","owner":"LenGxien","description":"react-music-webapp","archived":false,"fork":false,"pushed_at":"2023-02-28T13:12:57.000Z","size":2923,"stargazers_count":10,"open_issues_count":8,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-29T14:17:41.584Z","etag":null,"topics":["better-scroll","es6","react","react-router","redux","styled-components","swipperjs","webpack"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LenGxien.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-16T03:13:22.000Z","updated_at":"2024-11-01T09:36:10.000Z","dependencies_parsed_at":"2025-03-29T14:17:43.746Z","dependency_job_id":"4f3d2b42-0fc9-4081-a6c4-5e1b6046c946","html_url":"https://github.com/LenGxien/react-music-webApp","commit_stats":null,"previous_names":["lengxien/react-music-webapp"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LenGxien%2Freact-music-webApp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LenGxien%2Freact-music-webApp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LenGxien%2Freact-music-webApp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LenGxien%2Freact-music-webApp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LenGxien","download_url":"https://codeload.github.com/LenGxien/react-music-webApp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248514221,"owners_count":21116899,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["better-scroll","es6","react","react-router","redux","styled-components","swipperjs","webpack"],"created_at":"2025-04-12T03:40:56.825Z","updated_at":"2025-04-12T03:40:57.422Z","avatar_url":"https://github.com/LenGxien.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# React + Redux 简易版QQ音乐webApp\n\n## 项目查看运行：\n```shell\n$ git clone https://github.com/guixianleng/react-music-webApp.git\n$ cd react-music-webApp\n$ npm install\n\n$ npm run start \n```\n## 功能：\n- [x] 推荐\n  - [x] 专辑歌曲列表\n  - [x] 专辑详情\n- [x] 排行榜\n  - [x] QQ排行榜\n  - [x] 全球榜(假数据)\n- [x] 歌手\n  - [x] 列表\n  - [x] 条件搜索\n- [x] 搜索功能\n  - [x] 热门搜索\n  - [x] 自定义搜索\n- [x] 播放器\n  - [x] 迷你播放器\n  - [x] 歌曲列表\n  - [x] 歌曲播放模式\n  - [x] 上一首\n  - [x] 下一首\n  - [x] 暂停\n  - [x] 进度条\n- [x] 换肤\n\n## 功能演示：\n### 1.推荐\n![推荐](https://github.com/guixianleng/images-store/blob/master/images/recommend.gif?raw=true)\n\n### 2. 排行榜\n![排行榜](https://github.com/guixianleng/images-store/blob/master/images/rank.gif?raw=true)\n\n### 3. 歌手\n![歌手](https://github.com/guixianleng/images-store/blob/master/images/singer.gif?raw=true)\n\n### 4. 搜索\n![搜索](https://github.com/guixianleng/images-store/blob/master/images/search.gif?raw=true)\n\n### 5. 播放器\n![播放器](https://github.com/guixianleng/images-store/blob/master/images/player.gif?raw=true)\n\n### 6. 换肤\n![播放器](https://github.com/guixianleng/images-store/blob/master/images/skin.gif?raw=true)\n\n## 功能实现介绍：\n### 1. 换肤功能\n该项目使用的是`styled-components`样式化组件，可以去[官网](https://www.styled-components.com/docs/basics)了解\n\n优点：\n- 可以通过编写实际的CSS代码来设计组件样式，也不需要组件和样式之间的映射，即创建后就是一个正常的React组件，并且可以附加样式给当前组件。 优化react组件解耦.\n- 在一个组件内会将结构、样式和逻辑写在一起，有利于组件间的隔离。为了顺应组件化的潮流..\n- 使用`styled-components`不需要再使用className属性来控制样式，而是将样式写成更具语义化的组件的形式.\n- 使用style-components会随机生成一个class名称，这样不会污染到全局变量.\n\n注意：\n\n引入全局样式引入，需要使用`createGlobalStyle`组件\n```js\nimport { createGlobalStyle } from 'styled-components'\n\nexport const GlobalStyle = createGlobalStyle`\n  ...\n`\n```\n然后再将定义的全局样式组件，放在 render() 中最外层元素下面\n\n换肤使用的是`ThemeProvider`组件，[官网](https://www.styled-components.com/docs/advanced#theming)有详细说明.\n\n```js\nimport { ThemeProvider } from 'styled-components'\n\nrender () {\n  const theme = {\n    backgroundColor: '#317c47',\n    color: '#317c47'\n  }\n  return (\n    \u003cThemeProvider theme={theme}\u003e\n      ...\n    \u003c/ThemeProvider\u003e\n  )\n}\n```\n\n### 2. better-scroll移动端scroll神器\n\n```js\nimport React, { Component } from 'react'\nimport BScroll from 'better-scroll'\nimport PropTypes from 'prop-types'\n\nimport Loading from '../../baseUI/Loading/Loading'\nimport { debounce } from '../../utils'\nimport { ScrollDiv, PullUpLoading, PullDownLoading } from './style'\n\n\nclass Scroll extends Component {\n  constructor(props) {\n    super(props)\n    this.scrollRef = React.createRef()\n  }\n\n  static defaultProps = {\n    direction: 'vertical',\n    click: true,\n    refresh: true,\n    onScroll: null,\n    pullUpLoading: false,\n    pullDownLoading: false,\n    pullUp: () =\u003e {},\n    pullDown: () =\u003e {},\n    bounceTop: true,\n    bounceBottom: true\n  }\n\n  static propTypes = {\n    // 开启滚动方式\n    direction: PropTypes.oneOf(['vertical', 'horizontal']),\n    click: PropTypes.bool,\n    // 事件派发\n    refresh: PropTypes.bool,\n    onScroll: PropTypes.func,\n    pullUp: PropTypes.func,\n    pullDown: PropTypes.func,\n    // 开启加载\n    pullUpLoading: PropTypes.bool, \n    pullDownLoading: PropTypes.bool,\n    // 回弹\n    bounceTop: PropTypes.bool,\n    bounceBottom: PropTypes.bool\n  }\n\n  componentDidUpdate() {\n    // 组件更新后，如果实例化了better-scroll并且需要刷新就调用refresh()函数\n    if (this.bScroll \u0026\u0026 this.props.refresh === true) {\n      this.bScroll.refresh()\n    }\n  }\n\n  componentDidMount() {\n    // Options 参数\n    const { direction, click, bounceTop, bounceBottom } = this.props\n    // Events 事件\n    const { onScroll, pullUp, pullDown } = this.props\n    if (this.bScroll) return\n    this.bScroll = new BScroll(this.scrollRef.current, {\n      scrollX: direction === 'horizontal',\n      scrollY: direction === 'vertical',\n      /**\n       * 1 滚动的时候会派发scroll事件，会截流\n       * 2滚动的时候实时派发scroll事件，不会截流。\n       * 3除了实时派发scroll事件，在swipe的情况下仍然能实时派发scroll事件\n       */\n      probeType: 3,\n      stopPropagation: true,\n      // 是否派发click事件\n      click: click,\n      // 是否启用上下拉效果\n      bounce: {\n        top: bounceTop,\n        bottom: bounceBottom\n      }\n    })\n    // 监听滚动事件\n    if (!this.bScroll || !onScroll) return\n    this.bScroll.on('scroll', (scroll) =\u003e {\n      this.props.onScroll(scroll)\n    })\n    this.handleDealUp(pullUp)\n    this.handleDealDown(pullDown)\n  }\n  \n  // 处理判断是否滑动到了底部\n  handleDealUp (pullUp) {\n    if(!this.bScroll || !pullUp) return\n    this.bScroll.on('scrollEnd', () =\u003e {\n      if (this.bScroll.y \u003c= this.bScroll.maxScrollY + 100) {\n        debounce(pullUp, 200)()\n      }\n    })\n    return () =\u003e {\n      this.bScroll.off('scrollEnd')\n    }\n  }\n  // 处理判断用户的下拉动作\n  handleDealDown (pullDown) {\n    if(!this.bScroll || !pullDown) return\n    this.bScroll.on('touchEnd', (pos) =\u003e {\n      if(pos.y \u003e 50) {\n        debounce(pullDown, 200)()\n      }\n    })\n    return () =\u003e {\n      this.bScroll.off('touchEnd')\n    }\n  }\n\n  // 销毁\n  componentWillUnmount() {\n    this.bScroll.off('scroll')\n    this.bScroll = null\n  }\n\n  // 刷新\n  refresh() {\n    if (this.bScroll) {\n      this.bScroll.refresh()\n    }\n  }\n  render() {\n    const { pullUpLoading, pullDownLoading, children } = this.props\n    return (\n      \u003cScrollDiv ref={this.scrollRef} className=\"scroll-view\"\u003e\n        {children}\n        {/* 顶部下拉刷新动画 */}\n        \u003cPullDownLoading pullDown={pullDownLoading}\u003e\n          \u003cLoading\u003e\u003c/Loading\u003e\n        \u003c/PullDownLoading\u003e\n        {/* 上滑至底部加载动画 */}\n        \u003cPullUpLoading pullUp={pullUpLoading}\u003e\n          \u003cLoading\u003e\u003c/Loading\u003e\n        \u003c/PullUpLoading\u003e\n      \u003c/ScrollDiv\u003e\n    )\n  }\n}\n\nexport default Scroll\n\n```\n\n## react学习资源：\n- [React.js小书](http://huziketang.mangojuice.top/books/react/)，react/redux介绍的很细\n- [Redux中文文档](http://cn.redux.js.org/)\n- [React中文文档](https://react.docschina.org/)\n- [技术胖React系列](https://juejin.im/post/5d085be0f265da1bac401937)\n- [技术胖Redux系列](https://juejin.im/post/5d3e3c42e51d45590a445c37)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flengxien%2Freact-music-webapp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flengxien%2Freact-music-webapp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flengxien%2Freact-music-webapp/lists"}