react入門-React + webpack 開發(fā)單頁面應(yīng)用(react快速上手教程)

2018.09.26終---2019.11.10更---
注意:在現(xiàn)今前端的日常開發(fā)中需要nodejs+npm環(huán)境和基本的計(jì)算機(jī)知識(如命令行)糠雨。詳情參考:nodejsLinux命令大全钩述。不知道的請先去學(xué)會署惯,不然下面的內(nèi)容有可能不適合你篇裁。會使用shell的高手,請直接去博文最低下的附件3勇凭。

一煌茴、創(chuàng)建項(xiàng)目、安裝基本第三方庫以及配置所需目錄

1.1 創(chuàng)建項(xiàng)目
sudo npm i -g create-react-app # npm下安裝react環(huán)境
create-react-app react-demo # 創(chuàng)建一個(gè)項(xiàng)目名為react-demo的react項(xiàng)目
cd react-demo # 進(jìn)入此項(xiàng)目
npm start # 運(yùn)行項(xiàng)目(項(xiàng)目運(yùn)行后双妨,查看項(xiàng)目文件和運(yùn)行結(jié)果淮阐,查看完畢后,再進(jìn)行下面操作)
1.2 自定義配置模式
npm run eject # 此時(shí)默認(rèn)的項(xiàng)目結(jié)構(gòu)會發(fā)生較大變化刁品,注意觀察前后變化
1.3 安裝一些基本的第三方庫
npm i react-router-dom   # react 路由器的DOM綁定(必安裝)
npm i node-sass sass-loader axios es6-promise    # 使用sass和axios請求方式(根據(jù)個(gè)人情況決定是否安裝泣特,本人使用sass和axios)
1.4 配置所需目錄

不會shell的,可以手動配置目錄為以下結(jié)構(gòu):(主要配置public和src其他默認(rèn)就好)

├── config                          # 配置文件夾
├── node_modules                    # node 依賴文件夾
  ├── ...                           # 各種npm的js庫
├── public                          # 靜態(tài)資源目錄挑随、入口文件目錄
  ├── image                         # 靜態(tài)圖片存放
  ├── js                            # 本地js第三方庫
  ├── favicon.ico                   # 瀏覽器標(biāo)簽欄圖標(biāo)
  ├── index.html                    # 入口 index.html 文件
  ├── manifest.json                 # 配置參數(shù)
├── scripts                         # npm 腳本文件夾
  ├── ...                           # 默認(rèn)
├── src                             # 開發(fā)目錄
  ├── api                           # 請求
    ├── index.js                    # 請求的js
  ├── components                    # 組件
  ├── config                        # 配置
    ├── index.js                    # 配置的js
  ├── router                        # 路由
    ├── index.js                    # 路由配置入口js
  ├── style                         # 樣式
    ├── index.scss                  # css樣式主文件
  ├── tools                         # 自定義js工具包
    ├── index.js                    # 自定義的js方法
  ├── views                         # 單頁面應(yīng)用
    ├── home.jsx                    # 首頁jsx組件
  ├── App.js                        # dom 掛載文件
  ├── index.js                      # 入口文件
  ├── App.test.js                   # 測試文件
  ├── serviceWorker.js              # 注冊服務(wù)文件状您,舊版本是registerServiceWorker.js
  ├── setupProxy.js                 # 配置代理
├── package-lock.json               # 包鎖定文件,不用管兜挨。
├── package.json                    # 配置文件膏孟,有些內(nèi)容在此配置
└──README.md                        # 說明文檔,該文檔非常豐富拌汇,建議由時(shí)間閱讀

會shell的可以執(zhí)行我的快捷命令柒桑,不會的請按照上面的自行手動構(gòu)建:

# react-src-catalog-building.sh
# 新建文件 react-src-catalog-building.sh,內(nèi)容如下:(以下內(nèi)容可以通過命令行執(zhí)行)
cd src && mkdir api components config views router style tools # 在src下噪舀,創(chuàng)建我們需要的文件夾
rm -r App.css index.css logo.svg # 刪除App.css App.test.js index.css logo.svg等無用文件
cd api && touch index.js && cd ../ # api => index.js
cd config && touch index.js && cd ../ # config => index.js
cd router && touch index.js && cd ../ # router => index.js
cd style && touch index.scss && cd ../ # style => index.scss
cd tools && touch index.js && cd ../ # tools => indext.js
cd views && touch home.jsx && cd ../ # views => home.jsx
touch setupProxy.js
cd ../
# 運(yùn)行shell文件 react-src-catalog-building
sh react-src-catalog-building.sh # 如果是通過命令行執(zhí)行上面內(nèi)容魁淳,則不需要執(zhí)行該命令

