前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >RN项目第二节 -- 首页实现

RN项目第二节 -- 首页实现

作者头像
谦谦君子修罗刀
发布2018-06-19 17:24:26
6.5K0
发布2018-06-19 17:24:26
举报
文章被收录于专栏:谦谦君子修罗刀

一、微组件的封装

每个页面的导航都会有不同的样式或者图片,为了实现代码的复用性,可以将导航统一封装成一个微小组件。 封装的Item需要有可点击事件,需要显示文字和图片。

代码语言:javascript
复制
import React, { PureComponent } from 'react'
import { View, Text, StyleSheet, TouchableOpacity, Image } from 'react-native'

export default class NavigationItem extends PureComponent {
    render() {
    // 图片和文字时从外界传入的 所以用到props
        let icon = this.props.icon &&
            <Image style={[styles.icon, this.props.iconStyle]} source={this.props.icon} />

        let title = this.props.title &&
            <Text style={[styles.title, this.props.titleStyle]}>{this.props.title}</Text>
        return (
            <TouchableOpacity style={styles.container} onPress={this.props.onPress}>
                {icon}
                {title}
            </TouchableOpacity>
        );
    }
}

// 样式
const styles = StyleSheet.create({
    container: {
        flex:1,
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
    },
    icon: {
        width: 27,
        height: 27,
        margin: 8,
    },
    title: {
        fontSize: 15,
        color: '#333333',
        margin: 8,
    }
});

再来分析每个页面都有不同的字体出现,比如说标题、段落、小标题。所以也可以将文字封装成单独的组件。

代码语言:javascript
复制
import React from 'react';
import ReactNative, { StyleSheet, Dimensions, Text ,ReactElement} from 'react-native'
import color from './color'

export function Heading1({style, ...props}) {
    return <Text style={[styles.h1, style]} {...props} />
}

export function Heading2({style, ...props}) {
    return <Text style={[styles.h2, style]} {...props} />
}

export function Paragraph({style, ...props}) {
    return <Text style={[styles.p, style]} {...props} />
}

//设置样式
const styles = StyleSheet.create({
    h1: {
        fontSize: 15,
        fontWeight: 'bold',
        color: '#222222',
    },
    h2: {
        fontSize: 14,
        color: '#222222',
    },
    p: {
        fontSize: 13,
        color: '#777777',
    },
});

将整个页面分为两部分,页面最下方是一个列表,可以当成是iOS中的tableView,而页面上方可以看做是头部的View,这个View里面存放了各种模块。模块之间会有分割线,可以将分割线也封装成组件。

代码语言:javascript
复制
import React, { PureComponent } from 'react'
import { View, Text, StyleSheet } from 'react-native'

import color from './color'

export default class SpacingView extends PureComponent {
    render() {
        return (
            <View style={styles.container}>
            </View>
        );
    }
}

// define your styles
const styles = StyleSheet.create({
    container: {
        height: 14,
        backgroundColor: color.background,
    },
});

在设置样式的时候,会用到全屏,因此可以把全屏幕的尺寸也封装起来。

代码语言:javascript
复制
import { Dimensions, Platform, PixelRatio } from 'react-native'

export default {
    width: Dimensions.get('window').width,
    height: Dimensions.get('window').height,
    onePixel: 1 / PixelRatio.get(),   //在iphone4+中代表一个像素点
    statusBarHeight: (Platform.OS === 'ios' ? 20 : 0)  //iOS平台状态栏默认为0,安卓平台默认为20
}

二、首页封装

1) 首页导航的实现 同样也是在navigationOptions调用箭头函数。返回标题、图片。当然左右两边可以返回已经封装好的NavigationItem属性。

代码语言:javascript
复制
static navigationOptions = ({ navigation }) => ({
        headerTitle: (
            <TouchableOpacity style={styles.searchBar}>
                <Image source={require('../../img/Home/search_icon.png')} style={styles.searchIcon} />
                <Paragraph>一点点</Paragraph>
            </TouchableOpacity>
        ),
        headerRight: (
            <NavigationItem
                icon={require('../../img/Home/icon_navigationItem_message_white.png')}
                onPress={() => {

                }}
            />
        ),
        headerLeft: (
            <NavigationItem
                title='福州'
                titleStyle={{ color: 'white' }}
                onPress={() => {

                }}
            />
        ),
        headerStyle: { backgroundColor: color.theme },
    })

