一、App.tsx结构搭建
头部
底部
中间区域是useRoutes(routes)根据当前的页面路径,再根据路由规则,从而渲染对应的路由内容。
头部组件封装成各个组件中通用的组件存放在src/components下 src/components/app-header/index.tsx
a、先做结构,首先将头部结构分成左右两部分,左边存放头部导航栏,右边存放输入框,创作者中心,用户头像。
b、再书写结构样式文件: 在app-header文件夹下新建styled.ts文件用于书写样式
使用styled-components写样式,需要先安装 npm i styled-components -D npm i --save-dev @type/styled-components
安装好了之后,就到styled.ts文件中书写样式。 1、先引入styled: import styled from 'styled-components'
2、
HeaderWrapper就是结构最外层的组件 HeaderLeft就是左边结构最外层的组件 HeaderRight就是右边结构最外层的组件 最后再到组件中引入样式
import { HeaderLeft, HeaderRight, HeaderWrapper } from './style'
二、项目样式主题配置
在src/assets下新建theme文件夹,该文件夹专门用于集中管理项目的样式主题配置。
写入固定样式:
然后再引入该文件到项目入口文件处:
最后再到每一个组件中,给最外层结构下添加类名wrap-v1 次外层结构下添加类名wrap-v2
eg:
三、app-header组件的左边结构搭建
左边结构放在HeaderLeft组件内 准备一个导航列表资源文件,放在assets/data/header_titles.json文件中
[ { "title": "发现音乐", "type": "path", "link": "/discover" }, { "title": "我的音乐", "type": "path", "link": "/mine" }, { "title": "关注", "type": "path", "link": "/focus" }, { "title": "商城", "type": "link", "link": "music.163.com/store/produ…" }, { "title": "音乐人", "type": "link", "link": "music.163.com/st/musician" }, { "title": "下载客户端", "type": "path", "link": "/download" } ]
然后再将资源引入到组件中 import headerTitles from '@/assets/data/header_titles.json'
然后再将资源数据利用map方法渲染在导航列表处
渲染数据时,要记得做条件渲染,因为导航中有三个不属于路由组件的。
若item.type==="path",则说明是路由组件,则返回一个路由跳转NavLink
若item.type==="link"则说明是超链接,则返回一个超链接a
完成导航列表结构搭建之后,再完成一下导航高亮
我们进行路由跳转时,选择使用NavLink,而不是用Link,原因是:
NavLink可以帮助精准匹配,且其可以更方便的添加活动样式。使用NavLink时,他会自动检测当前页面路径是否与当前的路由路径相匹配,若匹配,则会自动的添加active类名。 (active类的样式需要先写好)
总而言之就是,在点击导航选项时,如果想要导航高亮,那么就使用NavLink。
四、app-header右侧结构搭建
要使用antd组件库中的组件,所以需要先安装组件库。
npm install antd
再安装组件图标 npm install --save @ant-design/icons
然后到assets/css/index.less文件中引入antd组件样式
且配置好自定义的主题,引入需要用到的antd组件
这里要用到input组件和搜索的图标组件SearchOutline。
五、"发现音乐"组件下的"推荐组件"显示
discover/index.tsx
discover/c-cpns文件夹专门用于封装"发现音乐"组件下的非路由组件 例如:头部导航栏组件
在assets/data/local_data.ts文件中存放导航栏数据,然后将数据引入到组件中。
discover/c-cpns/nav-bar/index.tsx:
import { discoverMenu } from '@/assets/data/local_data'
引入样式文件:import { NavWrapper } from './style'
NavWrapper组件则作为整个结构最外层的组件。
styled.ts:
在导航栏组件中利用map方法将数据渲染在组件中。
这里的导航选项同样需要在用户点击之后就高亮显示,所以利用NavLink。
“推荐”组件下的各个非路由组件显示:
在src/views/discover/c-views存放“发现音乐”组件下的路由组件 src/views/discover/c-views/recommend recommend/service存放“推荐组件”中用到的网络请求 recommend/c-cpns存放“推荐组件”下的非路由组件 recommend/store存放“推荐组件”中用到的各种数据 recommend/index.tsx是“推荐组件”的总架子,将各个非路由组件都引入到该文件中显示。
recommend/c-cpns/top-banner/index.tsx是轮播图组件。 在service/recommend.ts文件中封装网络请求接口方法。
获取轮播图数据:
在store/recommend.ts文件下存放数据以及异步方法
interface IRecommendState { bannerList:any[] }
const initialState : IRecommendState ={ bannerList:[] }
const recommendSlice = createSlice({ name: 'recommend', initialState, reducers:{} }
最后再到src/store/index.ts中引入redux
在recommend/store/index.ts中开始书写异步请求方法,用于获取轮播图数据。 (利用createAsyncThunk来书写异步请求)调用接口方法。
然后再到recommend/c-cpns/top-banner/index.tsx中调用异步方法,发送请求,获取数据
const dispatch=useAppDispatch()
useEffect(()=>{ dispatch(fetchRecommendDataAction()) },[])
然后再利用useAppSelector获取redux中存储的数据
书写静态结构以及样式文件,分成左右两部分,左边是轮播图,右边是下载客户端。
拿到了redux中存储的轮播图数据,在组件中渲染出来。
从antd组件库中引入轮播图组件
渲染出轮播图图片后,实现图片左右切换效果
1、先获取到轮播图组件这个对象。(由于轮播图组件比较大,所以获取其DOM对象时利用<Element<typeof 组件名>>(null)) )
Carousel ref={bannerRef}
再利用组件自带的切换图片的方法:
prev():切换到上一张图片
next():切换到下一张图片
然后分别调用prev()和next()方法
下面再去实现轮播图背景图片的高斯模糊效果。
所谓的高斯模糊效果,实际上就是拿到当前轮播图组件中显示的图片,然后对他进行模糊处理,再作为背景样式显示。
如何能拿到当前轮播图中显示的图片呢?
由于Carousel组件自带的afterChange事件,他会在轮播图图片发生切换时自动触发,并且将当前切换到的图片索引作为参数自动传入。那么我们利用拿到的这个图片索引再去数组中找到对应的图片即可。
Carousel afterChange={handelAfterChange}
然后创建一个状态变量用于表示图片索引
触发事件,调用函数,更改图片索引
根据图片索引,到数组中找到对应显示的图片以及他的路径
发现网易云官网对图片高斯模糊的处理是 给图片路径添加 '?ImageView&blur=heightxwidth'
最后再把当前效果作为轮播图背景样式显示:
下面再去实现轮播图组件下方的自定义指示器:
a、先隐藏原先的轮播图组件中原生的指示器 Carousel dots={false}
b、 再去设置自定义指示器
设置底部图标被激活样式:
只有当当前遍历到的图标的索引===被显示的轮播图图片的索引时,才能添加active类名。
总结:
1、先完成轮播图图片的渲染(接口,redux数据,异步方法,同步方法,组件获取数据,map渲染,Carousel组件) 2、在完成轮播图图片的左右切换效果(组件自带的prev,next方法,以及获取轮播图组件对象) 3、在完成轮播图组件的背景图片高斯模糊效果(图片切换触发afterChange事件,传入当前显示的图片的索引,在轮播图图片数组中根据索引找到图片路径,做高斯模糊效果,设置到背景样式中) 4、在完成轮播图组件底部图标样式自定义以及设置激活样式。(先隐藏原生样式,再设置自定义样式,再根据当前遍历到的底部图标的索引是否等于当前显示的轮播图图片的索引来判断是否添加active类名。)