二飘诗、配置config相關(guān)

2.1 配置支持 @ 文件映射 src 目錄

在根目錄下的/config/webpack.config.js 文件中,找到 alias 的配置:

注意:舊版是/config/webpack.config.dev.js 文件和 /config/webpack.config.prod.js 文件中界逛,找到 alias 的配置

alias: {
  ...
  '@': path.join(__dirname, '..', 'src'), // 添加這段內(nèi)容
}
2.2 配置項(xiàng)目支持 scss 文件

新版你可以跳過這一步昆稿,因?yàn)樗约阂呀?jīng)做了scss的支持

在根目錄下的 /config/webpack.config.dev.js 文件和 /config/webpack.config.prod.js 文件中,找到 module 的配置

module: {
  strictExportPresence: true,
  rules: [
    { test: /\.scss$/, loaders: ['style-loader', 'css-loader', 'sass-loader'],},    // 再rules這個(gè)數(shù)組中第一個(gè)位置,添加這段內(nèi)容
    ...
    {
      // "oneOf" will traverse all following loaders until one will
      // match the requirements. When no loader matches it will fall
      // back to the "file" loader at the end of the loader list.
      oneOf: [
        ...
        {
          exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],   # 改為 exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/, /.scss$/], // 增加 /.scss$/ 來使其支持sass
          loader: require.resolve('file-loader'),
          options: {
            name: 'static/media/[name].[hash:8].[ext]',
          },
        },
      ]
    }
  ],
  ...
}

三息拜、配置src下各個(gè)文件

3.1 配置 src/index.js 文件
import React from 'react'
import ReactDOM from 'react-dom'
import './style/index.scss'
import App from './App.js'
import * as serviceWorker from './serviceWorker' // 注意:新版本此處與舊版不一致溉潭,以新版為主;舊版import registerServiceWorker from './registerServiceWorker'

ReactDOM.render(<App />, document.getElementById('root'))

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister() // 注意:新版本此處與舊版不一致少欺,以新版為主岛抄;舊版registerServiceWorker()
3.2 配置 src/App.js 文件
import React, { Component } from 'react'
import RouterView from './router/index.js'

class App extends Component {
  render() {
    return (
      <RouterView></RouterView>
    )
  }
}

export default App
3.3配置 src/views/home.jsx 文件
import React, { Component } from 'react'

export default class Home extends Component {
  constructor (props) {
    super(props)
    this.state = {}
  }

  componentDidMount () {
  }

  render () {
    return (
      <div className="home">
        Home-首頁
      </div>
    )
  }
}
3.4 配置 src/router/index.js 文件
import React, { Component } from 'react'
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'

import Home from '@/views/home.jsx'

export default class App extends Component {
  render () {
    return (
      <Router basename="/">
        <Switch>
          <Route exact path='/' component={Home} />
        </Switch>
      </Router>
    )
  }
}
3.5 配置 src/style/index.scss 文件
// $static: "/erjimulu/image/"; // 打包時(shí)用此路徑
$static: "/image/"; // 本地路徑

body {
  margin: 0; padding: 0; font-family: sans-serif; font-size: 12px;
}
3.6配置src/config/index.js 文件
export default {
  projectName: '項(xiàng)目名稱', // 項(xiàng)目名稱
  title: '項(xiàng)目title',
  /**
   * @description api請求基礎(chǔ)路徑
   */
  baseUrl: {
    dev: '/api/v1', // 開發(fā)環(huán)境前綴
    pro: '/api/v1' // 生產(chǎn)環(huán)境前綴
  },
  /**
   * @description 是否自行存儲token
   */
  isSaveCookie: true,
  /**
   * @description token在Cookie中存儲的天數(shù),默認(rèn)1天
   */
  cookieExpires: 1,
  /**
   * @description 是否使用國際化狈茉,默認(rèn)為false
   * 如果不使用,則需要在路由中給需要在菜單中展示的路由設(shè)置 meta: {title: 'xxx'} 用來在菜單中顯示文字
   */
  useI18n: false,
  /**
   * @description 默認(rèn)打開的首頁的路由name值掸掸,默認(rèn)為home
   */
  homeName: 'home',
  // ...
  // 其他
}

四氯庆、配置接口請求相關(guān)

4.1 配置請求代理

請求 cnodejs.org 提供的公用接口。接口文檔查看扰付,請點(diǎn)擊 https://cnodejs.org/api堤撵。

相關(guān)參考這里:Proxying API Requests in Development新版react16.6中 create-react-app升級版(webpack4.0) 配置http請求跨域問題

1)安裝http-proxy-middleware管理包:http-proxy-middleware

npm install http-proxy-middleware --save
# or
yarn add http-proxy-middleware

2)在src/setupProxy.js文件羽莺,然后寫入如下代碼:

const proxy = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(proxy('/api/v1', {
    target: 'https://cnodejs.org',
    changeOrigin: true
  }));
};

注意:配置了代理之后实昨,項(xiàng)目需要重啟,才能生效 npm start

4.2 配置 src/api/index.js 文件
// 全局請求插件 Axios
import Config from '@/config'
import Axios from 'axios' // 全局請求插件 Axios

var Promise = require('es6-promise').Promise
var axios = Axios.create() // 實(shí)例化

const baseUrl = process.env.NODE_ENV === 'development' ? Config.baseUrl.dev : Config.baseUrl.pro
axios.defaults.baseURL = baseUrl // 接口請求前綴
axios.defaults.withCredentials = true // 是否跨域
axios.defaults.responseType = 'json' // json

// 設(shè)置默認(rèn)請求頭
// axios.defaults.headers = {
//   "Content-Type": "application/json"
// }

// `transformResponse` 在請求完成后響應(yīng)傳遞給 then/catch 前盐固,允許修改響應(yīng)數(shù)據(jù)荒给,函數(shù)必須return,function (data) { return data }
// axios.defaults.transformResponse = [(data) => {
//   return data
// }]

// 添加響應(yīng)攔截器
axios.interceptors.response.use(function (response) { // 請求成功的回調(diào)
  return Promise.resolve(response.data)
}, function (error) { // 請求失敗的回調(diào)
  return Promise.reject(error)
})

axios.original = Axios // 接口請求前綴不一致時(shí)的預(yù)留

export default axios
4.3 測試 src/api/index.js 是否正常,配置 src/views/home.jsx 文件
import React, { Component } from 'react'
import { Link } from 'react-router-dom' // 路由相關(guān) props.match 等
import Axios from '@/api/index.js'

export default class Home extends Component {
  constructor (props) {
    super(props) // this.props 用來接收父組件的傳值 子組件給父組件傳值:父組件把操作 state 的方法刁卜,通過屬性的形式傳遞給子組件志电,子組件調(diào)用該操作方法
    this.state = {
      list: []
    } // 局部狀態(tài)
  }

  // React 生命周期--------------------------------------------------------------
  componentDidMount () { // 掛載周期
    this.getTopics()
  }

  componentWillUnmount () { // 卸載周期
  }
  // React 生命周期--------------------------------------------------------------

  // 自定義方法-------------------------------------------------------------------
  getTopics () {
    return new Promise((resolve, reject) => {
      Axios({ method: 'get', url: 'topics', params: {} }).then((response) => {
        console.log(response)
        this.setState({list: response.data}) // 構(gòu)造函數(shù) setState 更新組件局部狀態(tài)
        // this.setState((prevState, props) => { // 接收先前的狀態(tài)作為第一個(gè)參數(shù),將此次更新被應(yīng)用時(shí)的props做為第二個(gè)參數(shù)
        //   return {
        //     ...
        //   }
        // }) // 函數(shù)形式
        resolve()
      }).catch((error) => {
        console.log(error)
        reject()
      })
    })
  }
  // 自定義方法-------------------------------------------------------------------

  render () { // render 函數(shù)蛔趴,渲染 dom 結(jié)構(gòu)
    console.log(this)
    let { list } = this.state
    let dom = null

    if (list.length !== 0) {
      let listDom = list.map((item, index, array) => {
        // console.log(item, index, array)
        return (
          <li key={index}><Link to={`/details/${item.id}`}> {index + 1} - {item.title} </Link></li>
        )
      })
      dom = (<div className='tipics-list'> <ul>{listDom}</ul> </div>)
    }
    return (
      <div className="home">
      首頁 {dom}
      </div>
    )
  }
}

重新 npm start 運(yùn)行后:

