時間:2023-06-02 11:00:01 | 來源:網站運營
時間:2023-06-02 11:00:01 來源:網站運營
通過React16.8構建新聞網站第三章:新聞主頁的構建:import React, { useState, useEffect } from 'react';import {Row, Col} from 'antd';//新聞列表組件import IndexTab from './IndexTab/index';//主頁左邊內容 輪播圖和新聞圖文列表import IndexLeft from './IndexLeft/index'//主頁底部新聞列表import IndexBottom from './IndexBottom/index';//主頁右側新聞列表import IndexRight from './IndexRight/index';import './index.scss';const Index = props => { return ( <div className='index'> <Row> <Col span={2}/> <Col span={21}> <Row className='top_news'> <Col span={8}> <div className='top_left top'> <IndexLeft /> </div> </Col> <Col span={7}> <div className='top_center top'> <IndexTab /> </div> </Col> <Col span={6}> <div className='top_right top'> <IndexRight /> </div> </Col> </Row> <Row> <div className='bottom'> <IndexBottom /> </div> </Row> </Col> <Col span={4}/> </Row> </div> );}export default Index;
這里我通過ANT Design的柵格布局將頁面劃分成四個部分 每個部分引入對應的組件var Tools = { // fetch接口封裝 api: function({ url, args='', callback }) { let argsStr = ''; if(args!='') { for(let key in args) { argsStr += key + '=' + args[key] + '&'; } argsStr = '?' + argsStr.substr(0, argsStr.length-1); } fetch(url+argsStr) .then(response => response.json()) .then(res => { callback(res); }); }, /** * zyx * 2019/10.22 * 時間戳轉時間‘YYYY-MM-DD HH:mm:ss’ */ time : function(time){ //從數(shù)據(jù)庫拿出來的時間戳是字符串形式 需要轉化為數(shù)字 time = parseInt(time); // 增加8小時 let date = new Date(time + 8 * 3600 * 1000); return date.toJSON().substr(0, 19).replace('T', ' '); //Date的‘toJSON’方法返回格林威治時間的JSON格式字符串,實際是使用‘toISOString’方法的結果。 //字符串形如‘2018-08-09T10:20:54.396Z’,轉化為杭州時間需要額外增加八個時區(qū), //我們需要取字符串前19位,然后把‘T’替換為空格,即是我們需要的時間格式。 }}export const api = Tools.api.bind(Tools);//host 請求地址export const host = 'http://xxx.xx.xx.xxx/tp5/public/index.php/index/index/';export const time = Tools.time.bind(Tools);
這里我們主要使用封裝好的fetch請求和暴露出來的hostimport React, { useState, useEffect } from 'react';import {Card} from 'antd';import {Link} from 'react-router-dom';//引入封裝的fetch方法和host地址import {api,host} from '../../until';import './index.scss';const ImgBlockTypeOne = props => { //定義需要渲染使用state const [news,setNews] = useState(''); //組件加載時調用 相當于componentDidMount useEffect(()=>{ //動態(tài)獲取數(shù)據(jù) 根據(jù)傳入得type type不同拿到的數(shù)據(jù)類型不同 let wenzhangType = props.type; /** * zyx * 2020/6/9 * 拿到數(shù)據(jù) */ api({ url:host + 'newsSelectContentByType', args: { type:1, wenzhangType, }, callback: (res) => { showData(res); } }); },[]) /** * zyx * 2020/6/9 * 數(shù)據(jù)處理函數(shù) */ const showData = (data)=>{ let listData = []; for (let i = 0; i < props.count; i++) { let img = JSON.parse(data[i].img); listData.push({ uniquekey: data[i].id, thumbnail_pic_s: img[0], title: data[i].title, author_name: data[i].name, }); } //調用news的change方法 setNews(listData) } //根據(jù)數(shù)據(jù)渲染方法 //根據(jù)傳入的componentType來渲染不同的樣式 //同時布局采用的flex布局 具體樣式通過props傳遞 判斷是橫向的排列還是縱向排列 const newsImage = ()=>{ if(news.length){ let newsList = ''; if(props.componentType == 1){ newsList=news.map((newsItem, index) => ( <div key={index} className='image_news_item' style={{width:props.imageWidth}}> <Link to={`details/${newsItem.uniquekey}`} target='_blank'> <img alt="newsItem.title" src={newsItem.thumbnail_pic_s} width={props.imageWidth}/> <h3>{newsItem.title}</h3> <p>{newsItem.author_name}</p> </Link> </div> )); }else if (props.componentType == 2){ newsList=news.map((newsItem,index)=>( <Link to={`details/${newsItem.uniquekey}`} target='_blank' key={index}> <section className='imageSingle_sec' style={{width:props.width}}> <div className='imageSingle_left' style={{width:props.ImageWidth}}> <img style={{width:props.ImageWidth}} src={newsItem.thumbnail_pic_s} alt={newsItem.title}/> </div> <div className='imageSingle_right'> <p>{newsItem.title}</p> <span className='realType' >{newsItem.realtype}</span> <span>{newsItem.author_name}</span> </div> </section> </Link> )); } return( <Card className={props.componentType == '2' ? 'imageSingleCard':'image_card'} title={props.cartTitle} bordered={true} style={{width:props.width,marginTop:'10px'}}> <div className='image_news_container' style={{width:props.width,justifyContent:props.justifyContent}}> {newsList} </div> </Card> ) }else{ //判斷數(shù)據(jù)是否為空 如果為空 直接渲染一個正在加載 return '正在加載' } } return ( <div className='pc_news_imgblock'> {/* 調用處理好的模塊*/} {newsImage()} </div> )}export default ImgBlockTypeOne;
import React, { useState, useEffect } from 'react';import {Carousel} from 'antd';import ImgBlockTypeOne from '../../component/ImgBlockTypeOne/index';const IndexLeft = props => { return ( <div> <Carousel autoplay> <div><img src="https://zyx-news.oss-cn-hangzhou.aliyuncs.com/news1.jpg"/></div> <div><img src="https://zyx-news.oss-cn-hangzhou.aliyuncs.com/news2.jpg"/></div> <div><img src="https://zyx-news.oss-cn-hangzhou.aliyuncs.com/news3.jpg"/></div> <div><img src="https://zyx-news.oss-cn-hangzhou.aliyuncs.com/news4.jpg"/></div> </Carousel> <ImgBlockTypeOne count={10} type='4' width='100%' imageWidth='112px' cartTitle='美國大暴動' justifyContent='space-around' componentType='1'/> </div> )}export default IndexLeft;
import React, { useState, useEffect } from 'react';import {Tabs} from 'antd';import {Link} from 'react-router-dom';import {host,api} from '../../until';const { TabPane } = Tabs;const IndexTab = props => { const callback = (key)=>{ console.log(key); } //定義渲染需要使用的數(shù)據(jù) const [news,setNews] =useState([]); //組件加載時調用 相當于componsetNewsentDidMount useEffect(()=>{ //動態(tài)獲取數(shù)據(jù) 根據(jù)傳入得type let wenzhangType = props.type; /** * zyx * 2020/6/19 * 拿到數(shù)據(jù) */ api({ url:host + 'newsSelectContentByType', args: { type:1, }, callback: (res) => { showData(res); } }); },[]) /** * zyx * 2020/6/9 * 數(shù)據(jù)處理函數(shù) */ const showData = (data)=>{ let listData = []; for (let i = 0; i < data.length; i++) { let img = JSON.parse(data[i].img); listData.push({ uniquekey: data[i].id, title: data[i].title, }); } //調用news的change方法 setNews(listData) } const List = ()=>{ // 將對應的新聞數(shù)據(jù)渲染成li列表 let newsList=news.map((newsItem, index) => ( <li key={index}> <Link to={`details/${newsItem.uniquekey}`} target='_blank'> {newsItem.title} </Link> </li> )); return( <ul> {newsList} </ul> ) } return ( <div> <Tabs defaultActiveKey="1" onChange={callback}> <TabPane tab="熱點文章" key="1"> <List /> </TabPane> <TabPane tab="熱點帖子" key="2"> <List /> </TabPane> <TabPane tab="國際新聞" key="3"> <List /> </TabPane> <TabPane tab="國內新聞" key="4"> <List /> </TabPane> </Tabs> </div> )}export default IndexTab;
import React, { useState, useEffect } from 'react';import ImgBlockTypeOne from '../../component/ImgBlockTypeOne/index';const IndexRight = props => { return ( <div> <ImgBlockTypeOne width='100%' ImageWidth='100px' type='3' count={5} cartTitle='海賊王' componentType='2'/> </div> )}export default IndexRight;
7IndexBottom import React, { useState, useEffect } from 'react';import ImgBlockTypeOne from '../../component/ImgBlockTypeOne/index';const IndexBottom = props => { return ( <div> <ImgBlockTypeOne count={12} type='2' width='100%' imageWidth='112px' cartTitle='R.I.P Kobe' justifyContent='space-start' componentType='1'/> </div> )}export default IndexBottom;
一個主頁抽離這么多模塊主要是為了將數(shù)據(jù)處理和頁面渲染分開,降低項目耦合關鍵詞:新聞,通過