系統: windows
node 下載地址.一路 nextnode
若是遇到 windows 沒有權限安裝 msi 文件.打開 cmd,運行
msiexec /package 文件路徑
.
查看是否安裝成功,打開終端react
node -v npm -v
vscode 下載地址.一路 nextwebpack
打開終端ios
npm install -g create-react-app
create-react-app myApp cd myApp npm install npm start code .
npm i react-router-dom mobx mobx-react axios qs --save
配置裝飾器語法支持web
npm i --save-dev @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators
解壓 webpack 配置npm
npm run eject
修改webpack.config.dev.js
和webpack.config.prod.js
json
{ test: /\.(js|mjs|jsx|ts|tsx)$/, include: paths.appSrc, loader: require.resolve('babel-loader'), options: { customize: require.resolve('babel-preset-react-app/webpack-overrides'), plugins: [ + ['@babel/plugin-proposal-decorators', { legacy: true }], + ['@babel/plugin-proposal-class-properties', { loose: true }], [ require.resolve('babel-plugin-named-asset-import'), { loaderMap: { svg: { ReactComponent: '@svgr/webpack?-prettier,-svgo![path]' } } } ] ], // This is a feature of `babel-loader` for webpack (not Babel itself). // It enables caching results in ./node_modules/.cache/babel-loader/ // directory for faster rebuilds. cacheDirectory: true, // Don't waste time on Gzipping the cache cacheCompression: false } }
在項目中新建src\pages
文件夾.
新建頁面文件src\pages\Home\index.js
axios
// Home\index.js /** * @name Home * @desc 首頁 */ import React, { Component } from 'react' class Home extends Component { render() { return ( <div> <h1>Home</h1> </div> ) } } export default Home
新建router.js
segmentfault
/** * @name Router * @desc 頁面路由配置 */ import React, { Component } from 'react' import { Switch, Route, Redirect } from 'react-router-dom' import Home from './pages/Home' class Router extends Component { render() { return ( <Switch> <Redirect path="/" to="/home" exact /> <Route path="/home" component={Home} /> </Switch> ) } } export default Router
新建src\utils\axios.js
windows
import axios from 'axios' import qs from 'qs' const axiosIns = axios.create({ baseURL: '/', timeout: 10000, responseType: 'json', transformRequest: [data => qs.stringify(data)], headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' } }) axiosIns.interceptors.request.use( config => { return config }, error => Promise.reject(error) ) axiosIns.interceptors.response.use(result => result.data, error => Promise.reject(error)) const get = (url, params = null, config = {}) => axiosIns.get(url, { ...config, params }) const post = axiosIns.post const all = axiosIns.all export { get, post, all }
src\utils\mobx-store.js
/** * @name Store * @desc store 構造器 */ import { action, configure } from 'mobx' configure({ enforceActions: 'observed' }) class Store { constructor(modules) { Object.keys(modules).forEach(moduleName => { this[moduleName] = new modules[moduleName]({ mapStore: this.mapStore.bind(this), rootState: this.rootState }) }) } rootState = {} mapStore(moduleName) { if (moduleName) { return this[moduleName] ? this[moduleName] : console.error(new Error(`has no store named "${moduleName}"`)) } else { return this } } } let $mapStore = null let $rootState = null class StoreModule { constructor({ mapStore, rootState }) { $mapStore = mapStore $rootState = rootState } mapStore(name) { return $mapStore(name) } getRootState() { return $rootState } setState(options) { action(opt => { Object.keys(opt).forEach(key => { if (Object.prototype.hasOwnProperty.call(this, key)) { this[key] = opt[key] } else { console.error(new Error(`mobx action "setState": has no attribute named "${key}"`)) } }) })(options) } } export { Store, StoreModule }
src\store\test-store.js
/** * @name Test * @desc */ import { observable, action, configure } from 'mobx' import { StoreModule } from '../utils/mobx-store' configure({ enforceActions: 'observed' }) class Test extends StoreModule { @observable msg = '' @action.bound handleChangeMsg(e) { this.setState({ msg: e.target.value }) } } export default Test
新建src\store\index.js
/** * @name Store * @desc 合併所有子模塊的store */ import { Store } from '../utils/mobx-store' import Test from './test-store.js' export default new Store({ Test })
修改index.js
import React from 'react' import ReactDOM from 'react-dom' import { BrowserRouter } from 'react-router-dom' import { Provider } from 'mobx-react' import store from './store' import App from './App' ReactDOM.render( <Provider {...store}> <BrowserRouter> <App /> </BrowserRouter> </Provider>, document.getElementById('root') )
修改App.js
import React, { Component } from 'react' import Routes from './router' class App extends Component { render() { return ( <div classes="container"> <Routes /> </div> ) } } export default App
修改src\pages\Home\index.js
/** * @name Home * @desc 首頁 * @author * @version */ import React, { Component } from 'react' import { inject, observer } from 'mobx-react' @inject('Test') @observer class Home extends Component { render() { return ( <div> <h1>Home</h1> <p>msg: {this.props.Test.msg}</p> <p> <input type="text" value={this.props.Test.msg} onChange={this.props.Test.handleChangeMsg} /> </p> </div> ) } } export default Home
// src\store\test-store.js /** * @name Test * @desc */ import { observable, action, configure } from 'mobx' import { StoreModule } from '../utils/mobx-store' import { post } from '../utils/axios' configure({ enforceActions: true }) class Test extends StoreModule { @observable msg = '' @action.bound handleChangeMsg(e) { this.setState({ msg: e.target.value }) } @action.bound async getSomething() { try { const res = await post('/some-data', { type: 'news' }) } catch (err) { console.error(err) } } } export default Test
npm run build
安裝本地服務器啓動工具
npm install -g serve
啓動打包的項目
serve -s ./build
來源:https://segmentfault.com/a/1190000017109354