在本节中,我们将编写“猜你喜欢”组件,该组件用于展示一个九宫格的卡片布局。
一、创建 Model
在 models/home.ts 中添加以下内容:
-
声明接口地址:
const GUESS_URL = '/mock/11/bear/guess'; -
定义
Guess接口:interface IGuess { id: string; title: string; image: string; } -
在
HomeState中定义guess属性:export interface HomeState { carousels: ICarousel[]; guess: IGuess[]; } -
在
effects中定义请求猜你喜欢的列表数据:effects: { *fetchGuess(_, { call, put }) { const { data } = yield call(axios.get, GUESS_URL); yield put({ type: 'setState', payload: { guess: data, }, }); }, },
二、创建组件
在 pages/Home/Guess.tsx 中创建组件:
import React from 'react';
import { View, Text, Image, FlatList, StyleSheet, TouchableOpacity } from 'react-native';
import { connect, ConnectedProps } from 'react-redux';
import { RootState } from '@/models/index';
interface IProps extends ConnectedProps<typeof connector> {}
class Guess extends React.PureComponent<IProps> {
componentDidMount() {
this.fetchGuessData();
}
fetchGuessData = () => {
const { dispatch } = this.props;
dispatch({
type: 'home/fetchGuess',
});
};
renderItem = ({ item }: { item: IGuess }) => {
return (
<TouchableOpacity style={styles.item} onPress={() => alert('点击')}>
<Image source={{ uri: item.image }} style={styles.image} />
<View style={styles.rightContainer}>
<Text numberOfLines={2}>{item.title}</Text>
</View>
</TouchableOpacity>
);
};
render() {
const { guess } = this.props;
return (
<View style={styles.container}>
<View style={styles.header}>
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<Icon name="icon-xihuan" />
<Text style={styles.headerTitle}>猜你喜欢</Text>
</View>
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<Text style={styles.moreTitle}>更多</Text>
<Icon name="icon-more" />
</View>
</View>
<FlatList
numColumns={3}
data={guess}
renderItem={this.renderItem}
keyExtractor={(item) => item.id}
style={styles.list}
/>
<TouchableOpacity style={styles.changeGuess} onPress={this.fetchGuessData}>
<Text>
<Icon name="icon-huanyipi" size={14} color="red" /> 换一批
</Text>
</TouchableOpacity>
</View>
);
}
}
const mapStateToProps = ({ home }: RootState) => ({
guess: home.guess,
});
const connector = connect(mapStateToProps);
export default connector(Guess);
const styles = StyleSheet.create({
container: {
backgroundColor: '#ffffff',
borderRadius: 8,
margin: 16,
shadowOffset: { width: 0, height: 5 },
shadowOpacity: 0.5,
shadowRadius: 10,
shadowColor: '#ccc',
elevation: 4,
},
header: {
padding: 15,
flexDirection: 'row',
justifyContent: 'space-between',
borderBottomColor: '#efefef',
borderBottomWidth: StyleSheet.hairlineWidth,
},
headerTitle: {
marginLeft: 5,
color: '#333333',
},
moreTitle: {
color: '#6f6f6f',
},
list: {
paddingTop: 10,
paddingHorizontal: 10,
},
item: {
flex: 1,
marginVertical: 6,
marginHorizontal: 5,
},
image: {
width: '100%',
height: 100,
borderRadius: 8,
marginBottom: 10,
},
rightContainer: {
flex: 1,
},
changeGuess: {
padding: 10,
alignItems: 'center',
},
});
三、功能说明
-
数据请求:
- 在组件加载时,调用
fetchGuessData方法,通过 Dva 的dispatch请求数据。 - 数据请求成功后,通过
put将数据更新到HomeState中。
- 在组件加载时,调用
-
列表展示:
- 使用
FlatList组件展示数据,设置numColumns={3}实现九宫格布局。 - 每个列表项使用
TouchableOpacity实现点击效果。
- 使用
-
换一批功能:
- 点击“换一批”按钮,重新请求数据并更新列表。
四、样式说明
-
容器样式:
container:设置背景颜色、圆角、阴影等样式。header:设置头部的布局和样式。
-
列表项样式:
item:设置每个列表项的布局和间距。image:设置图片的宽度、高度和圆角。
-
按钮样式:
changeGuess:设置按钮的样式和点击效果。
五、总结
在本节中,我们完成了“猜你喜欢”组件的开发,包括数据请求、列表展示、点击事件处理和换一批功能。下一节,我们将在首页添加一个列表页面。