├── vuex ├── store.js └── index.html ├── vue-router ├── history │ ├── index.js │ ├── index.html │ └── router.js ├── hash │ ├── index.html │ └── router.js └── router │ ├── index.html │ └── vue-router.js ├── promise ├── index.html └── promise.js └── README.md /vuex/store.js: -------------------------------------------------------------------------------- 1 | class Store { 2 | constructor (Vue, options) { 3 | var bus = new Vue({ 4 | data: { 5 | state: options.state 6 | } 7 | }) 8 | 9 | this.install(Vue, bus) 10 | } 11 | 12 | install (Vue, bus) { 13 | Vue.mixin({ 14 | beforeCreate () { 15 | if (this.$options.store) { 16 | Vue.prototype.$store = bus 17 | } 18 | } 19 | }) 20 | } 21 | } -------------------------------------------------------------------------------- /vue-router/history/index.js: -------------------------------------------------------------------------------- 1 | var http = require('http'); 2 | var fs = require('fs'); 3 | 4 | http.createServer(function (req, res) { 5 | var filepath = '.' + req.url; 6 | if (filepath === './') { 7 | filepath = './index.html'; 8 | } 9 | 10 | readFile(filepath, res); 11 | }).listen(80); 12 | 13 | function readFile (path, res) { 14 | fs.readFile(path, 'utf-8', function (err, data) { 15 | if (err) { 16 | readFile('./index.html', res); 17 | } else { 18 | res.write(data); 19 | res.end(); 20 | } 21 | }); 22 | } 23 | 24 | console.log('Server running at http://127.0.0.1:80/'); -------------------------------------------------------------------------------- /vue-router/hash/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hash 路由 6 | 7 | 8 |
9 | home 10 | book 11 | movie 12 | 13 |
14 |
15 | 16 | 17 | 33 | 34 | -------------------------------------------------------------------------------- /vue-router/hash/router.js: -------------------------------------------------------------------------------- 1 | class Router { 2 | constructor (options) { 3 | this.routes = {}; 4 | 5 | this.init(); 6 | 7 | // 遍历,绑定视图更新 8 | options.forEach(item => { 9 | this.route(item.path, () => { 10 | document.getElementById('content').innerHTML = item.component; 11 | }); 12 | }); 13 | } 14 | 15 | // 绑定监听事件 16 | init () { 17 | window.addEventListener('load', this.updateView.bind(this), false); 18 | window.addEventListener('hashchange', this.updateView.bind(this), false); 19 | } 20 | 21 | // 更新试图 22 | updateView () { 23 | const currentUrl = window.location.hash.slice(1) || '/'; 24 | this.routes[currentUrl] && this.routes[currentUrl](); 25 | } 26 | 27 | // 将路由与回调函数关联 28 | route (path, cb) { 29 | this.routes[path] = cb; 30 | } 31 | } -------------------------------------------------------------------------------- /promise/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 实现一个 Promise 5 | 6 | 7 | 8 | 9 | 33 | 34 | -------------------------------------------------------------------------------- /vue-router/history/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | History 路由 6 | 7 | 8 |
9 | home 10 | book 11 | movie 12 | 13 |
14 |
15 | 16 | 17 | 33 | 34 | -------------------------------------------------------------------------------- /promise/promise.js: -------------------------------------------------------------------------------- 1 | function MyPromise (fn) { 2 | var _this = this; 3 | 4 | this.callback = []; 5 | this.isResolved = false; 6 | 7 | function resolve (val) { 8 | if (_this.isResolved) return; 9 | _this.isResolved = true; 10 | 11 | if (_this.callback.length > 0) { 12 | _this.callback.forEach(function (item) { 13 | var res; 14 | var cb = item.cb; 15 | var resolve = item.resolve; 16 | 17 | cb && (res = cb(val)); 18 | if (typeof res === 'object' && res.then) { 19 | res.then(resolve); 20 | } else { 21 | resolve && resolve(res); 22 | } 23 | }); 24 | } 25 | } 26 | 27 | fn(resolve); 28 | } 29 | 30 | MyPromise.prototype.then = function (cb) { 31 | var _this = this; 32 | 33 | return new MyPromise(function (resolve) { 34 | _this.callback.push({ 35 | cb: cb, 36 | resolve: resolve 37 | }); 38 | }); 39 | }; -------------------------------------------------------------------------------- /vue-router/router/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 实现一个 vue-router 6 | 7 | 8 | 9 |
10 |

11 | home 12 | book 13 | movie 14 |

15 | 16 |
17 | 18 | 19 | 20 | 21 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /vue-router/history/router.js: -------------------------------------------------------------------------------- 1 | class Router { 2 | constructor (options) { 3 | this.routes = {}; 4 | 5 | this.init(); 6 | this.bindEvent(); 7 | 8 | // 遍历,绑定视图更新 9 | options.forEach(item => { 10 | this.route(item.path, () => { 11 | document.getElementById('content').innerHTML = item.component; 12 | }); 13 | }); 14 | } 15 | 16 | // 绑定点击事件 17 | bindEvent () { 18 | const _this = this; 19 | const links = document.getElementsByTagName('a'); 20 | 21 | [].forEach.call(links, link => { 22 | link.addEventListener('click', function () { 23 | const url = this.getAttribute('data-href'); 24 | _this.push(url); 25 | }); 26 | }); 27 | } 28 | 29 | // 绑定监听事件 30 | init () { 31 | window.addEventListener('load', this.updateView.bind(this), false); 32 | window.addEventListener('popstate', this.updateView.bind(this), false); 33 | } 34 | 35 | push (url) { 36 | window.history.pushState({}, null, url); 37 | this.updateView(); 38 | } 39 | 40 | // 更新试图 41 | updateView () { 42 | const currentUrl = window.location.pathname || '/'; 43 | this.routes[currentUrl] && this.routes[currentUrl](); 44 | } 45 | 46 | // 将路由与回调函数关联 47 | route (path, cb) { 48 | this.routes[path] = cb; 49 | } 50 | } -------------------------------------------------------------------------------- /vue-router/router/vue-router.js: -------------------------------------------------------------------------------- 1 | class VueRouter { 2 | constructor (Vue, options) { 3 | this.$options = options; 4 | this.routeMap = {}; 5 | this.app = new Vue({ 6 | data: { 7 | current: '#/' 8 | } 9 | }); 10 | 11 | this.init(); 12 | this.createRouteMap(this.$options); 13 | this.initComponent(Vue); 14 | } 15 | 16 | // 绑定事件 17 | init () { 18 | window.addEventListener('load', this.onHashChange.bind(this), false); 19 | window.addEventListener('hashchange', this.onHashChange.bind(this), false); 20 | } 21 | 22 | // 路由映射表 23 | createRouteMap (options) { 24 | options.routes.forEach(item => { 25 | this.routeMap[item.path] = item.component; 26 | }); 27 | } 28 | 29 | // 注册组件 30 | initComponent (Vue) { 31 | Vue.component('router-link', { 32 | props: { 33 | to: String 34 | }, 35 | template: '' 36 | }); 37 | 38 | const _this = this; 39 | Vue.component('router-view', { 40 | render (h) { 41 | var component = _this.routeMap[_this.app.current]; 42 | return h(component); 43 | } 44 | }); 45 | } 46 | 47 | // 获取当前 hash 串 48 | getHash () { 49 | return window.location.hash.slice(1) || '/'; 50 | } 51 | 52 | // 设置当前路径 53 | onHashChange () { 54 | this.app.current = this.getHash(); 55 | } 56 | } -------------------------------------------------------------------------------- /vuex/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 实现一个 vuex 5 | 14 | 15 | 16 | 17 |
18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # code-analysis 2 | 3 | ## vue 4 | 5 | > 基于 v2.0.1 版本 6 | 7 | 1. [vue 源码:整体概况](https://github.com/cobish/code-analysis/issues/22) 8 | 2. [vue 源码:如何调试源码](https://github.com/cobish/code-analysis/issues/23) 9 | 3. ...... 10 | 11 | ## vue-router 12 | 13 | > 基于 v2.1.0 版本 14 | 15 | 1. [vue-router 源码:前端路由](https://github.com/cobish/code-analysis/issues/15) 16 | 2. [vue-router 源码:实现一个简单的 vue-router](https://github.com/cobish/code-analysis/issues/16) 17 | 3. [vue-router 源码:路由的安装与初始化](https://github.com/cobish/code-analysis/issues/17) 18 | 4. [vue-router 源码:路由模式](https://github.com/cobish/code-analysis/issues/18) 19 | 5. [vue-router 源码:导航守卫](https://github.com/cobish/code-analysis/issues/19) 20 | 6. [vue-router 源码:路由匹配](https://github.com/cobish/code-analysis/issues/20) 21 | 7. [vue-router 源码:组件](https://github.com/cobish/code-analysis/issues/21) 22 | 23 | ## vuex 24 | 25 | > 基于 v2.0.0 版本 26 | 27 | 1. [vuex 源码:如何实现一个简单的 vuex](https://github.com/cobish/code-analysis/issues/1) 28 | 2. [vuex 源码:初探 vuex 之 install](https://github.com/cobish/code-analysis/issues/2) 29 | 3. [vuex 源码:深入 vuex 之 state](https://github.com/cobish/code-analysis/issues/3) 30 | 4. [vuex 源码:深入 vuex 之 getter](https://github.com/cobish/code-analysis/issues/4) 31 | 5. [vuex 源码:深入 vuex 之 mutation](https://github.com/cobish/code-analysis/issues/5) 32 | 6. [vuex 源码:深入 vuex 之 action](https://github.com/cobish/code-analysis/issues/6) 33 | 7. [vuex 源码:深入 vuex 之 module](https://github.com/cobish/code-analysis/issues/7) 34 | 8. [vuex 源码:深入 vuex 之 namespaced](https://github.com/cobish/code-analysis/issues/8) 35 | 9. [vuex 源码:深入 vuex 之辅助函数 mapState](https://github.com/cobish/code-analysis/issues/9) 36 | 37 | ## Promise 38 | 39 | > 基于 then/promise v3.0.0 版本 40 | 41 | 1. [Promise 源码:实现一个简单的 Promise](https://github.com/cobish/code-analysis/issues/10) 42 | 2. [Promise 源码:同步执行 resolve](https://github.com/cobish/code-analysis/issues/11) 43 | 3. [Promise 源码:异步执行 resolve](https://github.com/cobish/code-analysis/issues/12) 44 | 4. [Promise 源码:then 链式调用](https://github.com/cobish/code-analysis/issues/13) 45 | 5. [Promise 源码:静态方法](https://github.com/cobish/code-analysis/issues/14) 46 | --------------------------------------------------------------------------------