2)列表的实现

首页要实现列表功能,采用组件FlatList。

  • 引用必要的组件
代码语言:javascript
复制
import color from '../../widget/color'
import NavigationItem from '../../widget/NavigationItem'
import SpacingView from '../../widget/SpacingView'
import screen from '../../common/screen'
import api from '../../api'
import { Heading1, Heading2, Paragraph } from '../../widget/Text'
  • 在render方法中返回FlatList并设置它的属性
代码语言:javascript
复制
render() {
        return (
            <View style={styles.container}>
                <FlatList
                    data={this.state.dataList}   //请求的数据
                    keyExtractor={this.keyExtractor} //设置每个item唯一的key
                    onRefresh={this.requestData}   //刷新的操作
                    refreshing={this.state.refreshing}   //刷新状态
                    ListHeaderComponent={this.renderHeader}  //头部页面展示
                    renderItem={this.renderCell}  //每个item
                />
            </View>
        );
    }
  • 存放的数据要在state中声明并指定属性。(类中)
代码语言:javascript
复制
state: {
        discounts: Array<Object>,
        dataList: Array<Object>,
        refreshing: boolean,
    }
  • 在构造函数中设置初始值,并绑定要实现的方法
代码语言:javascript
复制
constructor(props) {
        super(props)

        this.state = {
            discounts: [],
            dataList: [],
            refreshing: false,
        }

        { this.requestData = this.requestData.bind(this) }
        { this.renderCell = this.renderCell.bind(this) }
        { this.onCellSelected = this.onCellSelected.bind(this) }
        { this.keyExtractor = this.keyExtractor.bind(this) }
        { this.renderHeader = this.renderHeader.bind(this) }
        { this.onGridSelected = this.onGridSelected.bind(this) }
        { this.onMenuSelected = this.onMenuSelected.bind(this) }
    }
  1. 实现方法
  • keyExtractor设置每个item唯一的key
代码语言:javascript
复制
keyExtractor(item, index) {
        return item.id
    }
  • onRefresh对应的requestData方法做刷新的操作 每次请求数据,都要进行刷新,所以刷新的状态要改为true。而且要刷新之后,要刷新折扣版块和列表版块的内容。为了代码简洁,将这两个功能封装成方法
代码语言:javascript
复制
requestData() {
        //每次请求数据 都要进行刷新
        this.setState({ refreshing: true })
        //调用折扣
        this.requestDiscount()
        //调用推荐方法
        this.requestRecommend()
    }
  • 实现折扣模块的方法

这里使用ES7的的异步线程语法。await表示紧跟在后面的表达式需要等待结果。也就是说当执行到awiat的时候,执行器将交给其他线程,等执行权返回再从暂停的地方往后执行。 这里做的是请求数据的操作,用fetch函数传入api得到全部的折扣数据结果。然后再转化为json数据,接着把json中的data赋值给discounts数组。

代码语言:javascript
复制
 async requestDiscount() {
        try {
            let response = await fetch(api.discount)
            let json = await response.json()
            this.setState({ discounts: json.data })
        } catch (error) {
            alert('错误信息:'+error)
        }
    }
  • 实现推荐列表的方法

上图是从API中的recommend的url解析出来的json数据。选取需要的数据。在代码中用fetch将数据解析成json格式,取出data集合中的数据传入箭头函数中,一一赋值给指定变量之后返回给数组dataList。如此一来,就可以用setState方法改变数组的数据。

代码语言:javascript
复制
async requestRecommend(){
        try{
            let response = await fetch(api.recommend)
            let json = await response.json()
            let dataList = json.data.map(
                (info)=>{
                    return{
                        id:info.id,
                        imageUrl:info.squareimgurl,
                        title:info.mname,
                        subtitle:`$[{info.range}]${info.title}`,
                        price:info.price
                    }
                }
            )
            this.setState({
                dataList:dataList,
                refreshing:false,
            })
        }catch (error){
            this.setState({
                refreshing:false
            })
        }
    }

为了不影响渲染效果,可以将请求数据的方法放在componentDidMount方法中

代码语言:javascript
复制
componentDidMount() {
        this.requestData()
    }
  • 处理列表

在iOS或者其他编程语言中,会采用各类框架来防止代码冗余。最常用的是MVC模式。在本项目中,为了返回列表,可以先将列表的UI封装起来。

