摘要:接入步驟安裝依賴(lài)啟用裝飾器語(yǔ)法如果有的話,要將沒(méi)有保存的文件上傳之后或者刪除之后才能跑命令在中找到項(xiàng)目在里面增加加入在下增加文件改寫(xiě)改寫(xiě)一下,來(lái)看看效果吧簡(jiǎn)要說(shuō)明表示注入在中的的屬性。
內(nèi)容導(dǎo)航
簡(jiǎn)單開(kāi)發(fā)react
將react與mobx結(jié)合開(kāi)發(fā)
使用react-router進(jìn)行多頁(yè)面開(kāi)發(fā)
將項(xiàng)目打包到后端項(xiàng)目中進(jìn)行部署
將完成的項(xiàng)目做成腳手架,避免重復(fù)的環(huán)境搭建
需要環(huán)境確保node已經(jīng)安裝
確保npm已經(jīng)安裝
創(chuàng)建項(xiàng)目npx create-react-app test # test 為你需要?jiǎng)?chuàng)建項(xiàng)目的名字,會(huì)在命令當(dāng)前目錄下創(chuàng)建test的目錄,包含項(xiàng)目所有的文件
你已經(jīng)完成了創(chuàng)建,開(kāi)始跑起來(lái)
npm start
你可以看到react已經(jīng)能夠在local host:3000訪問(wèn)了,只有一個(gè)歡迎頁(yè)面
目錄結(jié)構(gòu)
node_modules
是當(dāng)前目錄安裝的模塊存放的地方
public
index.html 是單頁(yè)面的入口
src
可存放自己編寫(xiě)的代碼,App是默認(rèn)生成的歡迎頁(yè)面邏輯,index 是js的主入口
開(kāi)始更改你的代碼 A. react簡(jiǎn)單開(kāi)發(fā)1.將App.js的代碼更改如下
import React, {Component} from "react"; import "./App.css"; class App extends Component { constructor(props) { super(props) this.state = {todos: [{checked: false, text: "hello"}, {checked: true, text: "world"}]} this.handleClick=this.handleClick.bind(this) } handleClick(index) { let todos = this.state.todos todos[index].checked = !todos[index].checked this.setState({todos:todos}) } render() { let todos = this.state.todos let todosDiv = todos.map((item, index) => { return () }) return ( {todosDiv}); } } class Todo extends Component { constructor(props){ super(props) this.handleClick=this.handleClick.bind(this) } handleClick() { let index = this.props.index this.props.handleClick(index) }; render() { return ({this.props.text}:{this.props.index}
) } } export default App;
再次npm start一下看看效果吧~
可以看到我們組件已經(jīng)能夠響應(yīng)點(diǎn)擊了
B. 引入mobx作為狀態(tài)管理 提出問(wèn)題在上面我們可以看到想要更改狀態(tài)是比較困難的,首先要將handClick方法由子組件傳給父組件,再進(jìn)行處理。如果我們的組件是
四五層組件的時(shí)候得一步一步的往上級(jí)傳遞,這就會(huì)導(dǎo)致組件傳遞寫(xiě)的很臃腫。這個(gè)時(shí)候就需要一個(gè)將狀態(tài)(即state這個(gè)值)獨(dú)立開(kāi)來(lái)。
react有很多狀態(tài)管理的組件,比如redux,mobx。但redux寫(xiě)起來(lái)還是不如mobx簡(jiǎn)單明了。下面我們就來(lái)接入mobx。
接入步驟
安裝依賴(lài)
npm install mobx --save npm install mobx-react --save
啟用裝飾器語(yǔ)法
# 如果有g(shù)it的話,要將沒(méi)有保存的文件上傳之后或者刪除之后才能跑eject命令 yarn run eject npm install --save-dev babel-preset-mobx
在package.json中找到babel項(xiàng)目,在presets里面增加"mobx"
"babel": {? "presets": [??? "react-app",??? "mobx"? ]},
加入core-decorators
npm install core-decorators --save
在src下增加store.AppStore.js文件
import {action, observable} from "mobx"; class AppStore { @observable todos; constructor() { this.todos = [{checked: false, text: "hello"}, {checked: true, text: "world"}] } @action.bound handleClick(index) { let todos = this.todos todos[index].checked = !todos[index].checked } } export default AppStore;
改寫(xiě)index.js
import React from "react"; import ReactDOM from "react-dom"; import "./index.css"; import App from "./App"; import * as serviceWorker from "./serviceWorker"; import {Provider} from "mobx-react"; import AppStore from "./store/AppStore" let rootStore = {} rootStore["app"] = new AppStore() ReactDOM.render(, 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();
改寫(xiě)App.js
import React, {Component} from "react"; import "./App.css"; import {inject, observer} from "mobx-react"; import {autobind} from "core-decorators"; @inject("app") @autobind @observer class App extends Component { constructor(props) { super(props) } render() { let todos = this.props.app.todos let todosDiv = todos.map((item, index) => { return () }) return ( {todosDiv}); } }
@inject("app") @autobind @observer class Todo extends Component { constructor(props) { super(props) } handleClick() { let index = this.props.index this.props.app.handleClick(index) }; render() { let index = this.props.index let todo = this.props.app.todos[index] return ({todo.text}:{index}
) } } export default App; ```
npm start一下,來(lái)看看效果吧
簡(jiǎn)要說(shuō)明@inject("app")表示注入在index.js中的rootStore的屬性app。是由
@autobind 將組件之間的綁定自動(dòng)完成
@observer mobx用來(lái)將react組件轉(zhuǎn)換為響應(yīng)式組件的注解,詳情查看mobx的文檔
上面可以看出,將原本的state的屬性抽離到AppStore中了,對(duì)值得更改方法也是直接調(diào)用AppStore的方法,從而避免了react組件的一級(jí)一級(jí)往上傳遞
C. 引入react-router作為多頁(yè)面管理 提出問(wèn)題上面我們完成了單頁(yè)面的開(kāi)發(fā)。當(dāng)需要多個(gè)頁(yè)面時(shí)我們就需要使用react-router來(lái)對(duì)不同路徑進(jìn)行渲染了
接入react-router步驟
安裝依賴(lài)
npm install react-router mobx-react-router --save
增加新的頁(yè)面,在src中增加component/Test.js
import * as React from "react"; class Test extends React.Component{ render() { return(welcome!
) } } export default Test;
更改index.js
import React from "react"; import ReactDOM from "react-dom"; import "./index.css"; import App from "./App"; import * as serviceWorker from "./serviceWorker"; import {Provider} from "mobx-react"; import AppStore from "./store/AppStore" import {Route, Router, Switch} from "react-router"; import {RouterStore, syncHistoryWithStore} from "mobx-react-router"; import createHashHistory from "history/createHashHistory" import Test from "./component/Test" let rootStore = {} const hashHistory = createHashHistory() const routerStore = new RouterStore() const history = syncHistoryWithStore(hashHistory, routerStore) rootStore["app"] = new AppStore() routerStore["routing"] = routerStore ReactDOM.render(, 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(); here is the menu
npm start一下,訪問(wèn)下/#/test,和/#/路徑,看看效果吧
簡(jiǎn)要說(shuō)明createHashHistory是單頁(yè)面的訪問(wèn),會(huì)在url加個(gè)#號(hào)作為定位,這個(gè)對(duì)于要打包到后臺(tái)作為頁(yè)面時(shí)是很方便的。
如果你直接使用node部署的話可以直接使用createBrowserHistory,url就會(huì)是沒(méi)有#號(hào)的url。
D. 結(jié)合ui框架 接入步驟找到一個(gè)合適的react ui框架,install之后按照ui框架的教程就可以開(kāi)發(fā)一個(gè)相對(duì)比較好看的頁(yè)面了
常見(jiàn)的框架有semantic,bootstrap,ant等。
E. 結(jié)合maven打包進(jìn)spring boot項(xiàng)目 提出問(wèn)題當(dāng)我們需要跟spring boot等后端項(xiàng)目結(jié)合,而又不想多帶帶部署前端頁(yè)面時(shí),就需要打包進(jìn)后端項(xiàng)目了
接入步驟新建一個(gè)多模塊的maven項(xiàng)目
按照之前創(chuàng)建的步驟,創(chuàng)建前端的模塊,假設(shè)模塊名字為view,并在前端模塊的目錄下增加pom.xml
com.github.eirslett frontend-maven-plugin 1.2 <-- Install our node and npm version to run npm/node scripts--> <-- Set NPM Registry --> install node and npm install-node-and-npm <-- 指定node的版本例如 v6.9.1 --> ${nodeVersion} ${npmVersion} https://npm.taobao.org/mirrors/node/ http://registry.npmjs.org/npm/-/ <-- Set SSL privilege --> npm set registry npm <-- config set registry https://registry.npmjs.org -->config set registry https://registry.npm.taobao.org <-- Install all project dependencies --> npm set non-strict ssl <-- Optional configuration which provides for running any npm command --> npm config set strict-ssl false <-- Build and minify static files --> npm install <-- optional: default phase is "generate-resources" --> npm generate-resources <-- Optional configuration which provides for running any npm command -->install npm run build npm run build
當(dāng)進(jìn)行mvn package時(shí)就會(huì)在目錄下生成build目錄,包含所有的頁(yè)面和腳本了。
在spring boot后端項(xiàng)目中,將前端打包好的頁(yè)面拷貝到后端目錄中
maven-resources-plugin Copy App Content generate-resources copy-resources src/main/resources/public true ${project.parent.basedir}/view/build static/ index.html org.springframework.boot spring-boot-maven-plugin
其中outputDirectory指明要放入的文件夾
directory指明要拷貝哪里的資源文件,需要根據(jù)你的前端模塊名進(jìn)行相應(yīng)的修改
mvn package 一下,后端模塊的打包jar里面就會(huì)有相應(yīng)的資源文件啦
F. 前后端聯(lián)調(diào) 步驟在前端項(xiàng)目package.json中指明接口的代理
"proxy":"http://localhost:8080/"
如果servletPath不為/,則需要在后面補(bǔ)上相應(yīng)的servletPath
當(dāng)你的后端項(xiàng)目有設(shè)置servletPath的時(shí)候,需要相應(yīng)配置前端的打包的servletPath,否則默認(rèn)為/的servletpath
方法1: package.json 增加
"homepage": "."
方法2: config.paths.js文件下修改配置
function getServedPath(appPackageJson) { const publicUrl = getPublicUrl(appPackageJson); //將/修改為./ const servedUrl = envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : "./"); return ensureSlash(servedUrl, true); }G. 將你創(chuàng)建好的項(xiàng)目做成腳手架 提出問(wèn)題
如果每個(gè)項(xiàng)目都要經(jīng)歷上面的步驟,才能完成,那前期工作量是在太繁瑣又重復(fù)
借助maven的archetype來(lái)幫你自動(dòng)生成一個(gè)初始項(xiàng)目吧
接入步驟按照上面的流程我們已經(jīng)建好了項(xiàng)目
在項(xiàng)目目錄下執(zhí)行 mvn archetype:create-from-project,生成的target就是你的腳手架項(xiàng)目
cd target/generated-sources/archetype 目錄下,執(zhí)行mvn install 就把a(bǔ)rchetype放入了本地倉(cāng)庫(kù)了,可以進(jìn)行使用了
為了deploy到遠(yuǎn)程倉(cāng)庫(kù)中,需要在target/generated-sources/archetype 目錄下的pom.xml中加入自己的遠(yuǎn)程倉(cāng)庫(kù)的地址,然后在target/generated-sources/archetype 目錄下mvn deploy就可以了
屏蔽掉部分不想打包進(jìn)archetype的文件要屏蔽部分文件夾時(shí)在pom中加入plugin
maven-archetype-plugin 3.0.1 archetype.properties
新建archetype.properties文件,配置要忽略的通配符excludePatterns=/.idea/,**.iml
怎么使用archetype創(chuàng)建項(xiàng)目在idea中,在點(diǎn)擊file-> new-> project后彈出的對(duì)話框中選擇maven
在create from archetype打勾,點(diǎn)擊Add archetype加入創(chuàng)建好的archetype
填寫(xiě)對(duì)應(yīng)的groupId,artifaceId,version后在列表中選擇已有的archetype
按引導(dǎo)進(jìn)行后續(xù)步驟的創(chuàng)建,然后就會(huì)自動(dòng)生成跟你項(xiàng)目一樣的啦
跨store的訪問(wèn) 什么是跨store訪問(wèn)在上面我們有這樣的代碼
const routerStore = new RouterStore() rootStore["app"] = new AppStore() routerStore["routing"] = routerStore
有時(shí)候我們往往需要在一個(gè)store的方法中去訪問(wèn)下別的store的內(nèi)容,這個(gè)時(shí)候就是跨store的訪問(wèn),就需要在初始化時(shí)將rootStore傳給這個(gè)store,通過(guò)rootStore去訪問(wèn),改寫(xiě)index.js
rootStore["app"] = new AppStore(rootStore)
改寫(xiě)AppStore.js,增加構(gòu)造函數(shù)
constructor(rootStore) { this.rootStore = rootStore }
這樣就可以在AppStore.js的函數(shù)中通過(guò)this.rootStore 去獲取所有store的json,從而訪問(wèn)所有的store了
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/73950.html
摘要:接入步驟安裝依賴(lài)啟用裝飾器語(yǔ)法如果有的話,要將沒(méi)有保存的文件上傳之后或者刪除之后才能跑命令在中找到項(xiàng)目在里面增加加入在下增加文件改寫(xiě)改寫(xiě)一下,來(lái)看看效果吧簡(jiǎn)要說(shuō)明表示注入在中的的屬性。 內(nèi)容導(dǎo)航 簡(jiǎn)單開(kāi)發(fā)react 將react與mobx結(jié)合開(kāi)發(fā) 使用react-router進(jìn)行多頁(yè)面開(kāi)發(fā) 將項(xiàng)目打包到后端項(xiàng)目中進(jìn)行部署 將完成的項(xiàng)目做成腳手架,避免重復(fù)的環(huán)境搭建 需要環(huán)境 確保...
摘要:結(jié)合編輯器可以推導(dǎo)變量對(duì)應(yīng)的類(lèi)型以及內(nèi)部的結(jié)構(gòu),提高代碼的健壯性和可維護(hù)性。通過(guò)充分利用時(shí)間回溯的特征,可以增強(qiáng)業(yè)務(wù)的可預(yù)測(cè)性與錯(cuò)誤定位能力。對(duì)于對(duì)象的哪部分需要成為可觀察的,提供了細(xì)粒度的控制。 showImg(https://segmentfault.com/img/bVba6Ts?w=1218&h=525); 為什么要使用TypeScript 偵測(cè)錯(cuò)誤 通過(guò)靜態(tài)類(lèi)型檢測(cè)可以盡早檢...
摘要:調(diào)試集成環(huán)境選擇模塊,簡(jiǎn)單分離開(kāi)發(fā),測(cè)試,線上環(huán)境。程序保護(hù)開(kāi)機(jī)自啟托盤(pán)最小化崩潰監(jiān)控升級(jí)一行代碼接入升級(jí)平臺(tái),實(shí)現(xiàn)客戶(hù)端升級(jí)功能打包構(gòu)建一個(gè)指令搞定打包項(xiàng)目地址 項(xiàng)目地址 : https://github.com/ConardLi/electron-react electron-react electron + react + react-router + mobx + webpac...
摘要:前言現(xiàn)在最熱門(mén)的前端框架,毫無(wú)疑問(wèn)是。對(duì)于小型應(yīng)用,引入狀態(tài)管理庫(kù)是奢侈的。但對(duì)于復(fù)雜的中大型應(yīng)用,引入狀態(tài)管理庫(kù)是必要的?,F(xiàn)在熱門(mén)的狀態(tài)管理解決方案,相繼進(jìn)入開(kāi)發(fā)者的視野。獲得計(jì)算得到的新并返回。 前言 現(xiàn)在最熱門(mén)的前端框架,毫無(wú)疑問(wèn)是React。 React是一個(gè)狀態(tài)機(jī),由開(kāi)始的初始狀態(tài),通過(guò)與用戶(hù)的互動(dòng),導(dǎo)致?tīng)顟B(tài)變化,從而重新渲染UI。 對(duì)于小型應(yīng)用,引入狀態(tài)管理庫(kù)是奢侈的。 但...
摘要:希望大家在這浮夸的前端圈里,保持冷靜,堅(jiān)持每天花分鐘來(lái)學(xué)習(xí)與思考。 今天的React題沒(méi)有太多的故事…… 半個(gè)月前出了248個(gè)Vue的知識(shí)點(diǎn),受到很多朋友的關(guān)注,都強(qiáng)烈要求再出多些React相前的面試題,受到大家的邀請(qǐng),我又找了20多個(gè)React的使用者,他們給出了328道React的面試題,由我整理好發(fā)給大家,同時(shí)發(fā)布在了前端面試每日3+1的React專(zhuān)題,希望對(duì)大家有所幫助,同時(shí)大...
閱讀 3553·2019-08-30 15:53
閱讀 3463·2019-08-29 16:54
閱讀 2254·2019-08-29 16:41
閱讀 2529·2019-08-23 16:10
閱讀 3436·2019-08-23 15:04
閱讀 1431·2019-08-23 13:58
閱讀 417·2019-08-23 11:40
閱讀 2511·2019-08-23 10:26