運(yùn)行最終結(jié)果

至此一個(gè)基本的react項(xiàng)目已經(jīng)搭建完畢挑辆,入門工作已經(jīng)完成,接下來需要的就是學(xué)習(xí)react的語法了孝情。請參考:react 中文文檔

附1. 自定義的搭建react的快捷腳本

https://github.com/nongshuqiner/react-building-project-shell

附2.atom 相關(guān) react 的第三方包的安裝

注意:本人使用的是 atom 編輯器鱼蝉,開發(fā) react 需要安裝一些插件,這里做了一個(gè)shell簡化你的插件安裝箫荡,如果你是其他編輯器請?zhí)^這部分魁亦。

新建文件 atom-react-package.sh,內(nèi)容如下:

# atom安裝插件: 找到atom包存放根路徑(例如: Mac下是 cd ~/.atom/packages)菲茬,git clone XXX 某個(gè)包后吉挣,cd XXX 進(jìn)入包派撕,然后npm install安裝,cd ../ || echo "Error: atom 的 ${PWD##*/} 包睬魂,安裝失敗" 回到 atom 包存放的根路徑

unameOut="$(uname -s)"
case "${unameOut}" in
    Linux*)     machine=Linux;;
    Darwin*)    machine=Mac;;
    CYGWIN*)    machine=Cygwin;;
    MINGW*)     machine=MinGw;;
    *)          machine="UNKNOWN:${unameOut}"
esac
echo ${machine}

if [ ${machine} == "Linux" ]; then # Linux
  atomPackagesPath="$HOME/.atom/packages"
elif [ ${machine} == "Mac" ]; then # Mac
  atomPackagesPath="$HOME/.atom/packages"
else
  atomPackagesPath="$HOME/.atom/packages"
fi

echo ${atomPackagesPath}
echo "------------------------------------------------------------------"

cd $atomPackagesPath && ls || echo "Error: ${atomPackagesPath} 沒有找到那個(gè)文件或目錄"
echo "------------------------------------------------------------------"


# React 相關(guān) atom 包

# atom-react-autocomplete:自動完成組件名稱和Project類型终吼,用于項(xiàng)目中使用的任何組件
echo "安裝 'atom-react-autocomplete' ..."
echo "git clone https://github.com/DavidWells/atom-react-autocomplete"
git clone https://github.com/DavidWells/atom-react-autocomplete
cd atom-react-autocomplete
npm install
echo "Success: atom 的 ${PWD##*/} 包,安裝成功" && cd ../ || echo "Error: atom 的 ${PWD##*/} 包氯哮,安裝失敗"
echo "------------------------------------------------------------------"

# autocomplete-js-import: JS導(dǎo)入語句的自動完成+提供程序
echo "安裝 'autocomplete-js-import' ..."
echo "git clone https://github.com/DanielGarcia-Carrillo/autocomplete-js-import"
git clone https://github.com/DanielGarcia-Carrillo/autocomplete-js-import
cd autocomplete-js-import
npm install
echo "Success: atom 的 ${PWD##*/} 包际跪,安裝成功" && cd ../ || echo "Error: atom 的 ${PWD##*/} 包,安裝失敗"
echo "------------------------------------------------------------------"

# language-babel: atom內(nèi)開發(fā)react的核心插件
echo "安裝 'language-babel' ..."
echo "git clone https://github.com/gandm/language-babel"
git clone https://github.com/gandm/language-babel
cd language-babel
npm install
echo "Success: atom 的 ${PWD##*/} 包喉钢,安裝成功" && cd ../ || echo "Error: atom 的 ${PWD##*/} 包姆打,安裝失敗"
echo "------------------------------------------------------------------"

# emmet-jsx-css-modules: React內(nèi)的Emmet補(bǔ)全
echo "安裝 'emmet-jsx-css-modules' ..."
echo "git clone https://github.com/ambethia/emmet-jsx-css-modules"
git clone https://github.com/ambethia/emmet-jsx-css-modules
cd emmet-jsx-css-modules
npm install
echo "Success: atom 的 ${PWD##*/} 包,安裝成功" && cd ../ || echo "Error: atom 的 ${PWD##*/} 包肠虽,安裝失敗"
echo "------------------------------------------------------------------"