代码语言:javascript
复制
import React,{Component} from 'react'
import {View,Text,StyleSheet,TouchableOpacity,Image} from 'react-native'
import {Heading1,Paragraph}from '../../widget/Text'
import screen from '../../common/screen'
import color from '../../widget/color'
export default class GroupPurchaseCell extends Component{
    render(){
        let {info} = this.props
        let imageUrl = info.imageUrl.replace('w.h','160.0')
        return(
            <TouchableOpacity style={style.container} onPress = {()=>this.props.onPress(info)}>
                <Image source={{uri:imageUrl}} style={styles.icon}/>
                <View style={styles.rightContainer}>
                    <Heading1>{info.title}</Heading1>
                    <View>
                    </View>
                    <Paragraph numberOfLines={0} style={{ marginTop: 8 }}>{info.subtitle}</Paragraph>
                    <View style={{ flex: 1, justifyContent: 'flex-end' }}>
                        <Heading1 style={styles.price}>{info.price}元</Heading1>
                    </View>

                </View>
            </TouchableOpacity>
        )
    }
}
const styles = StyleSheet.create({
    container: {
        flexDirection: 'row',
        padding: 10,
        borderBottomWidth: screen.onePixel,
        borderColor: color.border,
        backgroundColor: 'white',
    },
    icon: {
        width: 80,
        height: 80,
        borderRadius: 5,
    },
    rightContainer: {
        flex: 1,
        paddingLeft: 20,
        paddingRight: 10,
    },
    price: {
        color: color.theme
    }
});
  • 到首页中调用 引入框架
代码语言:javascript
复制
import GroupPurchaseCell from '../GroupPurchase/GroupPurchaseCell'

将数据传给cell并调用

代码语言:javascript
复制
renderCell(info) {
        return (
            <GroupPurchaseCell
                info={info.item}
                onPress={this.onCellSelected}
            />
        )
    }

实现cell的onPress方法

代码语言:javascript
复制
onCellSelected(info) {
        //把状态栏的样式给成暗色
        StatusBar.setBarStyle('default', false)
        //跳转到详情页面,并把本页信息传递给详情页
        this.props.navigation.navigate('GroupPurchase', { info: info })
    }

当点击cell的时候,导航会跳转到详情页面,那么就要把要跳转页面的名称传入到navigate中。

  • 为了测试,先简单封装详情页 建立一个.js文件GroupPurchaseScene,用来测试
代码语言:javascript
复制
import React, { Component } from 'react'
import { View, Text, StyleSheet, ScrollView, TouchableOpacity, ListView, Image, InteractionManager } from 'react-native'

export default class GroupPurchaseScene extends Component {
    render(){
    return(
        <View>
            <Text>
                详情页面
            </Text>>
        </View>
    )
}
}
const Styles = StyleSheet.create({
    container: {
        flex:1,
        backgroundColor:'pink'
    }
})
  • 测试 在RootScene中引用详情页,并把它加入到导航当中
