├── src ├── redux │ ├── actions │ │ ├── index.js │ │ ├── home.js │ │ └── cart.js │ ├── actionTypes.js │ └── reducers │ │ ├── cart.js │ │ ├── home.js │ │ └── index.js ├── pages │ ├── home │ │ ├── img │ │ │ └── icon-1.png │ │ ├── item │ │ │ └── nav.js │ │ ├── child.js │ │ ├── two.js │ │ ├── home.scss │ │ ├── router.js │ │ ├── one.js │ │ └── home.js │ └── user │ │ ├── router.js │ │ ├── user.scss │ │ └── user.js ├── assets │ └── common │ │ ├── images │ │ ├── 404 │ │ │ ├── 404.png │ │ │ ├── 404_msg.png │ │ │ ├── error_bg.jpg │ │ │ ├── 404_to_index.png │ │ │ ├── error_cloud.png │ │ │ └── screenshot.jpg │ │ ├── qq.png │ │ ├── empty.png │ │ ├── icon-1.png │ │ ├── icon-2.png │ │ ├── icon-3.png │ │ ├── logo.png │ │ ├── upload.png │ │ ├── backtop.png │ │ ├── loading.gif │ │ ├── call_kefu.png │ │ ├── loading_1.gif │ │ ├── icon-left-jt.png │ │ ├── icon-right-jt.png │ │ ├── PopLayer-close.png │ │ ├── default_big_img.png │ │ └── gods-default-icon.png │ │ ├── css │ │ ├── OpenSans-Regular.ttf │ │ ├── common.scss │ │ ├── vars.scss │ │ └── base.scss │ │ ├── js │ │ ├── common.js │ │ ├── config.js │ │ ├── format.js │ │ ├── echo.min.js │ │ └── util.js │ │ └── lib │ │ ├── page │ │ ├── page.css │ │ └── page.js │ │ └── popup │ │ ├── popup.css │ │ └── popup.js ├── components │ ├── Loading.js │ ├── AsyncComponent.js │ ├── BundleImport.js │ └── Bundle.js ├── commonjsx │ ├── footer.js │ └── header.js ├── index.html ├── main.js └── app.js ├── favicon.ico ├── demoImg └── 01.png ├── .gitignore ├── .flowconfig ├── postcss.config.js ├── README.md ├── .eslintrc └── package.json /src/redux/actions/index.js: -------------------------------------------------------------------------------- 1 | export * from './cart' 2 | export * from './home' -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/favicon.ico -------------------------------------------------------------------------------- /demoImg/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/demoImg/01.png -------------------------------------------------------------------------------- /src/pages/home/img/icon-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/pages/home/img/icon-1.png -------------------------------------------------------------------------------- /src/assets/common/images/qq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/qq.png -------------------------------------------------------------------------------- /src/assets/common/images/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/empty.png -------------------------------------------------------------------------------- /src/assets/common/images/icon-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/icon-1.png -------------------------------------------------------------------------------- /src/assets/common/images/icon-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/icon-2.png -------------------------------------------------------------------------------- /src/assets/common/images/icon-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/icon-3.png -------------------------------------------------------------------------------- /src/assets/common/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/logo.png -------------------------------------------------------------------------------- /src/assets/common/images/upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/upload.png -------------------------------------------------------------------------------- /src/assets/common/images/404/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/404/404.png -------------------------------------------------------------------------------- /src/assets/common/images/backtop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/backtop.png -------------------------------------------------------------------------------- /src/assets/common/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/loading.gif -------------------------------------------------------------------------------- /src/assets/common/images/404/404_msg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/404/404_msg.png -------------------------------------------------------------------------------- /src/assets/common/images/call_kefu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/call_kefu.png -------------------------------------------------------------------------------- /src/assets/common/images/loading_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/loading_1.gif -------------------------------------------------------------------------------- /src/assets/common/css/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/css/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /src/assets/common/images/404/error_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/404/error_bg.jpg -------------------------------------------------------------------------------- /src/assets/common/images/icon-left-jt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/icon-left-jt.png -------------------------------------------------------------------------------- /src/assets/common/images/icon-right-jt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/icon-right-jt.png -------------------------------------------------------------------------------- /src/assets/common/images/404/404_to_index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/404/404_to_index.png -------------------------------------------------------------------------------- /src/assets/common/images/404/error_cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/404/error_cloud.png -------------------------------------------------------------------------------- /src/assets/common/images/404/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/404/screenshot.jpg -------------------------------------------------------------------------------- /src/assets/common/images/PopLayer-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/PopLayer-close.png -------------------------------------------------------------------------------- /src/assets/common/images/default_big_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/default_big_img.png -------------------------------------------------------------------------------- /src/assets/common/images/gods-default-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangweianger/react16-webpack3.8-onepage-base-project/HEAD/src/assets/common/images/gods-default-icon.png -------------------------------------------------------------------------------- /src/redux/actionTypes.js: -------------------------------------------------------------------------------- 1 | /* 2 | * action 类型 3 | */ 4 | 5 | // 购物车 6 | export const GET_CART_NUMBER = 'GET_CART_NUMBER' 7 | export const UPDATE_CART_NUMBER = 'UPDATE_CART_NUMBER' //更新购物车数量 -------------------------------------------------------------------------------- /src/components/Loading.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default class Loading extends React.Component { 4 | render() { 5 | return
Loading...
6 | } 7 | } 8 | 9 | -------------------------------------------------------------------------------- /src/redux/actions/home.js: -------------------------------------------------------------------------------- 1 | import { 2 | UPDATE_CART_NUMBER, 3 | } from '../actionTypes' 4 | 5 | 6 | // 更新购物车数量 7 | export const updateCartNumber = (number) => { 8 | return { type: UPDATE_CART_NUMBER, number } 9 | } -------------------------------------------------------------------------------- /src/pages/user/router.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import asyncComponent from 'components/AsyncComponent' 3 | 4 | module.exports = [ 5 | { 6 | path: '/user', 7 | component: asyncComponent(() => import('./user')) 8 | }, 9 | ] 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /dist 3 | .idea/ 4 | .DS_Store 5 | src/.DS_Store 6 | src/assets/.DS_Store 7 | */.DS_Store 8 | */*/.DS_Store 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/commonjsx/footer.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | export default class Footer extends Component { 4 | render() { 5 | return ( 6 |
7 | 我是公共footer组件 8 |
9 | ) 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /src/commonjsx/header.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | export default class Header extends Component { 4 | render() { 5 | return ( 6 |
7 | 我是公共footer组件 8 |
9 | ) 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /src/pages/user/user.scss: -------------------------------------------------------------------------------- 1 | //home sass 2 | .home{ 3 | font-size:20px; 4 | font-weight:bold; 5 | text-align:center; 6 | margin-top:50px; 7 | .but{ 8 | padding:8px 10px; 9 | border:solid 1px #ccc; 10 | border-radius:3px; 11 | cursor:pointer; 12 | box-shadow:0 0 5px #ccc; 13 | } 14 | } -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | /dist/.* 3 | 4 | [include] 5 | 6 | [libs] 7 | 8 | [lints] 9 | 10 | [options] 11 | suppress_comment=.*\\$FlowFixMe 12 | suppress_comment=.*\\$FlowIssue 13 | esproposal.class_instance_fields=enable 14 | esproposal.class_static_fields=enable 15 | 16 | [strict] 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/pages/home/item/nav.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | require('../home.scss') 4 | 5 | export default class Home extends React.Component { 6 | constructor(props, context) { 7 | super(props, context) 8 | } 9 | 10 | render() { 11 | return ( 12 |
13 | 我是nav导航 14 |
15 | ) 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | react基础框架 9 | 10 | 11 | 12 |
13 | 14 | -------------------------------------------------------------------------------- /src/assets/common/js/common.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | //common 公共 AJAX 函数 4 | class common{ 5 | //初始化对象 6 | constructor(){ 7 | } 8 | 9 | // get ajax 10 | commonAjax(){ 11 | util.ajax({ 12 | url:config.baseApi+'', 13 | success:(data=>{ 14 | console.log(data) 15 | }) 16 | }) 17 | } 18 | } 19 | 20 | //初始化common对象 21 | module.exports=new common() 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/pages/home/child.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | require('./home.scss') 4 | 5 | export default class Child extends React.Component { 6 | constructor(props, context) { 7 | super(props, context) 8 | this.state = { 9 | username: 'wang' 10 | } 11 | } 12 | 13 | render() { 14 | return ( 15 |
我是 {this.props.match.path}的child
我也可以按需加载额
16 | ) 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/redux/reducers/cart.js: -------------------------------------------------------------------------------- 1 | import { 2 | UPDATE_CART_NUMBER, 3 | GET_CART_NUMBER, 4 | } from '../actionTypes' 5 | 6 | const initialState = { 7 | number:0 8 | } 9 | 10 | export default (state = initialState, action) => { 11 | switch (action.type) { 12 | case GET_CART_NUMBER: 13 | return { ...state, number: action.number } 14 | case UPDATE_CART_NUMBER: 15 | return { ...state, number: action.number } 16 | default: 17 | return state 18 | } 19 | } -------------------------------------------------------------------------------- /src/redux/reducers/home.js: -------------------------------------------------------------------------------- 1 | import { 2 | UPDATE_CART_NUMBER, 3 | GET_CART_NUMBER, 4 | } from '../actionTypes' 5 | 6 | const initialState = { 7 | number:10 8 | } 9 | 10 | export default (state = initialState, action) => { 11 | switch (action.type) { 12 | case GET_CART_NUMBER: 13 | return { ...state, number: action.number } 14 | case UPDATE_CART_NUMBER: 15 | return { ...state, number: action.number } 16 | default: 17 | return state 18 | } 19 | } -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins:[ 3 | // require('postcss-write-svg'), 4 | // require('postcss-px-to-viewport')({ 5 | // viewportWidth: 750, 6 | // viewportHeight: 1334, 7 | // unitPrecision: 5, 8 | // viewportUnit: 'vw', 9 | // selectorBlackList: [], 10 | // minPixelValue: 1, 11 | // mediaQuery: false 12 | // }), 13 | // require('postcss-aspect-ratio-mini'), 14 | ] 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/redux/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { createStore , applyMiddleware , combineReducers } from 'redux' 2 | import thunk from 'redux-thunk' 3 | import { routerReducer } from 'react-router-redux' 4 | 5 | import home from './home' 6 | import cart from './cart' 7 | 8 | const reducers = combineReducers({ 9 | routing: routerReducer, 10 | home, 11 | cart, 12 | }) 13 | 14 | // 创建 Redux 的 store 对象 15 | const store = createStore( 16 | reducers, 17 | applyMiddleware(thunk) 18 | ) 19 | 20 | export default store -------------------------------------------------------------------------------- /src/assets/common/js/config.js: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------后台配置------------------------------------------------*/ 2 | module.exports={ 3 | //登陆页面 4 | loginUrl:'/login.html', 5 | 6 | //登陆成功后需要跳转到的页面 7 | homeUrl: '/index.html', 8 | 9 | //根接口 10 | baseApi:'/api/', 11 | 12 | //ajax 请求超时时间 13 | ajaxtimeout:12000, 14 | 15 | //发送验证码时间间隔 16 | msgTime:60, 17 | 18 | //隐藏显示时间 19 | containerShowTime:10, 20 | 21 | //pagesize 分页数量 22 | pageSize:20, 23 | 24 | wangwei:'123456' 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/pages/home/two.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | require('./home.scss') 4 | 5 | export default class Two extends React.Component { 6 | constructor(props, context) { 7 | super(props, context) 8 | this.state = { 9 | username: 'wei' 10 | } 11 | } 12 | 13 | render() { 14 | return ( 15 |
16 |
17 | {this.state.username}
18 | 19 |
20 |
21 | ) 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from 'react' 3 | import { render } from 'react-dom' 4 | import { Provider } from 'react-redux' 5 | import store from './redux/reducers' 6 | import App from './App' 7 | // ant css 8 | import 'antd/dist/antd.css' 9 | 10 | //公用样式文件 11 | require('common/css/base.scss') 12 | 13 | // 弹窗 14 | import popup from 'popup' 15 | import $ from 'jquery' 16 | import config from 'common/js/config' 17 | import util from 'common/js/util' 18 | 19 | window.popup = popup 20 | window.config = config 21 | window.util = util 22 | window.$ = $ 23 | 24 | 25 | render( 26 | 27 | 28 | , 29 | document.getElementById('app') 30 | ) 31 | -------------------------------------------------------------------------------- /src/pages/home/home.scss: -------------------------------------------------------------------------------- 1 | //home sass 2 | .home{ 3 | font-size:20px; 4 | font-weight:bold; 5 | text-align:center; 6 | margin-top:50px; 7 | .but{ 8 | padding:8px 10px; 9 | border:solid 1px #ccc; 10 | border-radius:3px; 11 | cursor:pointer; 12 | box-shadow:0 0 5px #ccc; 13 | } 14 | } 15 | .mt20{ 16 | margin-top:20px; 17 | } 18 | .redux{ 19 | font-size:25px; 20 | color:red; 21 | } 22 | .button_add{ 23 | font-size:18px; 24 | border:solid 1px #000; 25 | color:#000; 26 | margin-left:20px; 27 | cursor:pointer; 28 | } 29 | .home-button{ 30 | padding:5px 10px; 31 | border:solid 1px #6f8fb7; 32 | margin-left:10px; 33 | cursor:pointer; 34 | color:#fff; 35 | background:#6f8fb7; 36 | border-radius:3px; 37 | } -------------------------------------------------------------------------------- /src/pages/home/router.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | import asyncComponent from 'components/AsyncComponent' 3 | 4 | module.exports = [ 5 | { 6 | path: '/', 7 | exact: true, 8 | component: asyncComponent(() => import('./home')) 9 | }, 10 | { 11 | path: '/one', 12 | component: asyncComponent(() => import('./one')), 13 | routes: [ 14 | { path: '/one/child', 15 | component: asyncComponent(() => import('./child')) 16 | }, 17 | ] 18 | }, 19 | { path: '/other/:id', 20 | component: asyncComponent(() => import('./child')) 21 | }, 22 | { 23 | path: '/two', 24 | component: asyncComponent(() => import('./two')), 25 | } 26 | 27 | ] 28 | -------------------------------------------------------------------------------- /src/redux/actions/cart.js: -------------------------------------------------------------------------------- 1 | import util from 'common/js/util' 2 | import { baseApi } from 'common/js/config' 3 | import { 4 | GET_CART_NUMBER, 5 | UPDATE_CART_NUMBER, 6 | } from '../actionTypes' 7 | 8 | 9 | // 获得购物车数量 10 | export const getCartNumber = () => { 11 | return (dispatch)=>{ 12 | util.ajax(baseApi+'native/cart/getTotalCartList', (data)=> { 13 | if (data.code === 1000) { 14 | dispatch({ 15 | type: UPDATE_CART_NUMBER, 16 | number:data.data.cartCount 17 | }) 18 | } 19 | }) 20 | } 21 | } 22 | 23 | // 更新购物车数量 24 | export const updateCartNumber_1 = (number) => { 25 | return { type: UPDATE_CART_NUMBER, number } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/assets/common/lib/page/page.css: -------------------------------------------------------------------------------- 1 | /*分页插件样式*/ 2 | /**width: 1180px; margin: 0 auto; text-align: center; */ 3 | .copot-page{width: 100%;} 4 | #copot-page{padding: 10px 0; color: #a9a9a9;} 5 | .copot-page a{display:inline-block;padding:5px 10px;border:solid 1px #E7E7E7;margin-right:5px;text-decoration:none;font-size:12px;background:#fff; color: #a9a9a9;} 6 | .copot-page a:hover{background:#4990e2;color:#fff;} 7 | .copot-page a.nowPage{background:#5974d9;border:solid 1px #5974d9;color:#fff;} 8 | .copot-page .Page-search-span{margin:0 5px 0 15px;} 9 | .copot-page #Page-search{width:40px;height:28px;padding-left:10px;margin:0 3px;border:solid 1px #E7E7E7;} 10 | .copot-page #pageSearch{width:40px;height:28px;font-size:12px;border:solid 1px #5974d9;background:#5974d9;color:#fff;cursor:pointer; } -------------------------------------------------------------------------------- /src/components/AsyncComponent.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | export default function asyncComponent(importComponent) { 4 | class AsyncComponent extends Component { 5 | constructor(props) { 6 | super(props) 7 | 8 | this.state = { 9 | component: null 10 | } 11 | } 12 | 13 | async componentDidMount() { 14 | const { default: component } = await importComponent() 15 | 16 | this.setState({ 17 | component: component 18 | }) 19 | } 20 | 21 | render() { 22 | const C = this.state.component 23 | 24 | return C ? : null 25 | } 26 | } 27 | 28 | return AsyncComponent 29 | } -------------------------------------------------------------------------------- /src/assets/common/js/format.js: -------------------------------------------------------------------------------- 1 | // 时间格式化 2 | if(!new Date().format){ 3 | Date.prototype.format = function (fmt) { //author: meizz 4 | var o = { 5 | 'M+': this.getMonth() + 1, //月份 6 | 'd+': this.getDate(), //日 7 | 'h+': this.getHours(), //小时 8 | 'H+':this.getHours()>12?this.getHours()-12:this.getHours(), 9 | 'm+': this.getMinutes(), //分 10 | 's+': this.getSeconds(), //秒 11 | 'q+': Math.floor((this.getMonth() + 3) / 3), //季度 12 | 'S': this.getMilliseconds() //毫秒 13 | } 14 | if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length)) 15 | for (var k in o) 16 | if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))) 17 | return fmt 18 | } 19 | } -------------------------------------------------------------------------------- /src/assets/common/js/echo.min.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | window.Echo=(function(window,document,undefined){'use strict';var store=[],offset,throttle,poll;var _inView=function(el){var coords=el.getBoundingClientRect();return((coords.top>=0&&coords.left>=0&&coords.top)<=(window.innerHeight||document.documentElement.clientHeight)+parseInt(offset));};var _pollImages=function(){for(var i=store.length;i--;){var self=store[i];if(_inView(self)){self.src=self.getAttribute('data-echo');store.splice(i,1);}}};var _throttle=function(){clearTimeout(poll);poll=setTimeout(_pollImages,throttle);};var init=function(obj){var nodes=document.querySelectorAll('[data-echo]');var opts=obj||{};offset=opts.offset||0;throttle=opts.throttle||250;for(var i=0;i { 24 | this.setState({ 25 | mod: mod.default ? mod.default : mod 26 | }) 27 | }) 28 | } 29 | render() { 30 | return this.state.mod ? this.props.children(this.state.mod) : null 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/components/Bundle.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | export default class Bundle extends Component { 4 | constructor(props, context){ 5 | super(props, context) 6 | this.state = { 7 | // short for "module" but that's a keyword in js, so "mod" 8 | mod: null 9 | } 10 | } 11 | componentWillMount() { 12 | this.load(this.props) 13 | } 14 | componentWillReceiveProps(nextProps) { 15 | if (nextProps.load !== this.props.load) { 16 | this.load(nextProps) 17 | } 18 | } 19 | load(props) { 20 | this.setState({ 21 | mod: null 22 | }) 23 | props.load((mod) => { 24 | this.setState({ 25 | // handle both es imports and cjs 26 | mod: mod.default ? mod.default : mod 27 | }) 28 | }) 29 | } 30 | render() { 31 | return this.state.mod ? this.props.children(this.state.mod) : null 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/assets/common/css/common.scss: -------------------------------------------------------------------------------- 1 | //数据为空时的提示样式 2 | .data_list_empty{display:inline-block;width:64px;height:64px;background:url('../images/empty.png') no-repeat center center;} 3 | //-----数据为空时的提示样式结束----- 4 | 5 | //禁止选中样式 6 | .user_select{ 7 | -moz-user-select: none; 8 | -o-user-select:none; 9 | -khtml-user-select:none; 10 | -webkit-user-select:none; 11 | -ms-user-select:none; 12 | user-select:none; 13 | } 14 | 15 | .nav{ 16 | overflow:hidden; 17 | width:350px; 18 | margin:30px auto 0px; 19 | li{ 20 | float:left; 21 | padding:10px 20px; 22 | } 23 | } 24 | 25 | .btn{ 26 | padding:8px 15px; 27 | border:solid 1px #ddd; 28 | } 29 | .input{ 30 | height:35px; 31 | border:solid 1px #ddd; 32 | padding-left:10px; 33 | } 34 | /*------------------css 1px解决方案-----------------------*/ 35 | .c-b-l:before { @include common-border-one(left,$C2); } 36 | .c-b-r:before { @include common-border-one(right,$C2); } 37 | .c-b-t:before { @include common-border-one(top,$C2); } 38 | .c-b-b:before { @include common-border-one(bottom,$C2); } 39 | .c-b-c:after{ @include common-border-all($C2,0); } 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/pages/user/user.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | require('./user.scss') 4 | 5 | export default class User extends React.Component { 6 | constructor(props, context){ 7 | super(props, context) 8 | this.state = { 9 | datas:[ 10 | {id:1,name:'wangwei',sex:'男',hobby:'羽毛球,游泳,旅游'}, 11 | {id:2,name:'zhangsan',sex:'男',hobby:'篮球,台球,游泳'}, 12 | {id:3,name:'xiaofang',sex:'女',hobby:'羽毛球,游泳,旅游'} 13 | ] 14 | } 15 | } 16 | 17 | alertId(item){ 18 | alert('我的编号是'+item.id) 19 | } 20 | 21 | render() { 22 | return ( 23 |
24 |
25 | {this.state.datas.map(item => ( 26 |
  • 27 | 姓名:{item.name} 28 | 性别:{item.sex} 29 | 爱好:{item.hobby} 30 | 31 |
  • 32 | ))} 33 |
    34 |
    35 | ) 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/assets/common/css/vars.scss: -------------------------------------------------------------------------------- 1 | 2 | // sass相关备注 3 | 4 | $C1:#333; //黑色主色调 5 | $C2:#f0f0f0; //border边线色调 6 | $C3:#F04848; // 主红色色调 7 | 8 | 9 | 10 | 11 | 12 | /*------------------css 1px解决方案-----------------------*/ 13 | @mixin common-border-one ($type,$color) { 14 | content: ''; 15 | position: absolute; 16 | @if $type == left { 17 | height:100%; 18 | width:1px; 19 | left:0; 20 | top:0; 21 | transform: scaleX(0.5); 22 | border-left: 1px solid $color; 23 | } @else if $type == right { 24 | height:100%; 25 | width:1px; 26 | right:0; 27 | top:0; 28 | transform: scaleX(0.5); 29 | border-right: 1px solid $color; 30 | } @else if $type == top { 31 | height:1px; 32 | width:100%; 33 | left:0; 34 | top:0; 35 | transform: scaleY(0.5); 36 | border-top: 1px solid $color; 37 | } @else { 38 | height:1px; 39 | width:100%; 40 | bottom:0; 41 | left:0; 42 | transform: scaleY(0.5); 43 | border-bottom: 1px solid $color; 44 | } 45 | z-index: 1; 46 | } 47 | @mixin common-border-all ($color,$radius) { 48 | position: absolute; 49 | top: -0.5px; 50 | left: -0.5px; 51 | width: 200%; 52 | height: 200%; 53 | content: ''; 54 | border: 1px solid $color; 55 | border-radius: $radius; 56 | transform: scale(0.5); 57 | transform-origin: top left; 58 | z-index: -1; 59 | display:block; 60 | } -------------------------------------------------------------------------------- /src/pages/home/one.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { renderRoutes } from 'react-router-config' 3 | import { Link } from 'react-router-dom' 4 | 5 | 6 | require('./home.scss') 7 | 8 | export default class One extends React.Component { 9 | constructor(props, context) { 10 | super(props, context) 11 | this.state = { 12 | username: 'wang' 13 | } 14 | } 15 | handler(e){ 16 | console.log(this) 17 | } 18 | 19 | handlerone(e){ 20 | console.log('000') 21 | let id = 0 22 | this.props.history.push(`/other/${id}`) 23 | } 24 | 25 | render() { 26 | return ( 27 |
    28 |
    29 | 加载child /one/child 路由 30 | /one/child 31 |
    32 | 33 |
    34 | 加载动态路由 35 | 36 |
    37 | 38 |
    39 | {this.state.username}
    40 | 41 |
    42 |
    43 | {renderRoutes(this.props.route.routes)} 44 |
    45 | 46 |
    47 | ) 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react 集成开发框架 2 | 3 | > * 使用知识点: 4 | >  * react          5 | > * webpack 前端自动话打包工具 6 | > * react-router-dom 7 | > * react-redux 8 | > * redux 9 | > * babel 10 | 11 | ## 项目webpack 优化说明文档 12 | ## http://blog.seosiwei.com/detail/9 13 | 14 | ## react-router的4种异步加载方式 15 | ## http://blog.seosiwei.com/detail/10 16 | 17 | ## 基于react-router-config的路由拆分 18 | ## http://blog.seosiwei.com/detail/11 19 | 20 | ## 项目步骤 21 | 22 | 1.安装node.js 23 | 24 | 2.安装项目依赖包 25 | 26 | ``` 27 | npm install 28 | 或 29 | yarn install 30 | ``` 31 | 32 | 3.运行开发环境 33 | 34 | ``` 35 | npm run dev 36 | 37 | ``` 38 | 39 | 4.打包生产文件 40 | 41 | ``` 42 | npm run build:dll //此命令一般只运行一次 请参考上面weboack构建优化文章说明 43 | 44 | npm run build 45 | 46 | ``` 47 | 48 | 49 | ### 增加flow 50 | - 参考链接: flow使用请参考官网:https://flow.org/ 51 | 52 | 53 | ``` 54 | 使用flow检查的文件在顶部增加 55 | // @flow 或者 /* @flow */ 标识 56 | 57 | 检查全部文件 58 | npm run flow 59 | 60 | ``` 61 | 62 | ### 如果Sublime要开启eslint的flow检测 需要做如下另个步骤 63 | 64 | - 1.安装 npm install babel-preset-flow --save-dev npm install flow-bin --save-dev 65 | - 2.sublime text安装 flow SublimeLinter-flow两个插件 66 | - 参考链接:https://flow.org/en/docs/editors/sublime-text/ 67 | 68 | 69 | ### 新增eslint代码检查 70 | - sublime text 安装插件:SublimeLinter,SublimeLinter-contrib-eslint 插件 71 | 参考链接: 72 | - https://eslint.org/docs/user-guide/integrations 73 | - http://www.jianshu.com/p/e826e13c67ec 74 | - 提醒:提交代码之前会进行 eslint 检测,若检测不通过提交不了代码。 75 | 76 | ### DEMO图片 77 | ![](https://github.com/wangweianger/react16-webpack3.8-onepage-base-project/blob/master/demoImg/01.png "") 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "plugins": [ 4 | "react" 5 | ], 6 | "env": { 7 | "es6": true, 8 | "browser": true, 9 | "node": true, 10 | "commonjs": true, 11 | "worker": true, 12 | "amd": true, 13 | "mocha": true, 14 | "jest": true, 15 | "jquery": true, 16 | "serviceworker": true 17 | }, 18 | "globals": { 19 | "popup": false, 20 | "config":true, 21 | "util":false 22 | }, 23 | "settings": { 24 | "import/ignore": [ 25 | "node_modules" 26 | ], 27 | "react": { 28 | "createClass": "createReactClass", 29 | "pragma": "React", 30 | "version": "16.0", 31 | "flowVersion": "0.59" 32 | }, 33 | }, 34 | "parserOptions": { 35 | "ecmaVersion": 6, 36 | "sourceType": "module", 37 | "ecmaFeatures": { 38 | "jsx": true 39 | } 40 | }, 41 | "extends": [ 42 | "eslint:recommended", 43 | "plugin:react/recommended" 44 | ], 45 | "rules": { 46 | "indent": [2, 4], //空格数 47 | "quotes": [2, "single"], //单双引号 48 | "linebreak-style": [2, "unix"], 49 | "semi": [2, "never"], 50 | "no-cond-assign": 2, //禁止条件表达式中出现赋值操作符 51 | "no-constant-condition": 2, //禁止在条件中使用常量表达式 52 | "no-control-regex":0, //正则 53 | "no-dupe-args": 2, //禁止函数参数同名 54 | "no-dupe-keys": 2, //禁止json中重复的key 55 | "no-duplicate-case": 2, //禁止switch同样的case条件 56 | "no-console": 0, //禁止出现console 57 | "no-debugger": 0, //禁止出现debugger 58 | "no-alert":0, //禁止出现alert 59 | "no-var": 0, //禁止出现没定义的var 60 | "no-empty":0, //禁止出现空语句块 61 | "no-trailing-spaces": 0, //禁用行尾空白 62 | "no-empty-character-class":2, //禁止在正则表达式中使用空字符集 63 | "no-ex-assign":2, //禁止对 catch 子句中的异常重新赋值 64 | "no-extra-boolean-cast":2, //禁止不必要的布尔类型转换 65 | "no-extra-semi":2, //禁用不必要的分号 66 | "no-func-assign":2, //禁止对 function 声明重新赋值 67 | "no-inner-declarations":2, //禁止在嵌套的块中出现变量声明或 function 声明 68 | "no-irregular-whitespace":2, //禁止在字符串和注释之外不规则的空白 69 | "no-obj-calls":2, //禁止将全局对象当作函数进行调用 70 | "no-sparse-arrays":2, //禁用稀疏数组 71 | "use-isnan":2, //要求使用 isNaN() 检查 NaN 72 | "valid-typeof":2, //强制 typeof 表达式与有效的字符串进行比较 73 | "eol-last": 0, //要求或禁止文件末尾存在空行 74 | "no-unused-vars": 0, //禁止出现未使用过的变量 75 | "no-underscore-dangle": 0, 76 | "no-lone-blocks": 0, 77 | "jsx-quotes": 1, //强制在 JSX 属性中一致地使用双引号或单引号 78 | "react/prop-types":0, 79 | } 80 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react16-webpack3.8-onepage-base-project", 3 | "version": "1.0.0", 4 | "description": "基础架子", 5 | "main": "index.js", 6 | "scripts": { 7 | "flow": "flow check --all", 8 | "dev": "cross-env PROT=8000 node build/webpack.dev.config.js", 9 | "test": "webpack -d --progress --hide-modules --colors --config build/webpack.test.config.js", 10 | "test:dll": "cross-env BUILD_TYPE=test webpack --progress --config build/webpack.dll.config.js", 11 | "build": "webpack --progress --colors --config build/webpack.product.config.js", 12 | "build:dll": "cross-env BUILD_TYPE=build webpack --progress --config build/webpack.dll.config.js", 13 | "eslint": "eslint src " 14 | }, 15 | "pre-commit": [ 16 | "eslint" 17 | ], 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/wangweianger/react16-webpack3.8-onepage-base-project.git" 21 | }, 22 | "keywords": [ 23 | "react", 24 | "react-router", 25 | "webpack", 26 | "redux" 27 | ], 28 | "author": "zane", 29 | "license": "ISC", 30 | "homepage": "http://blog.seosiwei.com/", 31 | "devDependencies": { 32 | "babel-cli": "^6.26.0", 33 | "babel-core": "^6.26.0", 34 | "babel-eslint": "^8.0.2", 35 | "babel-loader": "^7.1.2", 36 | "babel-plugin-syntax-dynamic-import": "^6.18.0", 37 | "babel-plugin-transform-object-rest-spread": "^6.26.0", 38 | "babel-polyfill": "^6.26.0", 39 | "babel-preset-env": "^1.6.1", 40 | "babel-preset-flow": "^6.23.0", 41 | "babel-preset-react": "^6.24.1", 42 | "bundle-loader": "^0.5.5", 43 | "cross-env": "^5.1.1", 44 | "css-loader": "^0.28.7", 45 | "eslint": "^4.10.0", 46 | "eslint-loader": "^1.9.0", 47 | "eslint-plugin-react": "^7.4.0", 48 | "extract-text-webpack-plugin": "^3.0.2", 49 | "file-loader": "^1.1.5", 50 | "flow-bin": "^0.59.0", 51 | "happypack": "^4.0.0", 52 | "html-webpack-plugin": "^2.30.1", 53 | "jquery": "^3.2.1", 54 | "node-sass": "^4.6.0", 55 | "open-browser-webpack-plugin": "^0.0.5", 56 | "pre-commit": "^1.2.2", 57 | "react": "^16.0.0", 58 | "react-dom": "^16.0.0", 59 | "react-loadable": "^5.3.1", 60 | "react-redux": "^5.0.6", 61 | "react-router-config": "^1.0.0-beta.4", 62 | "react-router-dom": "^4.2.2", 63 | "react-router-redux": "^4.0.8", 64 | "redux": "^3.7.2", 65 | "redux-thunk": "^2.2.0", 66 | "sass-loader": "^6.0.6", 67 | "string-replace-loader": "^1.3.0", 68 | "style-loader": "^0.19.0", 69 | "url-loader": "^0.6.2", 70 | "webpack": "^3.8.1", 71 | "webpack-cleanup-plugin": "^0.5.1", 72 | "webpack-dev-server": "^2.9.4", 73 | "webpack-dll-loader": "^0.0.1", 74 | "webpack-parallel-uglify-plugin": "^1.0.0", 75 | "zane-calendar": "^2.2.4" 76 | }, 77 | "dependencies": { 78 | "antd": "^3.11.6" 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/pages/home/home.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { connect } from 'react-redux' 3 | import zaneDate from 'zane-calendar' 4 | import { DatePicker, Button, Checkbox } from 'antd' 5 | 6 | require('./home.scss') 7 | 8 | import { updateCartNumber } from 'actions' 9 | 10 | class Home extends React.Component { 11 | constructor(props, context) { 12 | super(props, context) 13 | this.state = { 14 | username: 'wangweianger00', 15 | begintime:'', 16 | } 17 | console.log(props) 18 | } 19 | 20 | componentDidMount(){ 21 | zaneDate({ 22 | elem:'#zane-calendar', 23 | done:(fulltime,begintime,endtime)=>{ 24 | this.setState({ 25 | begintime:begintime 26 | }) 27 | } 28 | }) 29 | } 30 | 31 | handleAlert(e){ 32 | popup.alert({title:'Alert弹窗'}) 33 | } 34 | 35 | handleConfirm(e){ 36 | popup.confirm({title:'确定执行吗?',yes(){ 37 | alert('执行了!') 38 | }}) 39 | } 40 | handleAddNumber(){ 41 | const { number,dispatch } = this.props 42 | dispatch(updateCartNumber(number+1)) 43 | } 44 | 45 | onChange(e) { 46 | console.log(`checked = ${e.target.checked}`) 47 | } 48 | 49 | render() { 50 | const { number } = this.props 51 | return ( 52 |
    53 |
    54 | redux中的number值为 { number } 55 | 56 |
    57 |
    58 | Checkbox 59 |
    60 |
    61 | 62 | 63 | 64 | 65 |
    66 |
    67 | 68 |
    69 |
    70 | 时间日历插件 71 | 72 |
    73 |
    74 | 75 | 76 |
    77 |
    78 | {this.state.username}
    79 | 80 |
    81 | 82 |
    83 | ) 84 | } 85 | } 86 | 87 | // 获取购物车数量 88 | const mapStateToProps = (state) => { 89 | return { 90 | number:state.home.number 91 | } 92 | } 93 | export default connect(mapStateToProps)(Home) -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { connect } from 'react-redux' 3 | import { 4 | BrowserRouter as Router, 5 | Link 6 | } from 'react-router-dom' 7 | import { renderRoutes } from 'react-router-config' 8 | 9 | /*------------------------------react-loadable按需加载-------------------------------------------*/ 10 | // import Loadable from 'react-loadable'; 11 | // import Loading from './components/Loading' 12 | // const Home = Loadable({loader: () => import('./pages/home/home'),loading:Loading}); 13 | // const One = Loadable({loader: () => import('./pages/home/one'),loading:Loading}); 14 | // const Two = Loadable({loader: () => import('./pages/home/two'),loading:Loading}); 15 | // const User = Loadable({loader: () => import('./pages/user/user'),loading:Loading}); 16 | 17 | /*------------------------------bundle-loader按需加载---------------------------------------------*/ 18 | // import Bundle from './components/Bundle' 19 | // import loadHome from 'bundle-loader?lazy!./pages/home/home' 20 | // import loadOne from 'bundle-loader?lazy!./pages/home/one' 21 | // import loadTwo from 'bundle-loader?lazy!./pages/home/two' 22 | // import loadUser from 'bundle-loader?lazy!./pages/user/user' 23 | 24 | // const Home = (props) => ({(Home) => }) 25 | // const One = (props) => ({(One) => }) 26 | // const Two = (props) => ({(Two) => }) 27 | // const User = (props) => ({(User) => } ) 28 | 29 | /*-------------------------------import按需加载------------------------------------------------------*/ 30 | // import Bundle from './components/BundleImport' 31 | // const Home = (props) => ( import('./pages/home/home')}>{(Chat) => }); 32 | // const One = (props) => ( import('./pages/home/one')}>{(Chat) => }); 33 | // const Two = (props) => ( import('./pages/home/two')}>{(Chat) => }); 34 | // const User = (props) => ( import('./pages/user/user')}>{(Chat) => }); 35 | 36 | /*--------------------------------Create an Async Componen按需加载-------------------------------------*/ 37 | // import asyncComponent from './components/AsyncComponent'; 38 | // const Home = asyncComponent(() => import("./pages/home/home")); 39 | // const One = asyncComponent(() => import("./pages/home/one")); 40 | // const Two = asyncComponent(() => import("./pages/home/two")); 41 | // const User = asyncComponent(() => import("./pages/user/user")); 42 | 43 | 44 | // 合并路由 45 | const routes = [ 46 | ...require('pages/home/router'), 47 | ...require('pages/user/router') 48 | ] 49 | 50 | class App extends Component { 51 | constructor(props,context) { 52 | super(props,context) 53 | } 54 | 55 | render() { 56 | return ( 57 | 58 |
    59 |
      60 |
    • Home
    • 61 |
    • One
    • 62 |
    • Two
    • 63 |
    • User
    • 64 |
    65 | {renderRoutes(routes)} 66 | 67 | {/* 68 | 69 | 70 | */} 71 |
    72 |
    73 | ) 74 | } 75 | } 76 | 77 | export default connect()(App) 78 | 79 | -------------------------------------------------------------------------------- /src/assets/common/lib/popup/popup.css: -------------------------------------------------------------------------------- 1 | /*layer-mobile-css*/ 2 | @keyframes popScaleShow{from{opacity: 0;}to{opacity: 1;}} 3 | @-webkit-keyframes popScaleShow{from{opacity: 0;}to{opacity: 1;}} 4 | @keyframes popScale{from{opacity: 0;transform:scale(0.5,0.5);}to{opacity: 1;transform:scale(1,1);}} 5 | @-webkit-keyframes popScale{from{opacity: 0;-webkit-transform:scale(0.5,0.5);}to{opacity: 1;-webkit-transform:scale(1,1);}} 6 | iframe { display: block;} 7 | .popup{width:100%;box-sizing:border-box;height:100%;position: fixed;left:0;top:0;z-index:100000;animation:popScaleShow 300ms linear;-webkit-animation:popScaleShow 300ms linear;} 8 | .popup .mask{width:100%;height:100%;position: absolute;left:0;top:0;background: rgba(0,0,0,.6);z-index:-1;} 9 | .popup .popup_main{position:fixed;left:50%;top:50%;min-width:350px;min-height:100px;overflow:hidden;max-width:90%!important; 10 | transform:translateX(-50%);-webkit-transform:translateX(-50%);background:transparent; 11 | } 12 | .maminContent{width:100%;height:100%;background: #fff;overflow: hidden;animation:popScale 300ms;-webkit-animation:popScale 300ms;} 13 | .popup .maskMain{background:rgba(0,0,0,.6);color:#fff;} 14 | .popup .header_poup{height:30px;padding-left:46px;margin-top:10px;line-height:50px;position: relative;font-size:16px;} 15 | .popup .header_poup span{display:block;width:15px;height:15px;cursor:pointer;background: url('../../images/PopLayer-close.png') no-repeat top center;background-size:80% 80%;position: absolute;right:20px;top:15px;} 16 | .popup .header_poup i{width:25px;height:25px;display:inline-block;background: url('../../images/icon-1.png') no-repeat center center;position: absolute; 17 | left:15px;top:10px; 18 | } 19 | .popup .header_poup i.icon-1{background: url('../../images/icon-1.png') no-repeat center center;} 20 | .popup .header_poup i.icon-2{background: url('../../images/icon-2.png') no-repeat center center;} 21 | .popup .header_poup i.icon-3{background: url('../../images/icon-3.png') no-repeat center center;} 22 | .popup .content{line-height:25px;padding:30px 20px 10px 50px;color:#888;} 23 | .popup .footer{height:60px;width:100%;line-height: 40px;position: relative;margin-top:20px;padding-left:50px;} 24 | .popup .footer span{font-size:14px;height:35px;line-height:35px;cursor:pointer;display:inline-block;text-align:center;color:#4a4a4a;} 25 | .popup .footer .yes{padding:0px 25px;background: #ff4200;color:#fff;border-radius:5px;} 26 | .popup .footer .yes:hover, 27 | .popup .footer .yes5:hover{background:#ef6536;} 28 | .popup .footer .yes5{} 29 | .popup .footer .yesok{background:#ff4200;} 30 | .popup .footer .no{padding:0 15px;border:solid 1px #999;border-radius: 5px;margin-left:15px;} 31 | .popup .footer .no:hover{background:#e8e3e3;} 32 | .popup-hide .popup_main{min-width:100px;} 33 | .popup-hide .popup_main .content{line-height:50px;} 34 | .popup-hide .content{text-align:center;} 35 | .popup-loading{cursor: wait;} 36 | .popup-loading .popup_main{min-width:150px;height:60px;padding:0 15px 0 5px;} 37 | .popup-loading .popup_main .content{line-height:60px;} 38 | .popup-loading .popup_main .content:before{content: "";display: block;width:40px;height:60px;background: url('../../images/loading.gif') no-repeat center center;float:left; 39 | background-size: 60%;margin-top:-15px; 40 | } 41 | .popup-loading .content{text-align:center;} 42 | .popup .html{line-height:25px;} 43 | .popup-iframe .popup_main{width:80%;height:80%;left:10%;top:10%;} 44 | .popup-iframe .popup_main .contentios{overflow-scrolling:touch;-webkit-overflow-scrolling:touch;overflow-y: scroll; } 45 | .popup .yesHtml{text-align:center;cursor:pointer;color:#f48e08;padding-top:15px;border-top:solid 1px #dcdcdc;} 46 | .popup .yesHtml:hover{color:#b76b07;} 47 | .popup .popup_main .content-no{padding-top:12px;padding-bottom:12px;line-height:25px;} 48 | .popup .popup_main .miss_popup{border-radius: 5px!important;color:#fff;} 49 | .popup .popup_main .miss_popup .content-no{padding-left:20px;color:#fff;} -------------------------------------------------------------------------------- /src/assets/common/css/base.scss: -------------------------------------------------------------------------------- 1 | @import "./vars.scss"; 2 | 3 | /*CSS Reset*/ 4 | *, *:before, *:after { -webkit-box-sizing: border-box; box-sizing: border-box; }; 5 | body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td, header, hgroup, nav, section, article, aside, footer, figure, figcaption, menu, button { 6 | margin: 0; padding: 0; font-family: '微软雅黑'; 7 | }; 8 | body{background:#f5f5f5;max-width:750px;margin:0 auto;} 9 | body { font-family: Helvetica, STHeiTi, Sans-serif; line-height: 1.5; font-size: 14px; color: #333; -webkit-text-size-adjust: none; -webkit-tap-highlight-color: rgba(255, 255, 255, 0); outline: 0; } 10 | h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: normal; } 11 | table { border-collapse: collapse; border-spacing: 0; } 12 | fieldset, img { border: 0; } 13 | li { list-style: none; } 14 | input, textarea, select { font-family: inherit; font-size: inherit; font-weight: inherit; outline: none; -webkit-appearence: none; -ms-appearence: none; } 15 | button, html input[type="button"], input[type="reset"], input[type="submit"] { border: none; background: none; -webkit-appearance: none; outline: none; } 16 | a { -webkit-touch-callout: none; text-decoration: none; outline: 0; color:#6f8fb7;text-decoration:none;} 17 | em, i { font-style: normal; } 18 | iframe { display: none; } 19 | ::-webkit-input-placeholder { 20 | color: #999; 21 | } 22 | 23 | // 增加相关样式 youwei 2016/8/13 10:58:17 24 | .input-inline{ 25 | display: inline-block; 26 | width: auto; 27 | vertical-align: middle; 28 | } 29 | 30 | //一些列的边距样式 31 | .m5{margin: 5px;} 32 | .m10{margin: 10px;} 33 | .m15{margin: 15px;} 34 | .m20{margin: 20px;} 35 | .mt5{margin-top: 5px;} 36 | .mt10{margin-top: 10px;} 37 | .mt15{margin-top: 15px;} 38 | .mt20{margin-top: 20px;} 39 | .ml5{margin-left: 5px;} 40 | .ml10{margin-left: 10px;} 41 | .ml15{margin-left: 15px;} 42 | .ml20{margin-left: 20px;} 43 | .ml30{margin-left: 30px;} 44 | .mr5{margin-right: 5px;} 45 | .mr10{margin-right: 10px;} 46 | .mr15{margin-right: 15px;} 47 | .mr20{margin-right: 20px;} 48 | .mb5{margin-bottom: 5px;} 49 | .mb10{margin-bottom: 10px;} 50 | .mb15{margin-bottom: 15px;} 51 | .mb20{margin-bottom: 20px;} 52 | .mb30{margin-bottom: 30px;} 53 | //-----一些列的边距样式结束----- 54 | 55 | //等待加载样式 56 | #loading{display:none;background: url(../images/loading_1.gif) rgba(12,12,12,.2) no-repeat center center;position: fixed;width: 100%;height: 100%;top:0;left:0;} 57 | //--------等待加载样式结束--------- 58 | 59 | //字体相关样式 60 | html,body {color: #333;} 61 | a:hover{text-decoration:none;} 62 | 63 | .fs-12{font-size:12px;} 64 | .fs-14{font-size:14px;} 65 | .fs-16{font-size:16px;} 66 | .fs-18{font-size:18px;} 67 | .fs-20{font-size:20px;} 68 | .fs-25{font-size:25px;} 69 | 70 | .clear{clear:both} 71 | .blod{font-weight:blod;} 72 | .normal{font-weight:normal;} 73 | .cursor{cursor: pointer;} 74 | 75 | .tl{text-align:left;} 76 | .tc{text-align:center;} 77 | .tr{text-align:right;} 78 | 79 | .fl{float:left;} 80 | .fr{float:right;} 81 | 82 | .inline-block{display:inline-block;} 83 | 84 | .w-50{width:50px;} 85 | .w-80{width:80px;} 86 | .w-100{width:100px;} 87 | .w-150{width:150px;} 88 | .w-200{width:200px;} 89 | .w-250{width:250px;} 90 | .w-300{width:300px;} 91 | .w-400{width:400px;} 92 | .w-500{width:500px;} 93 | 94 | 95 | //阿里icon样式 96 | @font-face { 97 | font-family: 'iconfont'; /* project id:"133474" */ 98 | src: url('//at.alicdn.com/t/font_6gg3y6tm884wvcxr.eot'); 99 | src: url('//at.alicdn.com/t/font_6gg3y6tm884wvcxr.eot?#iefix') format('embedded-opentype'), 100 | url('//at.alicdn.com/t/font_6gg3y6tm884wvcxr.woff') format('woff'), 101 | url('//at.alicdn.com/t/font_6gg3y6tm884wvcxr.ttf') format('truetype'), 102 | url('//at.alicdn.com/t/font_6gg3y6tm884wvcxr.svg#iconfont') format('svg'); 103 | } 104 | 105 | @mixin icon-font ($sizing) { 106 | font-family:"iconfont"; 107 | font-size:$sizing; 108 | font-style:normal; 109 | vertical-align: middle; 110 | } 111 | .iconfont{@include icon-font(16px)} 112 | //------阿里icon样式结束-------- 113 | 114 | @import 'common.scss'; 115 | 116 | 117 | -------------------------------------------------------------------------------- /src/assets/common/lib/page/page.js: -------------------------------------------------------------------------------- 1 | import util from 'common/js/util' 2 | import popup from 'popup' 3 | 4 | require('./page.css') 5 | 6 | function Page(json) { 7 | this.route = json.route 8 | this.routerName = json.routerName 9 | this.nowPage = parseInt(json.nowPage) //当前页 10 | this.parent = json.parent //分页内容所放的div元素 11 | this.call = json.callback 12 | this.totalCount = json.totalCount 13 | this.pageSize = json.pageSize 14 | this.totalPage = Math.ceil(this.totalCount / this.pageSize) //总页数 15 | this.html = '' 16 | this.type = json.type || 1 17 | this.setting = json.setting || { 18 | defaultPage: 5, //默认展示的页数 19 | firstPageText: '首页', //第一页的字 (可以是:Home) 20 | prevPageText: '上一页', //上一页的字 21 | nextPageText: '下一页', //下一页的字 22 | lastPageText: '最后一页' //尾页的字 23 | } 24 | this.centPage = Math.ceil(this.setting.defaultPage / 2) //中间页 25 | this.init() //初始化 26 | } 27 | //初始化函数 28 | Page.prototype.init = function() { 29 | this.parent.html('') //清空 30 | this.totalPageText() //页数显示信息 31 | this.firstPage() //首页 32 | this.prevPageText() //上一页 33 | this.everyPage()//分页 34 | this.nextPage() //下一页 35 | this.lastPage() //尾页 36 | this.pageSearch() //搜索页 37 | this.parent.append(this.html) 38 | this.callback() 39 | } 40 | 41 | //循环页数 42 | Page.prototype.everyPage = function() { 43 | if (this.totalPage <= this.setting.defaultPage) { 44 | for (var i = 1; i <= this.totalPage; i++) { 45 | if (this.nowPage == i) { 46 | this.html += '' + i + '' 47 | } else { 48 | this.html += '' + i + '' 49 | } 50 | } 51 | } else { 52 | for (let i = 1; i <= this.setting.defaultPage; i++) { 53 | var page1 = this.nowPage - this.centPage + i 54 | var page2 = this.totalPage - this.setting.defaultPage + i 55 | 56 | if (this.nowPage < this.centPage) { 57 | if (this.nowPage == i) { 58 | this.html += '' + i + '' 59 | } else { 60 | this.html += '' + i + '' 61 | } 62 | } else if (this.nowPage > this.totalPage - this.centPage) { 63 | if (this.setting.defaultPage - (this.totalPage - this.nowPage) == i) { 64 | this.html += '' + this.nowPage + '' 65 | } else { 66 | this.html += '' + page2 + '' 67 | } 68 | } else { 69 | if (this.centPage == i) { 70 | this.html += '' + page1 + '' 71 | } else { 72 | this.html += '' + page1 + '' 73 | } 74 | } 75 | } 76 | } 77 | } 78 | 79 | //首页 80 | Page.prototype.firstPage = function() { 81 | if (this.nowPage > this.centPage && this.totalPage >= this.setting.defaultPage + 1) { 82 | this.html += '' + this.setting.firstPageText + '' 83 | } 84 | } 85 | //上一页 86 | Page.prototype.prevPageText = function() { 87 | if (this.nowPage >= 2) { 88 | this.html += '' + this.setting.prevPageText + '' 89 | } 90 | } 91 | 92 | //下一页 93 | Page.prototype.nextPage = function() { 94 | if (this.totalPage - this.nowPage >= 1) { 95 | this.html += '' + this.setting.nextPageText + '' 96 | } 97 | } 98 | 99 | //尾页 100 | Page.prototype.lastPage = function() { 101 | if (this.totalPage - this.nowPage >= this.centPage && this.totalPage > this.setting.defaultPage) { 102 | this.html += '' + this.setting.lastPageText + '' 103 | } 104 | } 105 | 106 | //总共页数 107 | Page.prototype.totalPageText = function() { 108 | this.html += '' + this.totalCount + ' 条记录 共' + this.totalPage + '    ' 109 | } 110 | 111 | //搜索页数 112 | Page.prototype.pageSearch = function() { 113 | if (this.totalPage > this.setting.defaultPage) { 114 | this.html += '跳转到' 115 | } 116 | } 117 | 118 | //点击分页执行的函数 119 | Page.prototype.callback = function() { 120 | let This = this 121 | let searchpage = null 122 | 123 | if (this.type == 1) { 124 | //按hash值改变分页 125 | this.parent.find('a').bind('click', function(event) { 126 | event.preventDefault() //阻止默认行为 ( 表单提交 ) 127 | var nowPage = $(this).attr('href').substring(1) 128 | //请求路由 129 | // router.push({ 130 | // name: This.routerName, 131 | // query: { 132 | // page: nowPage 133 | // } 134 | // }) 135 | This.getPage(nowPage) 136 | }) 137 | //输入搜索查询 138 | $(document).keydown(function(event) { 139 | if (event.keyCode == 13) { 140 | searchpage() 141 | } 142 | }) 143 | this.parent.find('#pageSearch').click(function() { 144 | searchpage() 145 | }) 146 | searchpage=function(){ 147 | var nowPage = This.parent.find('#Page-search').val() 148 | if (parseInt(nowPage) > This.totalPage) { 149 | This.parent.find('#Page-search').val('') 150 | popup.miss({ 151 | title: '超出搜索页数!' 152 | }) 153 | return false 154 | } 155 | if (parseInt(nowPage) > 0) { 156 | //请求路由 157 | // router.push({ 158 | // name: This.routerName, 159 | // query: { 160 | // page: nowPage 161 | // } 162 | // }) 163 | This.getPage(nowPage) 164 | } 165 | } 166 | } else if (this.type == 2) { 167 | //给每个a绑定事件 168 | this.parent.find('a').bind('click', function() { 169 | var nowPage = $(this).attr('href').substring(1) 170 | This.getPage(nowPage) 171 | return false 172 | }) 173 | //输入搜索查询 174 | this.parent.find('#pageSearch').click(function() { 175 | var nowPage = This.parent.find('#Page-search').val() 176 | if (parseInt(nowPage) > This.totalPage) { 177 | popup.miss({ 178 | title: '超出搜索页数!' 179 | }) 180 | return false 181 | } else { 182 | if (parseInt(nowPage) > 0) { 183 | This.getPage(nowPage) 184 | } 185 | } 186 | 187 | }) 188 | } 189 | 190 | 191 | } 192 | 193 | /*请求分页函数*/ 194 | Page.prototype.getPage = function(nowPage) { 195 | // util.showLoading(); 196 | this.parent.html('') //清空 197 | //写入分页 198 | new Page({ 199 | route: this.route, 200 | routerName: this.routerName, 201 | parent: this.parent, 202 | nowPage: nowPage, 203 | type: this.type, 204 | totalPage: this.totalPage, 205 | pageSize: this.pageSize, 206 | totalCount: this.totalCount, 207 | setting: this.setting, 208 | callback: this.call 209 | }) 210 | if (this.call) { 211 | this.call(nowPage, this.totalPage) //传参 212 | } 213 | } 214 | 215 | 216 | module.exports = function(json) { 217 | new Page(json) 218 | } 219 | -------------------------------------------------------------------------------- /src/assets/common/lib/popup/popup.js: -------------------------------------------------------------------------------- 1 | require('./popup.css') 2 | //构造函数 3 | function PopLayer(){ 4 | this.setting={} 5 | } 6 | 7 | /*确认回调函数*/ 8 | PopLayer.prototype.dosomePopup=function(obj,yes){ 9 | this.closeThisPopup(obj) 10 | yes&&yes() 11 | } 12 | PopLayer.prototype.addendHtml=function(str){ 13 | if(!$('div.popup').length){ 14 | $('body').append(str) 15 | } 16 | } 17 | /*关闭遮罩*/ 18 | PopLayer.prototype.closeThisPopup=function(obj){ 19 | if($(obj).parents('div.popup').length){ 20 | $(obj).parents('div.popup').remove() 21 | }else{ 22 | $(obj).remove() 23 | } 24 | } 25 | //居中函数 26 | PopLayer.prototype.middle=function(){ 27 | var main=$('div.popup_main') 28 | main.css({marginTop:-main.height()/2-20+'px'}) 29 | } 30 | 31 | 32 | /*extent json函数*/ 33 | PopLayer.prototype.extend=function(json1,json2){ 34 | var newJson=json1 35 | for(var i in json1){ 36 | for( var j in json2){ 37 | newJson[j]=json2[j] 38 | } 39 | } 40 | return newJson 41 | } 42 | /*公共变量*/ 43 | PopLayer.prototype.varLiang=function(json){ 44 | this.setting={ 45 | time:2000, 46 | header:'信息', //头部信息 47 | haveHeader:true, //是否显示头部 48 | maskHide:true, //是否点击遮罩隐藏 49 | closeBut:false, //是否需要关闭按钮 50 | loadingImg:'loading-1', 51 | type:'msg', 52 | style:'', 53 | title:'请填写提示信息!', 54 | yesHtml:'', 55 | imgs:{ 56 | msg:'icon-1', 57 | error:'icon-2', 58 | success:'icon-3', 59 | }, 60 | yes:function(){}, 61 | callback:function(){}, 62 | } 63 | if(json){ 64 | this.setting=this.extend(this.setting,json) //继承 65 | } 66 | } 67 | /*页面层*/ 68 | PopLayer.prototype.customHtml=function(json){ 69 | this.varLiang(json) 70 | var str='' 78 | this.addendHtml(str) 79 | this.middle() //居中 80 | this.setting.callback() 81 | 82 | } 83 | /*iframe层*/ 84 | PopLayer.prototype.iframe=function(json){ 85 | util.showLoading() 86 | this.varLiang(json) 87 | var str='