├── doc ├── redux.md └── react.md ├── src ├── async │ ├── rxjs │ │ ├── index.js │ │ ├── rxjs.js │ │ └── logOperator.js │ ├── readme.md │ ├── setTimeout.js │ ├── index.js │ ├── async_await.js │ ├── promise.js │ ├── mutationObserver.js │ └── generator.js ├── redux │ ├── compose │ │ ├── index.js │ │ └── compose.js │ ├── createStore │ │ ├── index.js │ │ ├── dispatch.js │ │ ├── subscribe.js │ │ └── createStore.js │ ├── index.js │ ├── demo │ │ └── index.js │ ├── combineReducers │ │ └── index.js │ ├── bindActionCreators │ │ └── index.js │ └── applyMiddleware │ │ └── index.js ├── test │ ├── another.css │ ├── hello.css │ └── index.js ├── ES6 │ ├── enumerate.js │ ├── iterator.js │ ├── 数组扩展.js │ ├── readme.md │ ├── class.js │ ├── promise.js │ ├── class1.js │ ├── module.js │ ├── 解构赋值.js │ ├── let_const.js │ ├── generator.js │ └── 函数.js ├── media │ ├── video.js │ ├── index.js │ └── player.js ├── oop │ ├── index.js │ └── readme.md └── react │ └── index.js ├── demo.png ├── .DS_Store ├── .gitignore ├── .babelrc ├── README.md ├── index.html ├── package.json ├── advance └── HOC.js └── webpack.config.js /doc/redux.md: -------------------------------------------------------------------------------- 1 | ## redux讲解 -------------------------------------------------------------------------------- /src/async/rxjs/index.js: -------------------------------------------------------------------------------- 1 | require('./rxjs.js'); -------------------------------------------------------------------------------- /src/redux/compose/index.js: -------------------------------------------------------------------------------- 1 | require('./compose') 2 | -------------------------------------------------------------------------------- /src/test/another.css: -------------------------------------------------------------------------------- 1 | body{ 2 | font-size: 20px 3 | } -------------------------------------------------------------------------------- /src/test/hello.css: -------------------------------------------------------------------------------- 1 | body{ 2 | background: red 3 | } -------------------------------------------------------------------------------- /demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slashhuang/web-bolilerplate-for-beginners/HEAD/demo.png -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slashhuang/web-bolilerplate-for-beginners/HEAD/.DS_Store -------------------------------------------------------------------------------- /src/test/index.js: -------------------------------------------------------------------------------- 1 | require('./hello.css') 2 | 3 | require.ensure(['./test.js'],require=>{ 4 | require('./test.js') 5 | },'fc') -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | node_modules 3 | test.js 4 | .idea 5 | dist 6 | *.log* 7 | 8 | lib 9 | test -------------------------------------------------------------------------------- /src/ES6/enumerate.js: -------------------------------------------------------------------------------- 1 | var s = {}; 2 | Object.defineProperty(s,'a',{ 3 | value:1 4 | }); 5 | 6 | 7 | console.log(s.hasOwnProperty('a')); -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "stage-0", 4 | "es2015", 5 | "react" 6 | ], 7 | "plugins": [ 8 | "transform-decorators-legacy", 9 | ["transform-class-properties", { "spec": true }] 10 | ] 11 | } -------------------------------------------------------------------------------- /src/ES6/iterator.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | let t = [1,2,3]; 5 | 6 | // for(let val of t){ 7 | // console.log(val) 8 | // }; 9 | 10 | const s= function(){ 11 | for(let val of arguments){ 12 | console.log(val) 13 | }; 14 | } 15 | s(1,2,34); -------------------------------------------------------------------------------- /src/async/readme.md: -------------------------------------------------------------------------------- 1 | ## 异步编程实践讲解 2 | 3 | - [Promise](./promise.js) 4 | 5 | - [generator](./generator.js) 6 | 7 | - [mutationObserver](./mutationObserver.js) 8 | 9 | - [async/await](./async_await.js) 10 | 11 | - [setTimout](./setTimout.js) 12 | 13 | - [rxjs](./rxjs.js) -------------------------------------------------------------------------------- /src/async/setTimeout.js: -------------------------------------------------------------------------------- 1 | /* 2 | * built by slashhuang 3 | * 17/5/11 4 | * 基础的microtask和macrotask 5 | */ 6 | process.nextTick(()=>console.log('tick0')) 7 | setTimeout(console.log,0,'0秒') 8 | process.nextTick(()=>console.log('tick1')) 9 | setTimeout(console.log,1,'1秒') 10 | setTimeout(console.log,2,'2秒') 11 | 12 | // ========> [同步代码] pop()[microtask] [macrotask] -------------------------------------------------------------------------------- /src/async/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 异步编程 番外讲解 3 | * built by slashhuang 4 | * 17/5/10 5 | */ 6 | // require('./promise') 7 | // require('./generator') 8 | // require('./async_await') 9 | // require('./setTimeout') 10 | // require('./mutationObserver') 11 | require('./rxjs') 12 | 13 | // reactive programming 14 | // functional programming 15 | // oop programming 16 | 17 | // netflix -------------------------------------------------------------------------------- /src/ES6/数组扩展.js: -------------------------------------------------------------------------------- 1 | //Array.from() 2 | let arrayLike = { 3 | '0': 'a', 4 | '1': 'b', 5 | '2': 'c', 6 | length: 3 7 | }; 8 | 9 | // ES5的写法 10 | var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c'] 11 | 12 | // ES6的写法 13 | let arr2 = Array.from(arrayLike); // ['a', 'b', 'c'] 14 | 15 | 16 | 17 | //数组实例的includes() 18 | [1, 2, 3].includes(2); // true 19 | [1, 2, 3].includes(4); // false 20 | [1, 2, 3].includes(3, 3); // false 21 | -------------------------------------------------------------------------------- /src/async/async_await.js: -------------------------------------------------------------------------------- 1 | /* 2 | * built by slashhuang 3 | * 17/5/11 4 | * async + await语法 ==> Promise+generator+autoIterate 5 | */ 6 | 7 | const f = async (val)=>{ 8 | const await1 = await new Promise((resolve,reject)=>{ 9 | setTimeout(resolve,1000,val) 10 | }).then(val=>{ 11 | return val+1 12 | }) 13 | console.log(`await value is ==>${await1}`) 14 | } 15 | 16 | //asyc + await ====> generator + 自动执行器 ==> Promise + 语法转换 17 | f(2) 18 | f(3) -------------------------------------------------------------------------------- /src/ES6/readme.md: -------------------------------------------------------------------------------- 1 | ## ES6 课程 2 | 3 | 4 | # ES6与JS 5 | 6 | ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现 7 | 8 | 9 | # ES6 stage 10 | 11 | Stage 0 - Strawman(展示阶段) 12 | Stage 1 - Proposal(征求意见阶段) 13 | Stage 2 - Draft(草案阶段) 14 | Stage 3 - Candidate(候选人阶段) 15 | Stage 4 - Finished(定案阶段 16 | 17 | 18 | 19 | # ES6 语法测试 20 | 21 | - 安装babel命令行 22 | 23 | ```bash 24 | 25 | $ cnpm install babel-cli 26 | 27 | ``` 28 | 29 | 30 | [参考文档](http://es6.ruanyifeng.com/) -------------------------------------------------------------------------------- /src/redux/createStore/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author slashhuang 3 | * 17/4/16 4 | * redux中的createStore是最核心的api 5 | * createStore入口 6 | */ 7 | 8 | /* 用法 9 | * 参数 10 | * createStore(reducer, preloadedState, enhancer) 11 | * 返回值 12 | * { 13 | dispatch, 14 | subscribe, 15 | getState, 16 | replaceReducer, 17 | [$$observable]: observable 18 | } 19 | */ 20 | require('./createStore') 21 | require('./subscribe') 22 | require('./dispatch') 23 | -------------------------------------------------------------------------------- /src/media/video.js: -------------------------------------------------------------------------------- 1 | import React, {PureComponent} from 'react'; 2 | export class Video extends React.PureComponent { 3 | render() { 4 | return ( 5 | ); 11 | } 12 | renderChildren() { 13 | return null; 14 | } 15 | } 16 | // web components 17 | // shadow dom -------------------------------------------------------------------------------- /src/ES6/class.js: -------------------------------------------------------------------------------- 1 | class TestSuper { 2 | constructor() { 3 | this.c = 'a1'; 4 | } 5 | e(){} 6 | } 7 | class Test extends TestSuper{ 8 | constructor(){ 9 | super(); 10 | this.a = 'a'; 11 | this.b = 'b' 12 | } 13 | d(){ 14 | return 'ddddd'; 15 | } 16 | } 17 | 18 | let ins = new Test(); 19 | // React用class语法来写 20 | 21 | 22 | let TestFactory = function (argument) { 23 | this.a = 'a'; 24 | this.b = 'b' 25 | }; 26 | Test.prototype.c = () => 'ddddd'; 27 | let inst = new Test(); 28 | console.log(inst.d) -------------------------------------------------------------------------------- /src/media/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {render} from 'react-dom'; // 结构赋值 3 | import ReactDom from 'react-dom'; 4 | import { Player } from './player'; 5 | const RootDom= document.getElementById('root'); 6 | render(, RootDom); // javascript xml 7 | 8 | 9 | let s = { 10 | tt: 0, 11 | get a() { 12 | return s.tt; 13 | }, 14 | set a(val) { 15 | s.tt = val + 2; 16 | // player.goToAnotherTime(time); 17 | } 18 | 19 | } 20 | s.a = 3; 21 | console.log(s.a); -------------------------------------------------------------------------------- /src/ES6/promise.js: -------------------------------------------------------------------------------- 1 | let p = new Promise((resolve,reject)=>{ 2 | setTimeout(resolve,3000,1) 3 | }) 4 | let q = new Promise((resolve, reject) => { 5 | reject('not good time') 6 | }) 7 | let pending = new Promise((resolve,reject)=>{ 8 | 9 | }) 10 | 11 | // p ==> fulfilled 1 12 | // Promise的状态 fulfilled pending rejected 13 | // Promise的值 14 | 15 | // 3s 后 16 | let p1 = p.then(val=>{ 17 | val += 2; 18 | return new Promise((res, rej) => { 19 | res(2) 20 | }) 21 | }).then((val) => { 22 | console.log(val); 23 | }); 24 | -------------------------------------------------------------------------------- /src/redux/compose/compose.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author slashhuang 3 | * 17/4/16 4 | * redux中的compose用于形成链式中间件 5 | */ 6 | 7 | import { compose } from 'redux'; 8 | 9 | //举例子 10 | let fn = (name)=>{ 11 | console.log(name); 12 | return name+'fn'; 13 | }; 14 | let fn1 = (name)=>{ 15 | console.log(name); 16 | return name+'f1' 17 | }; 18 | let fn2 = (name)=>{ 19 | console.log(name); 20 | return name+'fn2' 21 | }; 22 | 23 | //采用reduceRight,因此fn2先执行 24 | //compose(f, g, h) ===> f(g(h(...args))) 25 | let result = compose(fn,fn1,fn2)('start--'); 26 | //打印4 27 | console.log(result); 28 | -------------------------------------------------------------------------------- /src/ES6/class1.js: -------------------------------------------------------------------------------- 1 | class A { 2 | constructor(name, age) { 3 | this.name = name; 4 | this.age = age; 5 | } 6 | eat() { 7 | console.log('eat'); 8 | } 9 | } 10 | 11 | class B extends A { 12 | constructor(name, age, title) { 13 | super(name, age); 14 | this.title = title 15 | } 16 | work() { 17 | console.log('work'); 18 | } 19 | } 20 | 21 | const c = new B('lilei', 18, 'engineer'); 22 | c.work(); 23 | c.eat(); 24 | console.log(c.name); 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/redux/createStore/dispatch.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author slashhuang 3 | * 17/4/16 4 | * 调用store的api接口 5 | */ 6 | import store from './createStore'; 7 | /* 8 | * store的数据结构 9 | * { 10 | dispatch, ==== 11 | subscribe, 12 | getState, ==== 13 | replaceReducer, 14 | [$$observable]: observable 15 | } 16 | */ 17 | //redux数据流 action ==> reducer ==> nextState 18 | let counter = 0; 19 | document.addEventListener('click',()=>{ 20 | counter++; 21 | store.dispatch({type:counter%2==0?'first':"second"}); 22 | }) 23 | store.dispatch({type:'second'}); 24 | console.log(store.getState()) -------------------------------------------------------------------------------- /src/ES6/module.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | //webpack/gulp ==> 处理require 4 | 5 | import { a } from './let_const.js'; 6 | console.log('=------started') 7 | console.log(a); 8 | console.log('=------ ended') 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | // a.js ==> require('./b.js').kkkkk 17 | // b.js ==> require('./c.js').kkkkk 18 | // c.js ==> require('./a.js').kkkkk 19 | 20 | // AMD define + require 21 | 22 | // webpack ==> node.js的fs io体系来把所有的require依赖放在一个文件里面 23 | // bundle.js 24 | 25 | // (function(moduleArr) { 26 | // // XXX 27 | // }[ 28 | // a.js , 29 | // c.js, 30 | // d.js 31 | // ])() 32 | -------------------------------------------------------------------------------- /src/ES6/解构赋值.js: -------------------------------------------------------------------------------- 1 | // 基本用法 Destructuring 2 | 3 | let [ a, b, c ] = [1, 2, 3]; 4 | 5 | let { d,e }={ d:1, e:2 } 6 | 7 | // 深度解构 deep destructuring 8 | let obj = { 9 | p: [ 10 | 'Hello', 11 | { y: 'World' } 12 | ] 13 | }; 14 | 15 | let { p: [x, { y }] } = obj; 16 | 17 | //应用 18 | function add([x, y]){ 19 | return x + y; 20 | } 21 | add([1, 2]); // 3 22 | 23 | 24 | //字符串的解构赋值 25 | const [a1, b1, c1, d1, e1] = 'hello'; 26 | 27 | //rest解构 spread destructuring 28 | const { p,...rest } = {p:1,a:2,c:2}; 29 | console.log(rest) // {a:2, c:2} 30 | // 默认值 ,如果一个数组成员不严格等于undefined 31 | 32 | // //函数参数的解构赋值 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/redux/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * redux的主要对外api 4 | * ------- 中间件流转逻辑 5 | * 6 | * applyMiddleware 7 | 8 | * ------- utility工具 9 | * bindActionCreators 10 | * combineReducers 必掌握 11 | * compose 12 | * ------- 最核心的api 13 | * createStore 14 | */ 15 | 16 | /*let model = {} 17 | model.a = 'a' 18 | //无序的改变 19 | 20 | 优势: trackable model 21 | action 发起变更 'changeA' 22 | ===> reducers 返回一个新的model {a:1} 23 | ===> model ==> {a:1} 24 | 25 | */ 26 | // require('./demo'); 27 | // require('./createStore/') 28 | // require('./combineReducers/') 29 | // require('./bindActionCreators/') 30 | 31 | // require('./compose/') 32 | require('./applyMiddleware/') 33 | 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # web-bolilerplate-for-beginners 2 | 3 | ## 安装 4 | 5 | ``` 6 | # 安装依赖 7 | $ npm install 8 | 9 | ``` 10 | 11 | **有以下两种方法运行项目** 12 | 13 | ### 1. 不采用devServer运行项目 14 | 15 | ```bash 16 | # 编译代码 17 | $ npm build 18 | 19 | # 查看效果 20 | $ npm start 21 | 22 | ``` 23 | ### 2. 采用devServer运行项目 24 | 25 | ```bash 26 | # 采用webpack-dev-server编译代码 27 | $ npm start 28 | 29 | ``` 30 | 31 | ## 使用方式 32 | 33 | ES6/7 : 修改src/ES6/来测试你的ES6/7语法即可 34 | 35 | React : 修改src/react.js来学习react代码 36 | 37 | Redux : 修改src/redux/来学习redux代码 38 | 39 | async : 修改src/async/来学习异步编程 40 | 41 | async/generator : 如果你想用更高级的类似async/Promise等等语法,请修改webpack.config.js 42 | 43 | ## 页面 44 | 45 | ![示例页面](./demo.png) 46 | 47 | -------------------------------------------------------------------------------- /src/ES6/let_const.js: -------------------------------------------------------------------------------- 1 | // let 和 const 2 | 3 | export let a = 0 ; 4 | 5 | // 适用for 循环 6 | // for (let i = 0; i < 10; i++) { 7 | // console.log(i); 8 | // } 9 | 10 | // //比对 11 | 12 | // 块级作用域 13 | function f1() { 14 | let n = 5; 15 | if (true) { 16 | let n = 10; 17 | } 18 | console.log(n); // 5 19 | } 20 | f1() 21 | 22 | const C= 'C'; // readonly 23 | 24 | const c= { // point to a reference 25 | a:1 26 | } 27 | // c={a: 2}; // point to another reference 28 | c.a = 2; 29 | 30 | 31 | // //块级作用域返回值 do expression 32 | // let x = do{ 33 | // 1 34 | // } 35 | 36 | // //const read only 37 | 38 | // const p = 1; 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 语法测试篇 5 | 6 | 7 |
8 | 欢迎同学们使用web-bolilerplate-for-beginners学习JS 9 |
10 |
11 | 您可以修改src/index.js来学习ES6/7的语法, 12 |
13 | 16 |
17 | 18 | 数据预览区 19 |
20 |
21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /doc/react.md: -------------------------------------------------------------------------------- 1 | ## react 学习资料 2 | 3 | - [react官方源码](https://github.com/facebook/react) 4 | 5 | - [react官网](https://facebook.github.io/react/) 6 | 7 | - [webpack文档](https://webpack.github.io/docs/) 8 | 9 | - [vue文档](https://github.com/vuejs/vue) 10 | 11 | - directive指令框架 dom 12 | 13 |
14 | 21 |
22 | 27 | //vue 28 | //angular 29 | 30 | 31 | - js层面 32 | react 更具有动态性 JSX ==> JS xml 33 | 34 |

hello world

==> React.createElement() => V-DOM 35 | 36 | 37 | 38 | 39 | ------------ 40 | 41 | babel来去做这个事情 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/async/promise.js: -------------------------------------------------------------------------------- 1 | /* 2 | * built by slashhuang 3 | * 17/5/11 4 | * 基础的microtask和macrotask 5 | */ 6 | 7 | // repl 8 | const p_1 = new Promise((res,rej)=>{ 9 | res(1) //==> resolved 10 | console.log('started') 11 | // res(2) //==> rejected ===> sealed封锁 12 | // res(3) 13 | //=> enqueue to microtask [当前js执行loop的尾部] 14 | }).then(val=>{ 15 | //第二个 16 | console.log(val) 17 | }) 18 | 19 | // thenable ==> enqueue to microtask [当前js执行loop的尾部] 20 | Promise.resolve({ 21 | then:(res,rej)=>{ 22 | j2 23 | res(5) 24 | } 25 | // j3 26 | }).then(val=>{ 27 | //第三个 28 | console.log(val) 29 | }) 30 | //第一个 31 | console.log('3') 32 | 33 | //第四个 j5 34 | // enqueue to macrotask [下个js loop ] 35 | setTimeout(console.log,0,4) 36 | // 1行1行的执行 【 1 2 3 4 】 [j1,j2,j3] [macrotask j5] 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/redux/demo/index.js: -------------------------------------------------------------------------------- 1 | import { createStore } from 'redux'; 2 | const initState = {}; 3 | const action = { 4 | type: 'init', 5 | payload: 'hello world', 6 | }; 7 | const reducer = (state, action) => { 8 | return Object.assign({}, state, action); 9 | }; 10 | const store = createStore(reducer, initState); 11 | const INPUTDOM = document.getElementById('name'); 12 | const PREVIEWDOM = document.getElementById('preview'); 13 | const digestUI = () => { 14 | PREVIEWDOM.innerHTML = store.getState().payload; 15 | if (PREVIEWDOM.innerHTML.length > 20) { 16 | alert('good boy') 17 | } 18 | }; 19 | const inputChange = () =>{ 20 | let val = INPUTDOM.value; 21 | const action = { 22 | type: 'input_change', 23 | payload: val, 24 | }; 25 | store.dispatch(action); 26 | }; 27 | let counter = 0; 28 | INPUTDOM.addEventListener('input', inputChange) 29 | store.subscribe(digestUI); -------------------------------------------------------------------------------- /src/ES6/generator.js: -------------------------------------------------------------------------------- 1 | // 一是,function关键字与函数名之间有一个星号; 2 | // 二是,函数体内部使用yield语句,定义不同的内部状态(yield在英语里的意思就是“产出”)。 3 | function* helloWorldGenerator() { 4 | yield 'hello'; 5 | yield 'world'; 6 | return 'ending'; 7 | }; 8 | var hw = helloWorldGenerator(); 9 | let a = hw.next(); 10 | let b = hw.next(); 11 | let c = hw.next(); 12 | console.log(a,b,c,d) 13 | 14 | 15 | function* foo(x) { 16 | var y = 2 * (yield (x + 1)); 17 | var z = yield (y / 3); 18 | return (x + y + z); 19 | } 20 | 21 | // var a = foo(5); 22 | // a.next() // Object{value:6, done:false} 23 | // a.next() // Object{value:NaN, done:false} 24 | // a.next() // Object{value:NaN, done:true} 25 | 26 | 27 | // //通过next方法的参数,就有办法在 Generator 函数开始运行之后,继续向函数体内部注入值 28 | // var b = foo(5); 29 | // b.next() // { value:6, done:false } 30 | // b.next(12) // { value:8, done:false } 31 | // b.next(13) // { value:42, done:true } 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/redux/createStore/subscribe.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author slashhuang 3 | * 17/4/16 4 | * 调用store的api接口 5 | */ 6 | import store from './createStore'; 7 | /* 8 | * store的数据结构 9 | * { 10 | dispatch, ==== 11 | subscribe, 12 | getState, ==== 13 | replaceReducer, 14 | [$$observable]: observable 15 | } 16 | */ 17 | //redux数据流 action ==> reducer ==> nextState 18 | let counter=0; 19 | let listener1 = ()=>{ 20 | console.log(`counter=${++counter}--- listener1 called`) 21 | }; 22 | let listener2 = ()=>{ 23 | console.log(`counter=${++counter}--- listener2 called`) 24 | }; 25 | let domListener = ()=>{ 26 | document.body.innerHTML += JSON.stringify(store.getState()) 27 | }; 28 | 29 | store.subscribe(listener1) //===> arr.push(listener1) arr.forEach(fn=>fn()) 30 | store.subscribe(listener2) //===> arr.push(listener2) 31 | store.subscribe(domListener) 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/redux/createStore/createStore.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author slashhuang 3 | * 17/4/16 4 | * redux中的createStore是最核心的api 5 | * 创建store 6 | */ 7 | import { createStore } from 'redux'; 8 | /* 9 | * 参数 10 | * createStore(reducer, preloadedState, enhancer) 11 | * 返回值 12 | * { 13 | dispatch, ===> 分发action 14 | subscribe, [listen1,listener2] ===> 在每次dispatch的时候,注册回调函数 15 | getState, ===> getter 获取redux当前的state 16 | replaceReducer, 17 | [$$observable]: observable 18 | } 19 | model1 ==> model2 20 | action ==> reducer ==> nextState 21 | */ 22 | let reducer = (preState,action)=>{ 23 | switch(action.type){ 24 | case 'first': 25 | return Object.assign(preState,{name:'first cli'}) 26 | case 'second': 27 | return Object.assign(preState,{name:'2nd called'}) 28 | default: 29 | return preState 30 | } 31 | } 32 | let store = createStore(reducer,{a:1}); 33 | module.exports=store 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/async/rxjs/rxjs.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 异步编程 番外讲解 3 | * built by slashhuang 4 | * 17/5/10 5 | * rxjs 6 | * realtime[即时通讯 im] + continuency[持续性 stock] 7 | */ 8 | debugger 9 | import { log } from './logOperator'; 10 | import { Observable } from 'rxjs/Rx'; 11 | // Observable.prototype.log = log; 12 | const observer ={ 13 | next: (val) => { 14 | console.log(val); 15 | // if (this.unsubscribe) { 16 | // this.unsubscribe(); 17 | // } 18 | }, 19 | complete:()=>console.log('complete'), 20 | error:console.log 21 | } 22 | // observable == push notifications ==> observer 23 | const o_1 = Observable.create(observer=>{ 24 | observer.next(1); 25 | }); 26 | o_1.map((val) => val).subscribe(observer) 27 | 28 | 29 | // simple observable 30 | const o_2 = Observable.of([1,2,3,4]); 31 | o_2.subscribe(observer) 32 | 33 | // pub/sub observer观察者模式 34 | // const o_3 = Observable.interval(1000).map(val=>val*2) 35 | // o_3.subscribe(observer) 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/redux/combineReducers/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author slashhuang 3 | * 17/4/16 4 | * redux中的createStore是最核心的api 5 | * 创建store 6 | */ 7 | import { createStore,combineReducers } from 'redux'; 8 | 9 | let reducer = (preState={},action)=>{ 10 | debugger; 11 | return Object.assign(preState,action) 12 | } 13 | let reducer1 = (preState={},action)=>{ 14 | return Object.assign(preState,{hello:'我是另一个reducer'}) 15 | } 16 | /* 合并reducers 17 | * 参数 18 | * combineReducers(reducers) {key:fn,key1:fn2} 19 | * 返回值 20 | * function(state,action) ==> 21 | {reducer1(state,action); ==>State1 22 | reducer2(state,action);} ===> State2 23 | ===> 合并{state1,state2} 24 | ===> { 25 | userList:State1, 26 | userDetail:state2 27 | } 28 | */ 29 | let finalReducer = combineReducers({ 30 | userList:reducer, 31 | userDetail:reducer1 32 | }); 33 | let store = createStore(finalReducer,{userList:{}}); 34 | 35 | store.dispatch({type:"学习combineReducers"}) 36 | console.log(store.getState()); 37 | 38 | -------------------------------------------------------------------------------- /src/async/mutationObserver.js: -------------------------------------------------------------------------------- 1 | // Firefox和Chrome早期版本中带有前缀 2 | const MutationObserver = window.MutationObserver 3 | || window.WebKitMutationObserver || window.MozMutationObserver 4 | // 创建观察者对象 5 | const observer = new MutationObserver(mutations=>{ 6 | mutations.forEach(function(mutation) { 7 | console.log(mutation.type); 8 | }) 9 | }) 10 | // 配置观察选项: 11 | const config = { 12 | attributes: true, 13 | childList: true, 14 | characterData: true 15 | } 16 | // 选择目标节点 17 | const target = document.querySelector('#test'); 18 | // 传入目标节点和观察选项 19 | observer.observe(target, config); 20 | 21 | target.appendChild(document.createElement("div")) 22 | /* 23 | * mutationObserver优先于setTimeout 24 | */ 25 | setTimeout(console.log,0,'setTimeout') 26 | console.log('appending') 27 | target.setAttribute('class','hello') //添加了一个元素子节点,触发回调函数. 28 | 29 | // 随后,你还可以停止观察 30 | // observer.disconnect(); 31 | 32 | 33 | /* 34 | * doc https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver 35 | */ -------------------------------------------------------------------------------- /src/oop/index.js: -------------------------------------------------------------------------------- 1 | var s = function() { 2 | this.a = 'a'; 3 | this.b = 'b'; 4 | }; 5 | 6 | s.prototype.c = 'c'; 7 | 8 | 9 | var p = new s(); 10 | 11 | // // p? 12 | // p ---- 属性、方法 13 | // ===== 共享prototype 14 | // p1 ---属性、方法 15 | 16 | 17 | // parent class 父类 child class 子类 18 | 19 | var parent = function(name, age) { 20 | this.name = name; 21 | this.age = age; 22 | }; 23 | 24 | parent.prototype.c = 'c'; 25 | // var child = function(title) { 26 | // this.title = title; 27 | // }; 28 | // child.prototype = new parent('lilei', 10); 29 | 30 | 31 | 32 | var child = function(name, age, title) { 33 | this.title = title; 34 | parent.call(this, name, age); 35 | child.prototype = Object.create(parent.prototype); 36 | child.prototype.consturctor = child; 37 | // child.prototype.__proto__ = parent.prototype; 38 | }; 39 | child.prototype.d = "d" 40 | // child.prototype = new parent('lilei', 10); 41 | 42 | new child('lilei', 10, 'student'); 43 | 44 | |- title : 'student', 45 | |- name : 'lilei' 46 | |- age : 10, 47 | |- __proto__ 48 | |- d : 'd' 49 | |__proto__ 50 | |- c: 'c' 51 | |- Object... 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/async/generator.js: -------------------------------------------------------------------------------- 1 | /* 2 | * built by slashhuang 3 | * 17/5/11 4 | * generator yield 语法 5 | */ 6 | const generator_souce = function* () { 7 | const y = yield 1 8 | console.log('y==='+y) 9 | const z = yield 2 10 | console.log('z==='+z) 11 | } 12 | // control of iteration 13 | const generator1 = generator_souce() 14 | // value + done[boolean] 15 | // generator的开始 16 | // const a = generator1.next() 17 | // const b = generator1.next(a.value) 18 | // generator1.next(b.value) 19 | // co ==> 封装以上逻辑 20 | const co = generator=>{ 21 | //start the generator 22 | const a= generator.next() 23 | setTimeout(()=>{ 24 | if(!a.done){ 25 | const b = generator.next(a.value) 26 | if(!b.done){ 27 | const c = generator.next(b.value) 28 | if(!c.done){ 29 | const d = generator.next(c.value) 30 | } 31 | } 32 | } 33 | },0) 34 | 35 | } 36 | co(generator1) 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | // 遍历逻辑+ 传值逻辑 46 | 47 | // iteration 48 | // for(let i of generator1){ 49 | // console.log(i) 50 | // } 51 | 52 | 53 | // const g1 = generator1.next()['value'] 54 | // const g2 = generator1.next(g1)['value'] 55 | // const g3 = generator1.next(g2)['value'] 56 | 57 | // 用 Promise来处理generator ==> 著名的CO库 58 | -------------------------------------------------------------------------------- /src/async/rxjs/logOperator.js: -------------------------------------------------------------------------------- 1 | import Subscriber from 'rxjs/Subscriber'; 2 | export function log(project, thisArg) { 3 | return source => { 4 | if (typeof project !== 'function') { 5 | throw new TypeError('argument is not a function. Are you looking for `mapTo()`?'); 6 | } 7 | return source.lift(new LogOperator(project, thisArg)); 8 | } 9 | } 10 | export class LogOperator { 11 | constructor(project, thisArg) { 12 | this.project = project; 13 | this.thisArg = thisArg; 14 | } 15 | call (subscriber, source) { 16 | return source.subscribe(new LogSubscriber(subscriber, this.project, this.thisArg)); 17 | }; 18 | } 19 | export class LogSubscriber extends Subscriber { 20 | constructor(project, thisArg) { 21 | super(); 22 | this.project = project; 23 | this.count = 0; 24 | this.thisArg = thisArg || this; 25 | } 26 | _next (value) { 27 | var result; 28 | try { 29 | result = this.project.call(this.thisArg, value, this.count++); 30 | } 31 | catch (err) { 32 | this.destination.error(err); 33 | return; 34 | } 35 | this.destination.next(result); 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /src/redux/bindActionCreators/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author slashhuang 3 | * 17/4/16 4 | * redux中的createStore是最核心的api 5 | * 创建store 6 | */ 7 | import { createStore,bindActionCreators } from 'redux'; 8 | /* 9 | * 参数 {} 10 | * bindActionCreators(actionCreators, dispatch) 11 | * 返回值 12 | * {Function|Object} 13 | * 14 | * action ==> reducers ==> nextState 15 | * action1 action2 action3 16 | * 17 | * ajax 18 | * store.dispatch(action1) 19 | store.dispatch(action2) 20 | store.dispatch(action3) 21 | 22 | ===>let wrapper = bindActionCreators({ 23 | click:action1, 24 | focus:action2 25 | },dispatch) 26 | wrapper.click('参数') 27 | * 28 | */ 29 | let reducer = (preState={},action)=>{ 30 | return Object.assign(preState,action) 31 | } 32 | let store = createStore(reducer,{}); 33 | store.subscribe(()=>{ 34 | document.body.innerHTML += JSON.stringify(store.getState()) 35 | }) 36 | //action creator 37 | let clickAction = name=>{ 38 | return { 39 | type:name 40 | } 41 | }; 42 | 43 | let AutoDispatch = bindActionCreators( 44 | {click:clickAction}, 45 | //获取 dispatch reference 46 | store.dispatch 47 | ); 48 | document.addEventListener('click',()=>{ 49 | //store.dispatch({type:'学习bindActionCreators'}) 50 | AutoDispatch.click("学习bindActionCreators") 51 | }) 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/oop/readme.md: -------------------------------------------------------------------------------- 1 | # oop 2 | 3 | 1. oop的概念 4 | 5 | object-oriented-programming 6 | 7 | |- object ? 人、js、公司 8 | 9 | |- 属性 property eyes 10 | |- 方法 method eat() 11 | 12 | 13 | |- 抽象性 abstraction【抽取描述对象的方法、属性】 14 | |- 封装性 encapsulation【不用care细节,只暴露必要的东西】 15 | |- 继承性 inheritage 【复用共同的属性、方法...】 16 | parent class父类 child class子类 17 | 18 | new Person().eat() 19 | 20 | |- eyes 21 | |- mouth 22 | |- eat() 23 | 24 | 公务员 25 | |- work() 26 | 27 | 28 | 2. js中的oop 29 | 30 | 31 | class 类 java/c++/python 32 | 33 | class A ==> 创建对象 new A(name, age) 34 | 35 | class Person { // parent class 36 | constructor(name, age) { 37 | this.name = name ; 38 | this.age = age; 39 | this.eatList = []; 40 | } 41 | public eat(food) { 42 | this.eatList.push(food); 43 | } 44 | } 45 | 46 | // === inheritage 47 | class 公务员 extends Person{ //child class 48 | constructor(title) { 49 | super(); 50 | this.title = title; 51 | } 52 | } 53 | 54 | const a = new ('lilei', 10); 55 | console.log(a.age); 56 | a.eat('烤鸭'); 57 | console.log(a.eatList); 58 | 59 | 好像一个工厂、封装了person需要的属性和方法 60 | 61 | 62 | 63 | 64 | // 工厂函数 65 | var s = function () { 66 | return { 67 | a: 1 68 | } 69 | }; 70 | 71 | // 构造函数 constructor 72 | var s1 = function() { 73 | this.a = 'a'; 74 | this.b = 'b'; 75 | }; 76 | 77 | 78 | s1.prototype // 模板对象 79 | 80 | // 构造函数 + 原型链 81 | 82 | 3. js中oop的简单实现 83 | 4. 如何去应用oop 84 | 85 | 86 | -------------------------------------------------------------------------------- /src/ES6/函数.js: -------------------------------------------------------------------------------- 1 | //函数参数的默认值 2 | 3 | // 1. arrow function 4 | 5 | const another = function() { 6 | // function body 7 | return { 8 | a: 'hello world' 9 | } 10 | } 11 | // ==> 12 | const C = 'c'; 13 | const s = () => { 14 | const C = 's'; 15 | return { 16 | a: 'hello world' 17 | } 18 | } 19 | 20 | // 一个function (入参 + 返回值) 21 | const pa = (...args) => { 22 | console.log(args); 23 | return args.reduce((pre,cur) => { 24 | return pre+cur; 25 | }, 0); 26 | }; 27 | pa.apply(this, [1,2,45]); 28 | 29 | let a = [1,2,3]; 30 | let [c, ...d] = a; 31 | console.log(d); 32 | 33 | 34 | // 参数 初始值 35 | function log(x, y = 'World') { 36 | console.log(x, y); 37 | } 38 | log('hello'); // log('Hello') // Hello World 39 | 40 | 41 | //rest参数 42 | function add(a, b, ...values) { 43 | console.log(values) 44 | } 45 | add(2, 5, 3) // 10 46 | 47 | console.log(5,...[1, 2, 3]) 48 | 49 | const s = function(){ 50 | return () => { 51 | console.log(this) 52 | } 53 | }; 54 | s.apply({a:1})() 55 | 56 | // //箭头函数 {} 57 | // var f = v => v; 58 | // var f1 = v=>{ 59 | // console.log(this) 60 | // } 61 | var f3 = function(v){ 62 | //this 63 | return v=>{ 64 | console.log(this); 65 | } 66 | } 67 | 68 | // 箭头函数有几个使用注意点。 69 | 70 | // (1)函数体内的this对象,就是定义时所在的对象。 71 | 72 | // (2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。 73 | 74 | // (3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。 75 | 76 | // (4)不可以使用yield命令,因此箭头函数不能用作Generator函数。 -------------------------------------------------------------------------------- /src/media/player.js: -------------------------------------------------------------------------------- 1 | import React, {PureComponent} from 'react'; 2 | import { Video } from './video'; 3 | export class Player extends React.PureComponent { 4 | constructor() { 5 | super(); 6 | this.videoRef = null; 7 | } 8 | render() { 9 | let src = 'http://tb-video.bdstatic.com/tieba-smallvideo-transcode/62_ab5b58be998d965b5bca6741e668350e_3.mp4'; 10 | let poster = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1506264317769&di=ecbe9cd08dd63a21279411bcaf55717d&imgtype=0&src=http%3A%2F%2Fimages.xuejuzi.cn%2F1505%2F1_150528111508_1.jpg'; 11 | let videoProps = { 12 | src, 13 | poster, 14 | // autoPlay: true, 15 | controls: true, 16 | playsInline: true, 17 | // width: '100px', 18 | // height: '200px', 19 | }; 20 | return ( 21 |
22 |
); 30 | } 31 | forward = () => { 32 | if (this.videoRef) { 33 | this.videoRef.currentTime = this.videoRef.currentTime + 3.11; 34 | } 35 | } 36 | } 37 | 38 | // set get 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web-boilerplate-for-beginners", 3 | "version": "1.0.0", 4 | "description": "web-boilerplate-for-beginners", 5 | "main": "./src/index.js", 6 | "scripts": { 7 | "a": "echo \"hello world\"", 8 | "test": "nodemon ./test", 9 | "build": "rimraf dist && webpack", 10 | "server": "anywhere --port 8001 ", 11 | "start": "opn http://localhost:8080/webpack-dev-server/index.html && webpack-dev-server", 12 | "ES6": "babel -w src/ES6 -d lib/ES6" 13 | }, 14 | "keywords": [ 15 | "boilerplate", 16 | "ES6/7", 17 | "React", 18 | "Redux" 19 | ], 20 | "author": "slashhuang", 21 | "license": "ISC", 22 | "devDependencies": { 23 | "anywhere": "^1.4.0", 24 | "babel-cli": "^6.24.0", 25 | "babel-core": "^6.18.2", 26 | "babel-loader": "^6.2.7", 27 | "babel-plugin-import": "^1.1.0", 28 | "babel-plugin-syntax-async-functions": "^6.13.0", 29 | "babel-plugin-syntax-decorators": "^6.13.0", 30 | "babel-plugin-transform-async-to-generator": "^6.16.0", 31 | "babel-plugin-transform-class-properties": "^6.24.1", 32 | "babel-plugin-transform-decorators": "^6.22.0", 33 | "babel-plugin-transform-decorators-legacy": "^1.3.4", 34 | "babel-polyfill": "^6.23.0", 35 | "babel-preset-es2015": "^6.22.0", 36 | "babel-preset-react": "^6.5.0", 37 | "babel-preset-stage-0": "^6.16.0", 38 | "babel-runtime": "^6.23.0", 39 | "css-loader": "^0.28.1", 40 | "extract-text-webpack-plugin": "^2.1.2", 41 | "node-fetch": "^1.6.3", 42 | "nodemon": "^1.11.0", 43 | "opn-cli": "^3.1.0", 44 | "rimraf": "^2.6.1", 45 | "style-loader": "^0.17.0", 46 | "webpack": "^2.5.1", 47 | "webpack-dev-server": "^2.4.5" 48 | }, 49 | "dependencies": { 50 | "lodash": "^4.17.4", 51 | "react": "^15.4.2", 52 | "react-dom": "^15.4.2", 53 | "redux": "^3.6.0", 54 | "rxjs": "^5.4.0" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /advance/HOC.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 增加react decorator 3 | * @Author slashhuang 4 | * 17/3/24 5 | */ 6 | import React,{Component} from 'react'; 7 | import {render} from 'react-dom'; 8 | import _ from 'lodash' 9 | 10 | const highOrderFunc=methodHook=>InnerComponent=>{ 11 | _.forIn(methodHook, (hookFn, key)=>{ 12 | let cache = InnerComponent.prototype[key] 13 | InnerComponent.prototype[key]=function(...args){ 14 | cache.apply(this,args) 15 | hookFn() 16 | } 17 | }); 18 | return InnerComponent 19 | } 20 | @highOrderFunc({'clickFunc':()=>console.log('hook click called')}) 21 | class FirstComponent extends Component{ 22 | constructor(){ 23 | super(); 24 | this.state={ text: 'hello world' } 25 | } 26 | clickFunc(){ 27 | this.setState({text:'I am clicked'}) 28 | } 29 | render(){ 30 | return
{this.state.text}
31 | } 32 | }; 33 | render(,document.getElementById('root')) 34 | 35 | 36 | const highOrderFunc1=actions=>InnerComponent=>{ 37 | class Inst1 extends Component{ 38 | componentDidMount(){ 39 | let _ref = this.refs.InnerComponent; 40 | //侵入事件 41 | _ref.__proto__.clickFunc = function(...args){ 42 | this.props.Update(); 43 | let { text } = this.state; 44 | this.setState({text:`add Text ${text}`}) 45 | } 46 | } 47 | render(){ 48 | //update Props 49 | this.props = { 50 | ...this.props, 51 | ...actions 52 | }; 53 | return 54 | } 55 | } 56 | return Inst1; 57 | } 58 | @highOrderFunc1({ 59 | 'Update':()=>{console.log('Update')} 60 | }) 61 | class FirstComponent1 extends Component{ 62 | constructor(){ 63 | super() 64 | this.state={ text: 'hello world' } 65 | } 66 | clickFunc(){ 67 | this.setState({text:'I am clicked'}) 68 | } 69 | render(){ 70 | return
this.clickFunc()}>{this.state.text}
71 | } 72 | }; 73 | render(,document.getElementById('root1')) 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/redux/applyMiddleware/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author slashhuang 3 | * 17/4/16 4 | * redux中的applyMiddleware中间件 5 | * Middleware makes it easier for software developers 6 | * to implement 【communication and input/output】, 7 | * so they can focus on the 【specific purpose of their application】. 8 | * service服务 9 | * input/output service 10 | */ 11 | 12 | // ajax ==> json(乱的数据) =service转换=> UI(整齐的数据) 13 | // express/Koa 14 | // 前端 15 | // ajax ==http==> 16 | // httpRequest(head,cookie,body) 17 | // middlewares(解析cookie, 拿到post请求的数据) 18 | // 数据就是好的一笔的数据 19 | // 后端(node.js) 20 | /* 21 | * 中间件 applyMiddleware 22 | * 参数 23 | * 类数组的中间件对象 24 | * applyMiddleware(...middlewares) 25 | * 返回值 26 | * return { 27 | ...store, 28 | dispatch 29 | } 30 | * 31 | koa框架或者cuty等的数据流模型 32 | request ===> middleware ===> controller ===> response 33 | redux的数据流模型 34 | previouseState 35 | ===> action ===> reducers ==> 36 | nextState 37 | 38 | dispatch(action) ===> reducers 39 | 40 | === monkeyPatch == 41 | let _dispatch = store.dispatch; 42 | let log = (action)=>{console.log(action)} 43 | dispatch = (action)=>{ 44 | log(action); //打印日志 45 | _dispatch(action) ;//执行真正的逻辑 46 | } 47 | //日志中间件 48 | //devtool 49 | curry 化 ==> 50 | 1. 多参函数转换成单参函数 51 | 2. 灵活化闭包 52 | */ 53 | // 高阶函数 54 | import { createStore, applyMiddleware } from 'redux'; 55 | const logger1 = store => next => action => { 56 | console.log('current dipatch' + JSON.stringify(action)); 57 | next(action); 58 | }; 59 | const logger2 = store => next => action=> { 60 | next(action); 61 | }; 62 | const logger3 = store => next => action=> { 63 | next(action); 64 | }; 65 | 66 | 67 | // return funcs.reduce(function (a, b) { 68 | // return function () { 69 | // return a(b.apply(undefined, arguments)); 70 | // }; 71 | // }); 72 | // a = logger1 73 | // b = logger2 74 | 75 | // a1 = (arg1) => logger1(logger2(arg1)) 76 | // b1 = logger3; 77 | 78 | // a2 = (dispatch) => a1(logger3(dispatch)) 79 | 80 | 81 | 82 | const enhancer = applyMiddleware(logger1, logger2, logger3); 83 | const reducer = (state, action) => state; 84 | const store = createStore(reducer, {}, enhancer); 85 | store.dispatch({type:1}); 86 | store.dispatch({type:2}); 87 | store.dispatch({type:3}); 88 | 89 | // action ==> ==dispatch==> reducer ==> nextState; 90 | // action ==middlewares==> ==dispatch==> reducer ==> nextState; 91 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by slashhuang on 16/2/19. 3 | */ 4 | const fs = require('fs'); 5 | const webpack = require('webpack'); 6 | const path =require('path'); 7 | const ExtractTextPlugin = require("extract-text-webpack-plugin"); 8 | const Dir_prefix = path.resolve(__dirname,'src') 9 | module.exports = { 10 | watch:true, 11 | entry: Object.assign(fs.readdirSync(Dir_prefix).reduce((pre,cur)=>{ 12 | let absPath = path.resolve(Dir_prefix,cur); 13 | if(fs.statSync(absPath).isDirectory()){ 14 | if(fs.readdirSync(absPath).filter(name=>{ 15 | return name.match('index') 16 | }).length>0){ 17 | pre[cur] = path.resolve(absPath,'index.js'); 18 | } 19 | return pre; 20 | } 21 | if(path.extname(absPath).match('js') && !absPath.match('test')){ 22 | let base = path.basename(absPath,'.js'); 23 | pre[base] = absPath 24 | } 25 | return pre 26 | },{}),{ 27 | common:['babel-polyfill','react','react-dom']}), 28 | devtool:'source-map', 29 | output: { 30 | publicPath:'/dist/', 31 | path: path.join(__dirname,'dist'), 32 | filename: "[name].js", 33 | chunkFilename:'[name].js' 34 | }, 35 | plugins:[ 36 | new webpack.optimize.CommonsChunkPlugin({ 37 | name:'common', 38 | minChunks: Infinity, 39 | }), 40 | new ExtractTextPlugin({ 41 | filename: "[name].css", 42 | disable: false, 43 | allChunks: true 44 | }) 45 | ], 46 | resolve: { 47 | extensions: ['.js', '.jsx'] 48 | }, 49 | module: { 50 | loaders: [ 51 | { 52 | test: /\.js[x]?$/, 53 | loader: "babel-loader", 54 | exclude: /node_modules/ 55 | }, 56 | { 57 | test: /\.css$/, 58 | use: ExtractTextPlugin.extract({ 59 | fallback: "style-loader", 60 | use:{ 61 | loader:'css-loader', 62 | options: { 63 | sourceMap: true 64 | } 65 | } 66 | }) 67 | } 68 | ] 69 | } 70 | }; -------------------------------------------------------------------------------- /src/react/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 增加react decorator 3 | * @Author slashhuang 4 | * 17/3/24 5 | */ 6 | import React,{Component} from 'react';// ==> multi terminal 7 | //解构赋值 8 | import {render} from 'react-dom'; //dom 层面的渲染 9 | const RootDom= document.getElementById('root') 10 | /*------step 1--- get started 11 | * The template syntax in React is called JSX. 12 | * It is allowed in JSX to put HTML tags directly into JavaScript codes. 13 | * ReactDOM.render() is the method which translates JSX into HTML, 14 | * and renders it into the specified DOM node. 15 | */ 16 | //第一个参数是JSX,第二个参数是对应的dom节点 17 | // render(

Hello world

,RootDom) 18 | 19 | 20 | /** ----- step 2 ----- Use JavaScript in JSX 21 | * You could also use JavaScript in JSX. It takes angle brackets (<) as the beginning of HTML syntax, 22 | * and curly brackets ({) as the beginning of JavaScript syntax. 23 | */ 24 | // render(
25 | // { 26 | // ['react','饥人谷','学习'].map(function(name){ 27 | // return
Hello, {name}!
28 | // }) 29 | // } 30 | //
, 31 | // RootDom); 32 | 33 | 34 | /** ----- step 3 ----- Use array in JSX 35 | * If a JavaScript variable is an array, 36 | * JSX will implicitly concat all members of the array 37 | */ 38 | 39 | // let arr = [ 40 | //

Hello world!

, 41 | //

React is awesome

42 | // ]; 43 | // render(
{arr}
,RootDom); 44 | 45 | // const A = (props)=>{ 46 | // return
{props.gender } + {props.name}
47 | // } 48 | // props ==> properties {gender:'male',name:'slashhuang'} 49 | // render(,RootDom) 50 | 51 | 52 | 53 | /** ----- step 4 ----- Define a component 54 | * a component class, 55 | * which implements a render method to return an component instance of the class. 56 | * You don't need to call new on the class in order to get an instance, j 57 | * ust use it as a normal HTML tag. 58 | */ 59 | 60 | // lifecycle ===> 生命周期 61 | // 组件化 state + props ==> 62 | // class FirstComponent extends Component{ 63 | // constructor(){ 64 | // super(); 65 | // this.state={ 66 | // b:1 67 | // } 68 | // } 69 | // shouldComponentUpdate(){ 70 | // console.log('shouldComponentUpdate') 71 | // } 72 | // componentWillUnmount(){ 73 | // console.log('componentWillUnmount') 74 | // } 75 | // componentDidUpdate(){ 76 | // console.log('componentDidUpdate') 77 | // } 78 | // componentWillUpdate(){ 79 | // console.log('componentWillUpdate') 80 | // } 81 | // componentWillReceiveProps(){ 82 | // console.log('componentWillReceiveProps') 83 | // } 84 | // componentWillMount(){ 85 | // console.log('componentWillMount') 86 | // } 87 | // componentDidMount (){ 88 | // this.setState({b:1}) 89 | // console.log('componentDidMount') 90 | // } 91 | // render(){ 92 | // debugger; 93 | // console.log('render') 94 | // let a = '3/26' 95 | // return
96 | // I am a component 97 | // {a} 98 | // {this.state.b} 99 | //
100 | // } 101 | // }; 102 | 103 | // render(,RootDom); 104 | 105 | 106 | 107 | 108 | 109 | /** ----- step 5 ----- this.props.children 110 | * React uses this.props.children to access a component's children nodes. 111 | */ 112 | // class ChildComponent extends Component{ 113 | // render(){ 114 | // return
{this.props.children}
115 | // } 116 | // }; 117 | // render(我是个孩子,RootDom); 118 | 119 | /** ----- step 6 ----- state and props 120 | * React uses state and props to struct a component model 121 | */ 122 | //MVVM ==> model view viewModel 123 | 124 | class PropState extends Component{ 125 | constructor(){ 126 | super(); 127 | this.state={a:'I am state'} 128 | } 129 | click(){ 130 | this.setState({ 131 | a:'我更新啦 哈哈哈' 132 | })//=> 更新逻辑 133 | } 134 | //更新 135 | render(){ 136 | return
this.click()}> 137 | {this.state.a} 138 | {this.props.b} 139 | {this.props.c} 140 |
141 | } 142 | }; 143 | // data==> Another 144 | class Another extends Component{ 145 | constructor(){ 146 | super(); 147 | this.state={ 148 | prop1 : '我是another的第一个prop' 149 | }; 150 | } 151 | click(){ 152 | this.setState({ 153 | prop1 : '我是another的第而个prop' 154 | }) 155 | } 156 | render(){ 157 | //inline 158 | let compo = ; 159 | return
this.click()}> 160 | 我在another里面啦 161 | { compo } 162 |
163 | } 164 | }; 165 | render(,RootDom); 166 | 167 | 168 | 169 | --------------------------------------------------------------------------------