代码语言:javascript
复制
import GroupPurchaseScene from './scene/GroupPurchase/GroupPurchaseScene'
代码语言:javascript
复制
const Navigator = StackNavigator(
    {
        Tab: { screen: Tab },  //框架的页面
        // Web: { screen: WebScene }, //webview的页面
        GroupPurchase: { screen: GroupPurchaseScene },//详情页
    },

为了测试,先把首页的renderHeader()方法添加进去

代码语言:javascript
复制
renderHeader(){
        return(
            <View>
                <Text style={{fontSize:24}}>头部啊头部ddddddddddnihaoaha</Text>
            </View>
        )
    }

测试结果如下:

点击详情页也能跳转

  • 首页导航实现
代码语言:javascript
复制
static navigationOptions = ({ navigation }) => ({
        headerTitle: (
            <TouchableOpacity style={styles.searchBar}>
                <Image source={require('../../img/Home/search_icon.png')} style={styles.searchIcon} />
                <Paragraph>一点点</Paragraph>
            </TouchableOpacity>
        ),
        headerRight: (
            <NavigationItem
                icon={require('../../img/Home/icon_navigationItem_message_white.png')}
                onPress={() => {

                }}
            />
        ),
        headerLeft: (
            <NavigationItem
                title='福州'
                titleStyle={{ color: 'white' }}
                onPress={() => {

                }}
            />
        ),
        headerStyle: { backgroundColor: color.theme },
    })
  • 添加样式
代码语言:javascript
复制
searchBar: {
        width: screen.width * 0.7,
        height: 30,
        borderRadius: 19,
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: 'white',
        alignSelf: 'center',
    },
代码语言:javascript
复制
searchIcon: {
        width: 20,
        height: 20,
        margin: 5,
    }
  • 封装头部

头部分为2个部分,一个是滚动的部分,另一个则是格子的部分。并且这两部分底部都有一个分割线。现在来封装这两个部分。 先封装最上方的部分,新建一个HomeMenuView.js。而这个部分又是由许多小的view组成的。所以将这些小的view也封装起来。新建一个文件HomeMenuItem。而这个类返回的只要是一个图片和文字即可。

代码语言:javascript
复制
import React, {Component } from 'react'
import { View, Text, StyleSheet, Image, TouchableOpacity } from 'react-native'
import { Heading2 } from '../../widget/Text'
import screen from '../../common/screen'
export default class HomeMenuItem extends Component{
    render(){
        return(
            <TouchableOpacity
                style={styles.container}
                onPress = {this.props.onPress}
            >
                <Image source={this.props.icon} resizeMode='contain' style={styles.icon}/>
                <Heading2>
                    {this.props.title}
                </Heading2>

            </TouchableOpacity>
        );
    }

}

const styles = StyleSheet.create({
    container: {
        justifyContent: 'center',
        alignItems: 'center',
        width: screen.width / 5,
        height: screen.width / 5,
    },
    icon: {
        width: screen.width / 9,
        height: screen.width / 9,
        margin: 5,
    }
});

现在来封装HomeMenuView

这个View的主体是一个ScrollView和一个PageControl,当然RN中是没有特定的页面控制器的,所以该PageControl是需要自己封装的。把它放入widget组件中。

现在考虑PageControl需要什么属性。属性可以用propTypes来规定,然而最近React组件已经把PropTypes组件移除了React库,所以需要引入prop-types。import PropTypes from 'prop-types';

numberofPage:首先是各个组件能够分为多少页,这个是必须要传入的。规定为number类型。可以用isRequired来约束。 currentPage:当前页用来控制亮点会出现在哪一页,number类型。 hidesForSinglePage:当页面为1时,是否隐藏控制器,bool类型。 pageIndicatorTintColor:控制器上点的颜色,string类型。 currentPageIndicatorTintColor:当前亮点的颜色,string类型。 indicatorSize:指示器的大小,规定为object类型, indicatorStyle:指示器的样式,它是View规定的类型,所以规定为View.propTypes.style类型 currentIndicatorStyle:当前指示器的样式。同上 onPageIndicatorPress:点击指示器的处理时间,func类型。

引入头文件

代码语言:javascript
复制
import React, {Component } from 'react'
import { View, StyleSheet, TouchableWithoutFeedback } from 'react-native'
import assign from 'object-assign';
import PropTypes from 'prop-types';

在类中规定属性类型

代码语言:javascript
复制
 static propTypes = {
        numberOfPages: PropTypes.number.isRequired,
        currentPage: PropTypes.number,
        hidesForSinglePage: PropTypes.bool,
        pageIndicatorTintColor: PropTypes.string,
        currentPageIndicatorTintColor: PropTypes.string,
        indicatorSize: PropTypes.object,
        indicatorStyle: View.propTypes.style,
        currentIndicatorStyle: View.propTypes.style,
        onPageIndicatorPress: PropTypes.func
    }

给属性设置为默认值

代码语言:javascript
复制
static defaultProps = {
        numberOfPages: 0,
        currentPage: 0,
        hidesForSinglePage: false,
        pageIndicatorTintColor: 'gray',
        currentPageIndicatorTintColor: 'white',
        indicatorSize: { width: 8, height: 8 },
        indicatorStyle: {},
        currentIndicatorStyle: {},
        onPageIndicatorPress: function () { }
    }

实现方法

代码语言:javascript
复制
 onPageIndicatorPress(index) {
        this.props.onPageIndicatorPress(index);
    }

实现render方法

代码语言:javascript
复制
render() {
//解构赋值,取出所有的属性
        var { style, ...props } = this.props;
//给指示器设置默认的属性,备用
        var defaultStyle = {
            height: this.props.indicatorSize.height
        };
//设置每个小点的样式
        var indicatorItemStyle = {
            width: this.props.indicatorSize.width,
            height: this.props.indicatorSize.height,
            borderRadius: this.props.indicatorSize.height / 2,
            marginLeft: 5,
            marginRight: 5
        };
//指示器整体样式
        var indicatorStyle = assign({}, indicatorItemStyle, this.props.indicatorStyle, {
            backgroundColor: this.props.pageIndicatorTintColor
        });
//选中指示器的样式
        var currentIndicatorStyle = assign({}, indicatorItemStyle, this.props.currentIndicatorStyle, {
            backgroundColor: this.props.currentPageIndicatorTintColor
        });
//创建一个数组,将小点添加到pages里面。
        var pages = [];
        for (var i = 0; i < this.props.numberOfPages; i++) {
            pages.push(i);
        }
     //页面隐藏设置为真并且页面长度<=1时,返回null,否则返回一个个的小点。
        return (
            this.props.hidesForSinglePage && pages.length <= 1 ? null : <View style={[styles.container, defaultStyle, style]}>
            
 {/*从小点的集合中取出每个点,如果是当前的点就返回当前点样式,否则返回普通样式*/}
                {pages.map((el, i) => <TouchableWithoutFeedback key={i} onPress={this.onPageIndicatorPress.bind(this, i)}>
                        <View style={i == this.props.currentPage ? currentIndicatorStyle : indicatorStyle} />
                    </TouchableWithoutFeedback>
                )}
            </View>
        )
    }

现在可以做封装HomeMenuView的操作了 先把render函数要返回的东西梳理清楚

代码语言:javascript
复制
return (
 
  //scrollView里面要包含多个Item。将数组menuView添加到view里面
            <View style={styles.container}>
                <ScrollView contentContainerStyle={styles.contentContainer}
                    horizontal
                    showsHorizontalScrollIndicator={false}
                    pagingEnabled
                    onScroll={(e) => this.onScroll(e)}
                >
                    <View style={styles.menuContainer}>
                        {menuViews}
                    </View>
                </ScrollView>


                <PageControl
                    style={styles.pageControl}
                    numberOfPages={pageCount}
                    currentPage={this.state.currentPage}
                    hidesForSinglePage
                    pageIndicatorTintColor='gray'
                    currentPageIndicatorTintColor={color.theme}
                    indicatorSize={{ width: 8, height: 8 }}
                />
            </View>
        );

scrollview中包含的是menuView,也就是每个设置好样式的items。 在render方法的return方法之前,创建一个数组,该数组用来存放每个item。

代码语言:javascript
复制
render() {
        //取出属性中的menuinfos和onMenuSelected
        let { menuInfos, onMenuSelected } = this.props
        // 将属性传给每个HomeMenuitem
        let menuItems = menuInfos.map(
            (info, i) => (
                <HomeMenuItem
                    key={info.title}
                    title={info.title}
                    icon={info.icon}
                    onPress={() => {
                        onMenuSelected && onMenuSelected(i)
                    }} />
            )
        )
        //创建一个menuViews数组,用来表示每一页
        let menuViews = []
        //像上取整得到页数
        let pageCount = Math.ceil(menuItems.length / 10)

        for (let i = 0; i < pageCount; i++) {
            //slice() 方法可从已有的数组中返回选定的元素。start和end,表示一页放十个
            let items = menuItems.slice(i * 10, i * 10 + 10)
            // 一整页的
            let menuView = (
                <View style={styles.itemsView} key={i}>
                    {items}
                </View>
            )
            //加入到所有页面的数组
            menuViews.push(menuView)
        }
        //此处是省略的return 在上面已经写了
        }

上面return方法中要返回的PageControl要将currentPage传入进去,所以在MenuView应该先有一个状态机以便在用户滚动页面的时候实施修改。

代码语言:javascript
复制
 state: {
        currentPage: number
    }

    constructor(props) {
        super(props)

        this.state = {
            currentPage: 0
        }
    }

实现滚动的方法

代码语言:javascript
复制
onScroll(e) {
            //拿到x的偏移量
        let x = e.nativeEvent.contentOffset.x
              //用偏移量/宽度得到当前页数
        let currentPage = Math.round(x / screen.width)

        console.log('onScroll  ' + e.nativeEvent.contentOffset.x + '  page ' + currentPage + '  current ' + this.state.currentPage)
        if (this.state.currentPage != currentPage) {
                    //改变状态机

            this.setState({
                currentPage: currentPage
            })
        }
    }

设置样式

代码语言:javascript
复制
const styles = StyleSheet.create({
    container: {
        backgroundColor: 'white',
    },
    contentContainer: {
    },
    menuContainer: {
        flexDirection: 'row',
    },
    itemsView: {
        flexDirection: 'row',
        flexWrap: 'wrap',
        width: screen.width,
    },
    pageControl: {
        margin: 10,
    }
});
  • 到首页中修改readerHeader方法 引入头文件
代码语言:javascript
复制
import HomeMenuView from './HomeMenuView'

将HomeMenuView添加到方法中去

代码语言:javascript
复制
renderHeader() {
        return (
            <View>
                <HomeMenuView menuInfos={api.menuInfo} onMenuSelected={this.onMenuSelected} />
                <SpacingView />
                <View style={styles.recommendHeader}>
                    <Heading2>猜你喜欢</Heading2>
                </View>
            </View>
        )
    }

设置样式

代码语言:javascript
复制
recommendHeader: {
        height: 35,
        justifyContent: 'center',
        borderWidth: screen.onePixel,
        borderColor: color.border,
        paddingVertical: 8,
        paddingLeft: 20,
        backgroundColor: 'white'
    },

接下来封装头部的第二部分 原理同第一部分类似,建立第二个部分的js文件HomeGridView和第二部分的每一小项HomeGridItem。

HomeGridItem:

代码语言:javascript
复制
export default class HomeGridItem extends PureComponent {
    render() {
        let info = this.props.info

        let title = info.maintitle
        let color = info.typeface_color
        let subtitle = info.deputytitle
        let imageUrl = info.imageurl.replace('w.h', '120.0')

        return (
            <TouchableOpacity style={styles.container} onPress={this.props.onPress}>
                <View>
                    <Heading1 style={{ color: color, marginBottom: 10 }}>{title}</Heading1>
                    <Heading2 >{subtitle}</Heading2>
                </View>

                <Image style={styles.icon} source={{ uri: imageUrl }} />
            </TouchableOpacity>
        );
    }
}

// define your styles
const styles = StyleSheet.create({
    container: {
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
        width: screen.width / 2 - screen.onePixel,  //一行放两个,减去一个像素点
        height: screen.width / 4,
        backgroundColor: 'white',
        borderBottomWidth: screen.onePixel,
        borderRightWidth: screen.onePixel,
        borderColor: color.border
    },
    icon: {
        width: screen.width / 5,
        height: screen.width / 5,
    }
});

HomeGridView:

代码语言:javascript
复制
import React, { PureComponent } from 'react';
import { View, Text, StyleSheet } from 'react-native'
import color  from '../../widget/color'
import  screen from '../../common/screen'
import HomeGridItem from './HomeGridItem'

export default class HomeGridView extends PureComponent {
    //设定一个数组,用来接收数据
    static defaultProps = {
        infos: []
    }

    render() {
        return (
            <View style={styles.container}>
            //将infos赋值给Item
                {this.props.infos.map((info, index) => (
                    <HomeGridItem
                        info={info}
                        key={index}
                        onPress={() => this.props.onGridSelected(index)} />
                ))}
            </View>
        );
    }
}

// define your styles
const styles = StyleSheet.create({
    container: {
        flexDirection: 'row',
        flexWrap: 'wrap',
        justifyContent: 'space-between',
        borderTopWidth: screen.onePixel,
        borderLeftWidth: screen.onePixel,
        borderColor: color.border
    },
});

在HomeScene中 引入头文件

代码语言:javascript
复制
import HomeGridView from './HomeGridView'

修改renderHeader方法,将gridView加入进去

代码语言:javascript
复制
<HomeGridView infos={this.state.discounts} onGridSelected={(this.onGridSelected)} />
 <SpacingView />

到构造函数中绑定onGridSelected和onMenuSelected

代码语言:javascript
复制
 { this.onGridSelected = this.onGridSelected.bind(this) }
        { this.onMenuSelected = this.onMenuSelected.bind(this) }

将这两个方法的原型写出来

代码语言:javascript
复制
onGridSelected(index) {

    }
    onMenuSelected(index) {
        alert(index)
    }

首页第一个界面完成,其余的页面放在之后讲解。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.05.25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、微组件的封装
  • 二、首页封装
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档