Commit 3ce71500 by yangfangfang

init

parents
{
"presets": ["env","react"],
"plugins": ["transform-object-rest-spread"],
"env": {
"production": {
"plugins": ["transform-react-remove-prop-types"]
}
}
}
/.DS_Store
/node_modules/
/dist/
export const TEST_DATA = 'TEST_DATA'
export const USER_INFO = 'USER_INFO'
// require('./styles/login.css')
import '@/styles/style.scss'
import React from 'react'
import HttpService from '@/util/HttpService'
export default class About extends React.PureComponent {
constructor(props){
super(props)
this.state = {
infos: []
}
this.test = this.test.bind(this);
}
test () {
this.props.history.push("/user?a=1");
}
componentWillMount () {
}
componentDidMount () {
HttpService.getInfo("http://www.trackingio.com/api/report/all/home",{
startdate:'2017-11-22',
enddate:'2017-11-22',
datatype:'chart'
}).then((data) => {
this.setState({infos:data.content.val[0]})
});
}
componentWillUnmount () {
}
render() {
let name_p = this.state.infos.map((item,i) => {
return <p key={i}>name:{item.name}</p>
});
return <div>
{name_p}
</div>
}
}
import React from 'react'
import { HashRouter,Switch, Route, NavLink,Redirect} from 'react-router-dom';
import PropTypes from 'prop-types'
import DateTool from '@/util/DateTool'
import Book from '@/components/Book'
import User from '@/components/User'
import About from '@/components/About'
import Children from '@/components/Children'
const routes = {
'uinfo':[
{id:1,name:'用户','path':'/user'},
{id:2,name:'书籍','path':'/book'}
],
'others':[
{id:3,name:'多级路由与全局state','path':'/children'},
{id:4,name:'服务器数据交互','path':'/about'}
]
}
export default class App extends React.PureComponent {
constructor(props){
super(props)
let rkey = 'uinfo',keymenus = routes[rkey];
this.state = {
count: 1,
rkey: rkey,
menus: keymenus
};
this.getClassN = this.getClassN.bind(this);
this.changeMeus = this.changeMeus.bind(this);
}
get myDate () {
return DateTool.formatDate(new Date());
}
changeMeus (key) {
let keymenus = routes[key];
this.setState({
rkey: key,
menus: keymenus
});
}
getClassN (key) {
if(this.state.rkey == key){
return 'active';
}
else{
return '';
}
}
componentWillMount () {
}
componentDidMount () {
}
componentWillUnmount () {
}
componentDidUpdate (prevProps, prevState) {
console.log(prevState,this.state)
}
render() {
let navHtml = [{'name':'用户相关','key':'uinfo'},{'name':'其他','key':'others'}].map(menu => {
return <a key={menu.key} href="javascript:void(0)" className={this.getClassN(menu.key)} onClick={() => {this.changeMeus(menu.key)}}>{menu.name}</a>;
})
let menuCont = this.state.menus.map(item => {
return <li key={item.id}><NavLink to={item.path}>{item.name}</NavLink></li>
});
let defaultTo = this.state.menus[0].path;
return (<HashRouter>
<div className="mainbody">
<header>
<nav>{navHtml}</nav>
</header>
<div className="contentWrap">
<div className="leftNav">
<ul>{menuCont}</ul>
</div>
<div className="rightCont">
{this.myDate}
<Switch>
<Route path="/user" component={User}></Route>
<Route path="/book" component={Book}></Route>
<Route path="/children" component={Children}></Route>
<Route path="/about" component={About}></Route>
<Redirect to={defaultTo}/>
</Switch>
</div>
</div>
</div>
</HashRouter>)
}
}
App.defaultProps = {
name: 'kaka'
}
App.propTypes = {
name: PropTypes.string.isRequired
}
import React from 'react'
import TableList from '@/components/common/TableList'
export default class Book extends React.PureComponent {
constructor(props){
super(props)
console.log(this.props)
let {id} = this.props.match.params;
let {aa} = this.props.location.search.substr(1);
}
componentWillMount () {
}
componentDidMount () {
}
componentWillUnmount () {
}
render() {
let datas = {
columnkey: ['id','name','author'],
name: ['ID','书名','作者'],
val: [
{id:1,name:'西游记',author:'吴承恩'},
{id:2,name:'平凡的世界',author:'路遥'},
{id:3,name:'蛙',author:'莫言'},
{id:4,name:'梦里花落知多少',author:'郭敬明'}
]
}
return <TableList infos={datas}></TableList>
}
}
import React from 'react'
import { connect } from 'react-redux'
import { Route, Link} from 'react-router-dom';
import Notice from '@/components/Notice'
class Children extends React.PureComponent {
constructor(props){
super(props)
console.log( this.props)
let url = this.props.match.url;
this.state = {
url : url
}
}
componentWillMount () {
}
componentDidMount () {
}
componentWillUnmount () {
}
render() {
return <div>
<p>notice-data:[{this.props.data}]</p>
<p>user-name:[{this.props.name}]</p>
<p><Link to={`${this.state.url}/apple`}>apple</Link></p>
<p><Link to={`${this.state.url}/orange`}>orange</Link></p>
<Route path={`${this.state.url}/apple`} component={apple}></Route>
<Route path={`${this.state.url}/orange`} component={orange}></Route>
<Route exact path={this.state.url} render={() => (
<h3>I am children</h3>
)}/>
</div>
}
}
const apple = ({match}) => (
<div>I am a apple<Notice/></div>
)
const orange = () => (
<div>I am a orange</div>
)
const mapStateToProps = (state, ownProps) => {
return {
data: state.Notice.data,
code : state.Notice.code,
name : state.User.name
}
}
export default connect(
mapStateToProps
)(Children)
import React from 'react'
import { connect } from 'react-redux'
class NoticeUI extends React.PureComponent {
constructor(props){
super(props)
console.log( this.props)
this.state = {
value: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
this.props.changeName(event.target.value);
}
componentWillMount () {
}
componentDidMount () {
}
componentWillUnmount () {
}
render() {
return <div>
store.......<button onClick = {this.props.onClick}>改变notice-data|code</button>
<p>notice-code:[{this.props.code}]</p>
<p>user-name:[{this.props.name}]</p>
<div><input type='text' value={this.state.value} onChange={this.handleChange} placeholder="改变user-name"/></div>
</div>
}
}
const mapStateToProps = (state, ownProps) => {
return {
data: state.Notice.data,
code : state.Notice.code,
name : state.User.name
}
}
const mapDispatchToProps = (dispatch, ownProps) => {
return {
onClick: () => {
dispatch({
type: 'TEST_DATA',
data: 'hahahhahaha'
})
},
changeName: (name) => {
dispatch({
type: 'USER_INFO',
name: name
})
}
}
}
let Notice = connect(
mapStateToProps,
mapDispatchToProps
)(NoticeUI);
export default Notice;
import React from 'react'
import { Redirect} from 'react-router-dom';
import TableList from '@/components/common/TableList'
export default class User extends React.PureComponent {
constructor(props){
super(props)
this.state = {
redirect:false
}
this.clickHandle = () => {
this.setState({redirect:true})
}
this.childMethod = this.childMethod.bind(this);
}
childMethod () {
console.log(this.refs.tableref.props)
this.refs.tableref.testInfo();
}
componentWillMount () {
}
componentDidMount () {
}
componentWillUnmount () {
}
render() {
if(this.state.redirect){
return <Redirect push to="/book/2?aa=1" />
}
let datas = {
columnkey: ['id','name','age','country'],
name: ['ID','姓名','年龄','国家'],
val: [
{id:1,name:'张三',age:18,country:'中国'},
{id:2,name:'李四',age:50,country:'美国'},
]
}
return <div>
<p><button onClick={this.clickHandle}>跳转到Book</button></p>
<p><button onClick={this.childMethod}>调用子组件方法</button></p>
<TableList infos={datas} ref="tableref"></TableList>
</div>
}
}
import React from 'react'
import PropTypes from 'prop-types'
export default class TableList extends React.PureComponent {
constructor(props){
super(props)
this.state = {
names: this.props.infos.name,
columnkey: this.props.infos.columnkey,
values: this.props.infos.val
}
this.testInfo = this.testInfo.bind(this);
}
testInfo () {
console.log('test'+this.state.names)
}
componentWillMount () {
}
componentDidMount () {
}
componentWillUnmount () {
}
render() {
let names = this.state.names.map((name) => {
return <th key={name}>{name}</th>
});
let infos = this.state.values.map((val,i) => {
let tds = this.state.columnkey.map((key) => {
return <td key={key}>{val[key]}</td>
})
return <tr key={val.id}>{tds}</tr>
})
return <div className="tableWrap">
<table>
<thead>
<tr>
{names}
</tr>
</thead>
<tbody>
{infos}
</tbody>
</table>
</div>
}
}
TableList.defaultProps = {
}
TableList.propTypes = {
infos:PropTypes.shape({
name:PropTypes.array.isRequired,
columnkey:PropTypes.array.isRequired,
val:PropTypes.arrayOf(PropTypes.object).isRequired
})
}
import React from 'react'
import ReactDOM from 'react-dom'
import App from '@/components/App'
// 引入redux
import { createStore} from 'redux'
import { Provider } from 'react-redux'
// 引入reducer
import rootReducer from "./reducers"
// 创建store
const store = createStore(
rootReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
function Clock(props) {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {props.date.toLocaleTimeString()}.</h2>
</div>
);
}
ReactDOM.render(
<Provider store={store}>
<App name1='122'/>
</Provider>,
// <Clock date={new Date()} />,
document.getElementById('app')
);
import {TEST_DATA} from '@/actions/index'
let Notice = (state = {code:''},action) => {
switch (action.type) {
case TEST_DATA:
return {
data: action.data,
code: 'success'
}
default:
return state;
}
}
export default Notice;
import {USER_INFO} from '@/actions/index'
let User = (state = {code:''},action) => {
switch (action.type) {
case USER_INFO:
return {
name: action.name,
code: 'ADD'
}
default:
return state;
}
}
export default User;
import {combineReducers} from 'redux'
import Notice from './Notice'
import User from './User'
const rootReducer = combineReducers({
Notice,
User
});
export default rootReducer
@import "value.scss";
html,body{
font-family:'Microsoft YaHei','Arial';
width:100%;
height:100%;
overflow:hidden;
margin:0px;
padding:0px;
font-size:14px;
}
ul,li,nav{
padding:0;
margin:0;
list-style:none;
}
#app,.mainbody{
width:100%;
height:100%;
overflow:hidden;
}
header{
height:$headerH;
background-color:$headerBg;
display: flex;
nav{
display: flex;
justify-content:flex-start;
align-items:center;
align-content:center;
a{
text-decoration: none;
color:#fff;
display: inline-block;
align-self:center;
min-width: 100px;
text-align: center;
}
a.active{
text-decoration: underline;
}
}
}
.contentWrap{
display:flex;
flex-wrap:nowrap;
height: calc(100% - 70px);
.leftNav{
width:$leftW;
background-color:$leftBg;
border-right:1px solid $leftBr;
li{
height: 35px;
line-height: 35px;
border-bottom:1px solid $leftBr;
padding-left: 15px;
&.active{
background-color: $leftactiveBg;
a{
color:$leftactiveFC;
}
}
a.active{
color:$leftactiveFC;
}
a{
text-decoration: none;
color:#666;
}
}
}
.rightCont{
flex-grow:10;
padding:15px;
max-height: 100%;
overflow-y: auto;
}
}
.tableWrap{
table{
border-collapse: collapse;
width:80%;
th,td{
line-height: 30px;
border:1px solid #dcdcdc;
text-align: center;
}
}
}
h5{
color:red;
}
$headerH:70px;
$headerBg:#5f97fb;
$leftBg:#f1f1f1;
$leftBr:#e4e4e4;
$leftW:170px;
$leftactiveBg:#f1f3f5;
$leftactiveFC:#5f97fb;
const DateTool = {
formatDate(date) {
return date.toLocaleDateString();
}
}
export default DateTool;
import request from 'superagent-bluebird-promise'
const HttpService = {
getInfo: function (url,params) {
let paramsArr = ['r='+Math.random()];
if(params){
for(let k in params){
paramsArr.push(k + '=' + params[k]);
}
}
url = url.indexOf("?") > -1 ? url : (url+'?');
url += paramsArr.join("&");
return new Promise(function (resolve, reject){
request.get(url,{}).set('Accept', 'application/json').then(function (data) {
resolve(data.body);
},function (data) {
reject(data);
});
});
},
postInfo: function (url,params) {
if(!params){params = {}}
params.r = Math.random();
return new Promise(function (resolve, reject){
request.post(url,params).set('Accept', 'application/json').then(function (data) {
resolve(data.body);
},function (data) {
reject(data);
});
});
}
}
export default HttpService;
'use strict'
const path = require("path");
const extractTextPlugin = require('extract-text-webpack-plugin');
const postcssImport = require('postcss-import');
const autoprefixer = require('autoprefixer');
function resolve (dir) {
return path.join(__dirname, '..', dir);
}
function cssLoaders (type) {
var postcssLoader = {
loader:'postcss-loader',
options:{
plugins:[postcssImport,autoprefixer],
browser:['last 5 versions']
}
};
if(process.env.NODE_ENV === 'development'){
var loaders = ['style-loader','css-loader',postcssLoader];
if(type && type == 'sass'){
loaders.push("sass-loader");
}
return loaders;
}
else{
var loaders = {
fallback: 'style-loader',
use: ['css-loader',postcssLoader, 'sass-loader']
};
if(type && type == 'sass'){
loaders.use.push("sass-loader");
}
return extractTextPlugin.extract(loaders);
}
}
module.exports = {
entry: {
app:'./client/index.js',
common:['./client/common.js']
},
output: {
path: resolve('./dist'),
filename:'js/[name]-[hash].js',
publicPath:''
},
// devServer:{
// historyApiFallback: true,
// contentBase: './',
// hot:true
// },
resolve: {
extensions: ['.js', '.jsx', '.json'],
alias: {
'@': resolve('client'),
}
},
module:{
rules:[
{
test:/\.js[x]?$/,
loader:['babel-loader'],
exclude:resolve('node_modules/')
},
{
test:/\.html$/,
loader:'html-loader'
},
{
test:/\.json$/,
loader:'json-loader'
},
{
test:/\.css$/,
use: cssLoaders()
},
{
test:/\.scss$/,
use: cssLoaders('sass')
},
{
test:/\.(jpg|png|jpeg|gif)$/,
loaders:[
{
loader:'url-loader',
options:{
limit:1000,
name:'assets/[name]-[hash:5].[ext]'
}
},
'image-webpack-loader'
]
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'fonts/[name].[hash:7].[ext]'
}
}
]
}
}
'use strict'
const path = require("path");
const webpack = require('webpack');
const merge = require('webpack-merge');
const baseConfig = require("./base");
const htmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = merge(baseConfig,{
devtool: '#source-map',
plugins:[
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new htmlWebpackPlugin({
filename:'index.html',
template:'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: false
},
chunksSortMode: 'dependency'
}),
new CleanWebpackPlugin(
[resolve('dist/*')],  //匹配删除的文件
{
root: '/',           //根目录
verbose: true,           //开启在控制台输出信息
dry: false           //启用删除文件
}
),
new ExtractTextPlugin('style/[name]-[contenthash].css'),
new OptimizeCSSPlugin({
cssProcessorOptions: {
safe: true
}
}),
new CopyWebpackPlugin([
{
from: resolve('client/static'),
to: resolve('dist/static'),
ignore: ['.*']
}
]),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
// Drop `console` statements
drop_console: true
},
sourceMap: true
}),
new webpack.HashedModuleIdsPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
return (
module.resource &&
/\.(js|css)$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
})
]
});
'use strict'
require('eventsource-polyfill')
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
hotClient.subscribe(function (event) {
if (event.action === 'reload') {
window.location.reload()
}
})
'use strict'
const path = require("path");
const webpack = require('webpack');
const merge = require('webpack-merge');
const baseConfig = require("./base");
const htmlWebpackPlugin = require('html-webpack-plugin');
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
//加入热更新
Object.keys(baseConfig.entry).forEach(function (name) {
baseConfig.entry[name] = ['./config/dev-client'].concat(baseConfig.entry[name])
})
module.exports = merge(baseConfig,{
devtool: '#cheap-module-eval-source-map',
plugins:[
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"development"'
}
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new htmlWebpackPlugin({
filename:'index.html',
template:'index.html',
chunks:['app','common']
}),
new FriendlyErrorsPlugin()
]
});
'use strict'
const path = require('path')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
exports.assetsPath = function (_path) {
const assetsSubDirectory = "static"
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
const cssLoader = {
loader: 'css-loader',
options: {
minimize: process.env.NODE_ENV === 'production',
sourceMap: options.sourceMap
}
}
function generateLoaders (loader, loaderOptions) {
const loaders = [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
return {
css: generateLoaders(),
postcss: generateLoaders(),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass')
}
}
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
'use strict'
if (!process.env.NODE_ENV) {
process.env.NODE_ENV = 'development';
}
const devConfig = require("./dev")
const opn = require('opn')
const path = require('path')
const express = require('express')
const webpack = require('webpack')
const app = express()
const compiler = webpack(devConfig)
const devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: devConfig.output.publicPath,
quiet: true
})
const hotMiddleware = require('webpack-hot-middleware')(compiler, {
log: false,
heartbeat: 2000
})
app.use(hotMiddleware);
app.use(devMiddleware);
const staticPath = path.posix.join('/', 'static')
app.use(staticPath, express.static('./static'))
const port = 8080;
const uri = 'http://localhost:' + port;
var _resolve
var _reject
var readyPromise = new Promise((resolve, reject) => {
_resolve = resolve
_reject = reject
})
var server
var portfinder = require('portfinder')
portfinder.basePort = port
console.log('> Starting dev server...')
devMiddleware.waitUntilValid(() => {
portfinder.getPort((err, port) => {
if (err) {
_reject(err)
}
process.env.PORT = port
var uri = 'http://localhost:' + port
console.log('> Listening at ' + uri + '\n')
if (process.env.NODE_ENV !== 'testing') {
opn(uri)
}
server = app.listen(port)
_resolve()
})
})
module.exports = {
ready: readyPromise,
close: () => {
server.close()
}
}
'use strict'
process.env.NODE_ENV = 'production';
const buildConfig = require("./build");
const merge = require('webpack-merge');
module.exports = merge(buildConfig,{});
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>react+webpack</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
{
"name": "wpdemo03",
"version": "1.0.0",
"description": "",
"scripts": {
"build": "webpack --progress --colors --config config/webpack.pro.config.js",
"dev": "node config/webpack.dev.config.js ",
"start": "npm run dev"
},
"author": "",
"license": "ISC",
"devDependencies": {
"autoprefixer": "^7.1.6",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-react-remove-prop-types": "^0.4.10",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1",
"clean-webpack-plugin": "^0.1.17",
"copy-webpack-plugin": "^4.2.0",
"css-loader": "^0.28.7",
"eslint": "^4.11.0",
"eslint-loader": "^1.9.0",
"eventsource-polyfill": "^0.9.6",
"express": "^4.16.2",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.5",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-loader": "^0.5.1",
"html-webpack-plugin": "^2.30.1",
"image-webpack-loader": "^3.4.2",
"json-loader": "^0.5.7",
"node-sass": "^4.6.1",
"opn": "^5.1.0",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"portfinder": "^1.0.13",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"sass-loader": "^6.0.6",
"style-loader": "^0.19.0",
"superagent": "^3.8.2",
"superagent-bluebird-promise": "^4.2.0",
"uglify-loader": "^2.0.0",
"url-loader": "^0.6.2",
"webpack": "^3.10.0",
"webpack-dev-middleware": "^1.12.0",
"webpack-hot-middleware": "^2.20.0",
"webpack-merge": "^4.1.1"
},
"dependencies": {
"prop-types": "^15.6.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-redux": "^5.0.6",
"react-router-dom": "^4.2.2",
"redux": "^3.7.2"
}
}
# install dependencies
npm install
# serve with hot reload at localhost:8081
npm run dev or npm start
# build for production with minification
npm run build
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment