React全家桶构建一款Web音乐App实战
2017-12-20 15:16
393 查看
上一节使用create-react-app脚手架搭建了基本项目骨架,这一节继续制作项目需要的字体图标和页面主路由的搭建
图标放大或缩小不会被拉伸,会保持足够的清晰度
颜色可以随意设置。如果使用普通图片,图片颜色已经是设计好的,如果要换颜色需要借助工具来对图片进行修改
制作字体图片首先我们需要svg图片。svg图片可以从iconfont阿里矢量图标库自行选择。笔者已经下载了项目需要的svg图片
借助一个叫iconmoon的网站。浏览器地址上输入:icomoon.io/app
点击上方的Import Icons按钮弹出选择对话框,选择刚刚下载的svg图片
点击打开
然后选中所有的图标,点击Generate Font
跳转到如下界面,点击download
下载后面的压缩包如下
该压缩包包含了字体图片使用的demo,和生成的字体图标文件及相关样式。在项目src目录下面新建一个assets目录然后再新建一个stylus目录用来放置styl文件,解压压缩包把里面的style.css和fonts文件夹复制出来放置到stylus目录下。
对fonts目录下的文件和style.css稍做修改
将fonts下面的文件名都重命名为icomusic,将style.css重命名为font.styl。然后打开icomusic将里面的花括号和分号去掉变成标准的styl语法格式,把里面的iconmoon全部替换为icomusic
修改后的文件结构如下
删除App.test.js、logo.svg。在src目录下面新建一个components目录,将App.js和App.styl放置在components目录下面,将App.styl中的内容全部删除,然后删除App.js中render函数中的div标签下面的内容
修改index.css文件,将html、body、div#root宽高都设置为100%,在body上设置根字体和字体大小
最后在stylus目录下新增reset.styl文件
修改后的目录结构如下
推荐页
排行榜
搜索
这三个页面是一个Tab选项卡模式顶部是Logo,三个Tab按钮中间是Tab对应的视图,Logo和Tab按钮是不变的,所以这里中间就设计成一个路由的视图界面,三个Tab对应三个路由
编写Logo及Tab样式在assets目录下面新建一个imgs文件夹用来存放图片,这里放了三张图片,其中一张就是头部Logo图片,其它两张后面会用到
三个Tab采用flex布局,自适应屏幕宽度
编写推荐页、排行旁页、搜索页三个组件。在components目录下面新建recommend、ranking和search三个目录用来存放推荐、排行、搜索页面相关组件
在recommend目录下创建Recommend.js和recommend.styl。React约定组件的名字首字母大写。对应的js文件名和组件一样大写(不强制),组件对应一个样式文件,命名和组件名一样方便寻找
recommend.styl内容暂时为空
同样在ranking目录和search目录下新建Ranking.js、ranking.styl和Search.js、search.styl
编写路由
回到App.js中,import路由相关组件
在App组件中导入Recommend、Ranking和Search组件,App的根使用Router包裹,加入一个div包裹Route组件
在app.styl中增加一下样式样式填屏幕充剩余高度
使用NavLink组件包裹Tab,使其具有路由跳转功能
设置NavLink组件样式
NavList组件最后渲染的是一个a标签,使用以上样式对齐进行美化,在当前NavLink组件被激活的时候回自动添加上**.active**样式
App.js和app.styl完整代码如下
后续更新中...
完整项目地址:github.com/code-mcx/ma…
本章节代码在chapter2分支
作者:code_mcx
链接:https://juejin.im/post/5a3738876fb9a0450e763541
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
字体图标制作
为什么要使用字体图标?图标放大或缩小不会被拉伸,会保持足够的清晰度
颜色可以随意设置。如果使用普通图片,图片颜色已经是设计好的,如果要换颜色需要借助工具来对图片进行修改
制作字体图片首先我们需要svg图片。svg图片可以从iconfont阿里矢量图标库自行选择。笔者已经下载了项目需要的svg图片
借助一个叫iconmoon的网站。浏览器地址上输入:icomoon.io/app
点击上方的Import Icons按钮弹出选择对话框,选择刚刚下载的svg图片
点击打开
然后选中所有的图标,点击Generate Font
跳转到如下界面,点击download
下载后面的压缩包如下
该压缩包包含了字体图片使用的demo,和生成的字体图标文件及相关样式。在项目src目录下面新建一个assets目录然后再新建一个stylus目录用来放置styl文件,解压压缩包把里面的style.css和fonts文件夹复制出来放置到stylus目录下。
对fonts目录下的文件和style.css稍做修改
将fonts下面的文件名都重命名为icomusic,将style.css重命名为font.styl。然后打开icomusic将里面的花括号和分号去掉变成标准的styl语法格式,把里面的iconmoon全部替换为icomusic
font.styl
@font-face font-family: 'icomusic' src: url('fonts/icomusic.eot?nnepb1') src: url('fonts/icomusic.eot?nnepb1#iefix') format('embedded-opentype'), url('fonts/icomusic.ttf?nnepb1') format('truetype'), url('fonts/icomusic.woff?nnepb1') format('woff'), url('fonts/icomusic.svg?nnepb1#icomusic') format('svg') font-weight: normal font-style: normal [class^="icon-"], [class*=" icon-"] /* use !important to prevent issues with browser extensions that change fonts */ font-family: 'icomusic' !important speak: none font-style: normal font-weight: normal font-variant: normal text-transform: none line-height: 1 /* Better Font Rendering =========== */ -webkit-font-smoothing: antialiased -moz-osx-font-smoothing: grayscale .icon-back:before content: "\e900" .icon-delete:before content: "\e901" .icon-fe-music:before content: "\e902" .icon-list-play:before content: "\e903" .icon-music:before content: "\e904" .icon-next:before content: "\e905" .icon-pause:before content: "\e906" .icon-play:before content: "\e907" .icon-play-list:before content: "\e908" .icon-previous:before content: "\e909" .icon-search:before content: "\e90a" .icon-shuffle-play:before content: "\e90b" .icon-single-play:before content: "\e90c" .icon-user:before content: "\e90d"
修改后的文件结构如下
页面路由搭建
准备
先对项目结构做一些修改删除App.test.js、logo.svg。在src目录下面新建一个components目录,将App.js和App.styl放置在components目录下面,将App.styl中的内容全部删除,然后删除App.js中render函数中的div标签下面的内容
App.js
//import React, { Component } from 'react'; import React from 'react'; //import logo from './logo.svg'; 删除此行 import './App.styl'; class App extends React.Component { render() { return ( //<div className="App"> <div className="app"> //<header className="App-header"> // <img src={logo} className="App-logo" alt="logo" /> // <h1 className="App-title">Welcome to React</h1> //</header> //<p className="App-intro"> // To get started, edit <code>src/App.js</code> and save to reload. //</p> </div> ); } } export default App;
Index.js
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; //import App from './App'; import App from './components/App'; import registerServiceWorker from './registerServiceWorker'; ReactDOM.render(<App />, document.getElementById('root')); registerServiceWorker();
修改index.css文件,将html、body、div#root宽高都设置为100%,在body上设置根字体和字体大小
index.css
html, body, #root { width: 100%; height: 100%; } body { margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; font-size: 16px; } ::-webkit-scrollbar { width: 0; height: 0; }
最后在stylus目录下新增reset.styl文件
reset.styl
/* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 License: none (public domain) */ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video margin: 0 padding: 0 border: 0 vertical-align: baseline /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section display: block body line-height: 1 ol, ul list-style: none blockquote, q quotes: none blockquote:before, blockquote:after, q:before, q:after content: '' content: none table border-collapse: collapse border-spacing: 0
修改后的目录结构如下
搭建路由
我们先来看一下页面结构推荐页
排行榜
搜索
这三个页面是一个Tab选项卡模式顶部是Logo,三个Tab按钮中间是Tab对应的视图,Logo和Tab按钮是不变的,所以这里中间就设计成一个路由的视图界面,三个Tab对应三个路由
编写Logo及Tab样式在assets目录下面新建一个imgs文件夹用来存放图片,这里放了三张图片,其中一张就是头部Logo图片,其它两张后面会用到
App.js
import React from 'react'; import logo from "../assets/imgs/logo.png" import '../assets/stylus/reset.styl' import './App.styl'; class App extends React.Component { render() { return ( <div className="app"> <header className="app-header"> <img src={logo} className="app-logo" alt="logo" /> <h1 className="app-title">Mango Music</h1> </header> <div className="music-tab"> <div className="tab-item selected"> <span>推荐</span> </div> <div className="tab-item"> <span>排行榜</span> </div> <div className="tab-item"> <span>搜索</span> </div> </div> </div> ); } } export default App;
App.styl
.app width: 100% height: 100% color: #DDDDDD background-color: #212121 .app-header height: 55px line-height: 55px color: #FFD700 text-align: center .app-logo width: 30px height: 25px margin-top: -5px vertical-align: middle .app-title display: inline-block height: 55px margin-left: 10px font-size: 18px font-weight: 300 .music-tab display: flex height: 30px line-height: 30px color: #DDDDDD text-align: center .tab-item flex: 1
三个Tab采用flex布局,自适应屏幕宽度
编写推荐页、排行旁页、搜索页三个组件。在components目录下面新建recommend、ranking和search三个目录用来存放推荐、排行、搜索页面相关组件
在recommend目录下创建Recommend.js和recommend.styl。React约定组件的名字首字母大写。对应的js文件名和组件一样大写(不强制),组件对应一个样式文件,命名和组件名一样方便寻找
Recommend.js
import React from "react" import "./recommend.styl" class Recommend extends React.Component { render() { return ( <div className="music-recommend"> Recommend </div> ); } } export default Recommend
recommend.styl内容暂时为空
同样在ranking目录和search目录下新建Ranking.js、ranking.styl和Search.js、search.styl
Ranking.js
import React from "react" import "./ranking.styl" class Ranking extends React.Component { render() { return ( <div className="music-ranking"> Ranking </div> ); } } export default Ranking
Search.js
import React from "react" import "./search.styl" class Search extends React.Component { render() { return ( <div className="music-search"> Search </div> ); } } export default Search
编写路由
回到App.js中,import路由相关组件
import {BrowserRouter as Router, Route, Switch, Redirect, NavLink} from "react-router-dom"
在App组件中导入Recommend、Ranking和Search组件,App的根使用Router包裹,加入一个div包裹Route组件
import Recommend from "./recommend/Recommend" import Ranking from "./ranking/Ranking" import Search from "./search/Search"
<div className="music-view"> {/* Switch组件用来选择最近的一个路由,否则最后一个没有指定path的路由也会显示 Redirect重定向到列表页 */} <Switch> <Route path="/recommend" component={Recommend} /> <Route path="/ranking" component={Ranking} /> <Route path="/search" component={Search} /> <Redirect from="/" to="/recommend" /> <Route component={Recommend} /> </Switch> </div>
在app.styl中增加一下样式样式填屏幕充剩余高度
.music-view position: fixed top: 88px left: 0 bottom: 52px width: 100%
使用NavLink组件包裹Tab,使其具有路由跳转功能
<div className="tab-item"> <NavLink to="/recommend" className="nav-link"> <span>推荐</span> </NavLink> </div> <div className="tab-item"> <NavLink to="/ranking" className="nav-link"> <span>排行榜</span> </NavLink> </div> <div className="tab-item"> <NavLink to="/search" className="nav-link"> <span>搜索</span> </NavLink> </div>
设置NavLink组件样式
.nav-link, .link display: block color: inherit text-decoration: none &.active color: #FFD700 border-bottom: 2px solid #FFD700
NavList组件最后渲染的是一个a标签,使用以上样式对齐进行美化,在当前NavLink组件被激活的时候回自动添加上**.active**样式
App.js和app.styl完整代码如下
App.js
import React from 'react';
import {BrowserRouter as Router, Route, Switch, Redirect, NavLink} from "react-router-dom"import Recommend from "./recommend/Recommend" import Ranking from "./ranking/Ranking" import Search from "./search/Search"
import logo from "../assets/imgs/logo.png"
import '../assets/stylus/reset.styl'
import './App.styl';
class App extends React.Component {
render() {
return (
<Router>
<div className="app">
<header className="app-header">
<img src={logo} className="app-logo" alt="logo" />
<h1 className="app-title">Mango Music</h1>
</header>
<div className="music-tab">
<div className="tab-item"> <NavLink to="/recommend" className="nav-link"> <span>推荐</span> </NavLink> </div> <div className="tab-item"> <NavLink to="/ranking" className="nav-link"> <span>排行榜</span> </NavLink> </div> <div className="tab-item"> <NavLink to="/search" className="nav-link"> <span>搜索</span> </NavLink> </div></div>
<div className="music-view"> {/* Switch组件用来选择最近的一个路由,否则最后一个没有指定path的路由也会显示 Redirect重定向到列表页 */} <Switch> <Route path="/recommend" component={Recommend} /> <Route path="/ranking" component={Ranking} /> <Route path="/search" component={Search} /> <Redirect from="/" to="/recommend" /> <Route component={Recommend} /> </Switch> </div></div>
</Router>
);
}
}
export default App;
app.styl
.app width: 100% height: 100% color: #DDDDDD background-color: #212121 .app-header height: 55px line-height: 55px color: #FFD700 text-align: center .app-logo width: 30px height: 25px margin-top: -5px vertical-align: middle .app-title display: inline-block height: 55px margin-left: 10px font-size: 18px font-weight: 300 .music-tab display: flex height: 30px line-height: 30px color: #DDDDDD text-align: center .tab-item flex: 1.music-view position: fixed top: 88px left: 0 bottom: 52px width: 100%
.nav-link, .link display: block color: inherit text-decoration: none &.active color: #FFD700 border-bottom: 2px solid #FFD700
总结
在本章节讲解了如何制作字体图标,根据页面设计基本路由结构后续更新中...
完整项目地址:github.com/code-mcx/ma…
本章节代码在chapter2分支
作者:code_mcx
链接:https://juejin.im/post/5a3738876fb9a0450e763541
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
相关文章推荐
- React全家桶构建一款Web音乐App实战3
- 【WEB】Vue2.0音乐APP实战中的知识点总结(四)
- 【WEB】Vue2.0音乐APP实战中的知识点总结(三)
- react 实战案例(webpack构建)
- webpack---使用插件,常见webpack的plugin,构建vue,react单页面/多页面工程APP必备插件
- 【Web】vue2.0音乐APP实战中的知识点总结(二)
- 构建高性能web之路------mysql读写分离实战
- 如果让你设计一款混合APP,以公司项目为例,哪些界面通过Web展现,哪些界面用源生?
- webpack 1.x构建react项目简单配置
- react学习笔记(一)用create-react-app构建 React 开发环境
- React教程(六)——使用 create-react-app 快速构建 React 开发环境
- Spring实战5-基于Spring构建Web应用
- Cordova webapp实战开发:(3)后面可能会学到的东西
- 构建高性能web之mysql读写分离实战
- [HTML5之APP实战]基于ionic开发的一款KTV移动应用
- 解决:使用create-react-app构建react应用很慢
- 【《Node.js 实战》学习思维导图】第4章 构建Node Web程序
- 使用Electron构建React+Webpack桌面应用的方法
- 构建高可扩Web架构和分布式系统实战(下)
- 构建高可扩Web架构和分布式系统实战