# language-javascript-jsx: JavaScript, ES6, ES7, React JSX, Flow支持
echo "安裝 'language-javascript-jsx' ..."
echo "git clone https://github.com/subtleGradient/language-javascript-jsx"
git clone https://github.com/subtleGradient/language-javascript-jsx
cd language-javascript-jsx
npm install
echo "Success: atom 的 ${PWD##*/} 包幔戏,安裝成功" && cd ../ || echo "Error: atom 的 ${PWD##*/} 包,安裝失敗"
echo "------------------------------------------------------------------"

# atom-react-snippets:atom的react代碼片段補(bǔ)齊
echo "安裝 'atom-react-snippets' ..."
echo "git clone https://github.com/webbushka/atom-react-snippets"
git clone https://github.com/webbushka/atom-react-snippets
cd atom-react-snippets
npm install
echo "Success: atom 的 ${PWD##*/} 包税课,安裝成功" && cd ../ || echo "Error: atom 的 ${PWD##*/} 包闲延,安裝失敗"
echo "------------------------------------------------------------------"

打開控制臺執(zhí)行(任何目錄下執(zhí)行都可以)

sh atom-react-package.sh # 注意:不支持window

附3.react 生命周期圖

react-生命周期.jpg

結(jié)語

提示:后面還有精彩敬請期待,請大家關(guān)注我的專題:web前端韩玩。如有意見可以進(jìn)行評論垒玲,每一條評論我都會認(rèn)真對待。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末找颓,一起剝皮案震驚了整個(gè)濱河市合愈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌击狮,老刑警劉巖佛析,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異帘不,居然都是意外死亡说莫,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門寞焙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來储狭,“玉大人,你說我怎么就攤上這事捣郊×杀罚” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵呛牲,是天一觀的道長刮萌。 經(jīng)常有香客問我,道長娘扩,這世上最難降的妖魔是什么着茸? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任壮锻,我火速辦了婚禮,結(jié)果婚禮上涮阔,老公的妹妹穿的比我還像新娘猜绣。我一直安慰自己,他們只是感情好敬特,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布掰邢。 她就那樣靜靜地躺著,像睡著了一般伟阔。 火紅的嫁衣襯著肌膚如雪辣之。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天皱炉,我揣著相機(jī)與錄音怀估,去河邊找鬼。 笑死合搅,一個(gè)胖子當(dāng)著我的面吹牛奏夫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播历筝,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼廊谓!你這毒婦竟也來了梳猪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤蒸痹,失蹤者是張志新(化名)和其女友劉穎春弥,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叠荠,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡匿沛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了榛鼎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逃呼。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖者娱,靈堂內(nèi)的尸體忽然破棺而出抡笼,到底是詐尸還是另有隱情,我是刑警寧澤黄鳍,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布推姻,位于F島的核電站,受9級特大地震影響框沟,放射性物質(zhì)發(fā)生泄漏藏古。R本人自食惡果不足惜增炭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拧晕。 院中可真熱鬧隙姿,春花似錦、人聲如沸防症。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蔫敲。三九已至饲嗽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間奈嘿,已是汗流浹背貌虾。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留裙犹,地道東北人尽狠。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像叶圃,于是被迫代替她去往敵國和親袄膏。 傳聞我的和親對象是個(gè)殘疾皇子庐杨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1 Webpack 1.1 概念簡介 1.1.1 WebPack是什么 1藤韵、一個(gè)打包工具 2、一個(gè)模塊加載工具 3...
    Kevin_Junbaozi閱讀 6,659評論 0 16
  • 版權(quán)聲明:本文為博主原創(chuàng)文章眉厨,未經(jīng)博主允許不得轉(zhuǎn)載锌奴。 webpack介紹和使用 一、webpack介紹 1憾股、由來 ...
    it筱竹閱讀 11,120評論 0 21
  • GitChat技術(shù)雜談 前言 本文較長鹿蜀,為了節(jié)省你的閱讀時(shí)間,在文前列寫作思路如下: 什么是 webpack服球,它要...
    蕭玄辭閱讀 12,691評論 7 110
  • 目錄第1章 webpack簡介 11.1 webpack是什么耻姥? 11.2 官網(wǎng)地址 21.3 為什么使用 web...
    lemonzoey閱讀 1,735評論 0 1
  • 今天,咱們聊聊宇航員吧有咨!蘇聯(lián)有一位宇航員第一個(gè)進(jìn)入太空琐簇,有一次美國和蘇聯(lián)比賽看誰先登上月球,最后,美國贏了婉商。還有一...
    超級安安007閱讀 293評論 0 0