├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── README.md ├── blog ├── JavaScript核心原理解析.md ├── vue3对比vue2.md └── 从0开始学架构.md ├── package-lock.json ├── package.json ├── post ├── HTTP协议原理+实践 │ └── README.md ├── Javascript忍者秘籍2 │ ├── 02.运行时的页面构建过程.md │ ├── 03.理解函数.md │ ├── 04.函数进阶:理解函数调用.md │ ├── 05.精通函数:闭包和作用域.md │ ├── 06.未来的函数:生成器和promise.md │ ├── 07.面向对象与原型.md │ ├── 08.控制对象的访问.md │ ├── 09.处理集合.md │ ├── 10.正则表达式.md │ ├── 11.代码模块化.md │ ├── 12.DOM操作.md │ ├── 13.历久弥新的事件.md │ ├── 14.跨浏览器开发技巧.md │ ├── 15.附录.md │ └── source │ │ ├── assert.html │ │ ├── match.html │ │ └── proxy.html ├── Javascript核心技术开发解密 │ ├── 01.三种基础数据结构 │ │ └── README.md │ ├── 02.内存空间 │ │ └── README.md │ ├── 03.执行上下文 │ │ └── README.md │ ├── 04.变量对象 │ │ ├── README.md │ │ └── src │ │ │ └── index.html │ ├── 05.作用域与作用域链 │ │ └── README.md │ ├── 06.闭包 │ │ ├── README.md │ │ └── src │ │ │ ├── README.md │ │ │ ├── demo1.html │ │ │ ├── demo2.html │ │ │ ├── demo3.html │ │ │ ├── demo4.html │ │ │ └── index.html │ ├── 07.this │ │ ├── README.md │ │ └── src │ │ │ └── demo1.html │ ├── 08.函数与函数式编程 │ │ ├── README.md │ │ └── src │ │ │ ├── demo1.html │ │ │ ├── demo1.js │ │ │ └── demo2.js │ ├── 09.面向对象 │ │ ├── README.md │ │ └── src │ │ │ ├── demo1.html │ │ │ ├── demo1.js │ │ │ ├── demo2.js │ │ │ ├── jQuery.simple.js │ │ │ ├── 拖拽 │ │ │ ├── drag.html │ │ │ ├── drag.jquery.js │ │ │ ├── drag.module.js │ │ │ └── drag.simple.js │ │ │ ├── 无缝滚动 │ │ │ ├── scroll.html │ │ │ ├── scroll.js │ │ │ └── scroll.module.js │ │ │ └── 选项卡 │ │ │ ├── tab.html │ │ │ ├── tab.js │ │ │ └── tab.module.js │ ├── 10.ES6 与模块化 │ │ ├── README.md │ │ └── src │ │ │ └── es6app │ │ │ ├── public │ │ │ └── index.html │ │ │ └── src │ │ │ ├── box.js │ │ │ ├── controlBtns │ │ │ ├── bdColor.js │ │ │ ├── bgColor.js │ │ │ ├── height.js │ │ │ ├── index.js │ │ │ ├── showBtn.js │ │ │ └── width.js │ │ │ ├── index.js │ │ │ ├── register.js │ │ │ ├── state.js │ │ │ └── utils.js │ └── README.md ├── Javascript高级程序设计 │ ├── 13-14 │ │ └── README.md │ ├── 15-20 │ │ └── README.md │ ├── 21-25 │ │ └── README.md │ ├── 4-6 │ │ └── README.md │ ├── 7-10 │ │ └── README.md │ └── README.md ├── Nodejs微服务 │ ├── 01.微服务架构.md │ ├── 02.基于Seneca和PM2构建Node.js微服务.md │ ├── 03.从单块软件到微服务.md │ ├── 04.编写你的第一个Node.js微服务.md │ └── source │ │ ├── index.js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── report │ │ ├── email.js │ │ ├── index.js │ │ ├── post.js │ │ └── sms.js │ │ └── seneca │ │ ├── demo.js │ │ ├── minimal-plugin.js │ │ ├── plugin.js │ │ ├── sum.js │ │ ├── web.js │ │ └── word.js ├── Python学习笔记 │ ├── README.md │ └── source │ │ ├── Requests.py │ │ ├── followers.json │ │ ├── hello.py │ │ └── weixincrawler │ │ └── crawler.py ├── js基础 │ ├── 1.js基础知识(上).html │ ├── 1.js基础知识(下).html │ ├── 1.js基础知识(中).html │ ├── 2.JS-Web-API(上).html │ ├── 2.JS-Web-API(下).html │ ├── 3.开发环境.html │ ├── 4.运行环境.html │ ├── AMD │ │ ├── a-util.js │ │ ├── a.js │ │ ├── index.html │ │ ├── main.js │ │ └── util.js │ ├── CMD │ │ ├── dist │ │ │ └── bundle.js │ │ ├── index.html │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ │ ├── a-util.js │ │ │ └── app.js │ │ └── webpack.config.js │ ├── JS-Web-API(上).md │ ├── JS-Web-API(下).md │ ├── js基础知识(上).md │ ├── js基础知识(下).md │ ├── js基础知识(中).md │ ├── 原型对象.png │ ├── 开发环境.md │ └── 运行环境.md ├── js高级面试 │ ├── code │ │ ├── async │ │ │ ├── data.json │ │ │ ├── deferred.html │ │ │ ├── index.html │ │ │ └── promise.html │ │ ├── es6 │ │ │ ├── class │ │ │ │ ├── index.html │ │ │ │ └── index.js │ │ │ ├── rollup │ │ │ │ ├── .babelrc │ │ │ │ ├── build │ │ │ │ │ └── bundle.js │ │ │ │ ├── index.html │ │ │ │ ├── package.json │ │ │ │ ├── rollup.config.js │ │ │ │ └── src │ │ │ │ │ ├── index-1.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── util1.js │ │ │ │ │ └── util2.js │ │ │ ├── webpack-wfp │ │ │ │ ├── .babelrc │ │ │ │ ├── build │ │ │ │ │ └── bundle.js │ │ │ │ ├── index.html │ │ │ │ ├── package.json │ │ │ │ ├── src │ │ │ │ │ ├── index.js │ │ │ │ │ ├── util1.js │ │ │ │ │ └── util2.js │ │ │ │ └── webpack.config.js │ │ │ └── webpack │ │ │ │ ├── .babelrc │ │ │ │ ├── build │ │ │ │ └── bundle.js │ │ │ │ ├── index.html │ │ │ │ ├── package.json │ │ │ │ ├── src │ │ │ │ ├── index.js │ │ │ │ ├── util1.js │ │ │ │ └── util2.js │ │ │ │ └── webpack.config.js │ │ ├── framework │ │ │ ├── jsx-test │ │ │ │ ├── .babelrc │ │ │ │ ├── demo.jsx │ │ │ │ ├── package.json │ │ │ │ └── test.jsx │ │ │ ├── mvvm │ │ │ │ ├── defineProperty.html │ │ │ │ ├── demo.html │ │ │ │ ├── simplehtmlparser.html │ │ │ │ ├── simplehtmlparser.js │ │ │ │ ├── test.html │ │ │ │ ├── vue-2.5.13.js │ │ │ │ └── vue-2.5.9.js │ │ │ ├── preact.js │ │ │ ├── to-do-list │ │ │ │ ├── jquery │ │ │ │ │ └── index.html │ │ │ │ ├── react-test │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── README.md │ │ │ │ │ ├── package.json │ │ │ │ │ ├── public │ │ │ │ │ │ ├── favicon.ico │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── manifest.json │ │ │ │ │ └── src │ │ │ │ │ │ ├── App.css │ │ │ │ │ │ ├── App.js │ │ │ │ │ │ ├── App.test.js │ │ │ │ │ │ ├── components │ │ │ │ │ │ └── todo │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── input │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ │ └── list │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── logo.svg │ │ │ │ │ │ └── registerServiceWorker.js │ │ │ │ └── vue │ │ │ │ │ ├── demo.html │ │ │ │ │ ├── index.html │ │ │ │ │ └── vue-2.5.13.js │ │ │ └── vdom │ │ │ │ ├── diff │ │ │ │ ├── log1.txt │ │ │ │ └── log2.txt │ │ │ │ ├── jquery │ │ │ │ └── index.html │ │ │ │ ├── snabbdom │ │ │ │ ├── demo.html │ │ │ │ └── index.html │ │ │ │ └── source │ │ │ │ ├── createElement.js │ │ │ │ └── updateChildren.js │ │ ├── hybrid │ │ │ ├── invoke.js │ │ │ └── schema.html │ │ ├── index.txt │ │ └── prototype │ │ │ ├── jquery │ │ │ ├── demo.html │ │ │ ├── index.html │ │ │ ├── jquery-3.2.1.js │ │ │ └── my-jquery.js │ │ │ └── zepto │ │ │ ├── index.html │ │ │ ├── my-zepto.js │ │ │ └── zepto-1.2.0.js │ ├── demo.html │ ├── vue双向数据绑定(es5).html │ ├── vue双向数据绑定(es6).html │ ├── 实现简易react.js.html │ ├── 知识点.md │ └── 面向切面.html ├── one-light │ ├── 01.JavaScript │ │ ├── 01.预读班 │ │ │ ├── 01.你不知道的HTML.md │ │ │ ├── 02.CSS3构建3D的世界.md │ │ │ ├── 03.CSS高级实用技巧.md │ │ │ ├── 04.CSS与数学的巧妙运用.md │ │ │ ├── 05.ES5核心技术.md │ │ │ ├── 06.jQuery技术内幕.md │ │ │ ├── 07.走进后端工程师的世界.md │ │ │ ├── 08.常用后端语言的介绍.md │ │ │ └── README.md │ │ ├── 02.linux基础入门 │ │ │ └── README.md │ │ ├── 03.ECMAScript5.1新增语法 │ │ │ └── README.md │ │ ├── 04.php与mysql开发入门 │ │ │ ├── 01.PHP基础入门.md │ │ │ ├── 02.PHP面向对象.md │ │ │ ├── 03.PHP与MySQL操作.md │ │ │ └── README.md │ │ ├── 05.ES6 │ │ │ └── README.md │ │ ├── 06.深度实践课 │ │ │ ├── Javascript&QA.md │ │ │ ├── 01.JavaScript与QA工程师.md │ │ │ ├── JavaScript-Functional-Programming.md │ │ │ ├── Javascript语言新发展【深度实践课】.md │ │ │ ├── README.md │ │ │ ├── paper.md │ │ │ └── source │ │ │ │ ├── functional │ │ │ │ ├── Monad.js │ │ │ │ └── functional.js │ │ │ │ ├── index.html │ │ │ │ └── paper.js │ │ └── README.md │ ├── README.md │ └── other.md ├── webpck4初体验 │ ├── 01.webpack基本配置介绍.md │ ├── 02.配置loader.md │ ├── 03.配置plugin.md │ ├── 04.更好地使用 webpack-dev-server.md │ ├── 05.开发和生产环境的构建配置差异.md │ ├── 06.用 HMR 提高开发效率.md │ ├── 07.优化前端资源加载.md │ ├── 08.提升 webpack 的构建速度.md │ ├── 09.探究 webpack 内部工作流程.md │ ├── 10.创建自己的 loader.md │ ├── 11.创建自己的 plugin.md │ ├── 12.总结.md │ └── README.md ├── web前后端漏洞分析与防御 │ ├── source │ │ ├── project.zip │ │ └── t1eexx │ │ │ ├── .editorconfig │ │ │ ├── .eslintrc.js │ │ │ ├── .gitignore │ │ │ ├── controllers │ │ │ ├── site.js │ │ │ └── user.js │ │ │ ├── models │ │ │ └── connection.js │ │ │ ├── other │ │ │ ├── Untitled.sketch │ │ │ ├── clickhijack.html │ │ │ ├── clickhijack.png │ │ │ └── csrf.html │ │ │ ├── package-lock.json │ │ │ ├── package.json │ │ │ ├── routes │ │ │ ├── site.js │ │ │ └── user.js │ │ │ ├── safety.sql │ │ │ ├── server.js │ │ │ ├── static │ │ │ ├── config.js │ │ │ ├── materialize │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── css │ │ │ │ │ ├── main.css │ │ │ │ │ ├── materialize.css │ │ │ │ │ └── materialize.min.css │ │ │ │ ├── fonts │ │ │ │ │ └── roboto │ │ │ │ │ │ ├── Roboto-Bold.eot │ │ │ │ │ │ ├── Roboto-Bold.ttf │ │ │ │ │ │ ├── Roboto-Bold.woff │ │ │ │ │ │ ├── Roboto-Bold.woff2 │ │ │ │ │ │ ├── Roboto-Light.eot │ │ │ │ │ │ ├── Roboto-Light.ttf │ │ │ │ │ │ ├── Roboto-Light.woff │ │ │ │ │ │ ├── Roboto-Light.woff2 │ │ │ │ │ │ ├── Roboto-Medium.eot │ │ │ │ │ │ ├── Roboto-Medium.ttf │ │ │ │ │ │ ├── Roboto-Medium.woff │ │ │ │ │ │ ├── Roboto-Medium.woff2 │ │ │ │ │ │ ├── Roboto-Regular.eot │ │ │ │ │ │ ├── Roboto-Regular.ttf │ │ │ │ │ │ ├── Roboto-Regular.woff │ │ │ │ │ │ ├── Roboto-Regular.woff2 │ │ │ │ │ │ ├── Roboto-Thin.eot │ │ │ │ │ │ ├── Roboto-Thin.ttf │ │ │ │ │ │ ├── Roboto-Thin.woff │ │ │ │ │ │ └── Roboto-Thin.woff2 │ │ │ │ └── js │ │ │ │ │ ├── materialize.js │ │ │ │ │ └── materialize.min.js │ │ │ └── scripts │ │ │ │ ├── login.js │ │ │ │ └── ui │ │ │ │ └── modal.js │ │ │ ├── todo.todo │ │ │ └── views │ │ │ ├── index.pug │ │ │ ├── login.pug │ │ │ └── post.pug │ ├── xss攻击原理.png │ ├── 前端安全.md │ ├── 明文密码泄露.png │ └── 确定服务器身份.png ├── 前端工程化 │ ├── 01.前端工程简史 │ │ └── README.md │ ├── 02.脚手架 │ │ └── README.md │ └── 03.构建 │ │ └── README.md ├── 前端性能优化 │ ├── serviceWorker │ │ ├── app.js │ │ ├── main.css │ │ ├── msg-demo.html │ │ ├── msgapp.js │ │ ├── msgsw.js │ │ ├── service-worker.js │ │ └── serviceWorker.html │ ├── workspace │ │ ├── css、js的加载与执行.pptx │ │ ├── indexDB.html │ │ ├── 图片相关的优化.pptx │ │ ├── 懒加载与预加载.pptx │ │ ├── 浏览器存储.pptx │ │ ├── 资源合并与压缩.pptx │ │ └── 重绘与回流.pptx │ ├── 前端性能优化.md │ └── 缓存 │ │ ├── app.js │ │ ├── assets │ │ └── view.jpg │ │ ├── config.js │ │ └── mime.js ├── 数据结构与算法 │ ├── 01.数组.md │ ├── 02.栈.md │ ├── 03.队列.md │ ├── 04.链表.md │ ├── 05.集合.md │ ├── 06.字典.md │ ├── 07.散列表.md │ ├── 08.树.md │ └── source │ │ ├── Dictionary.js │ │ ├── Hash.js │ │ ├── LinkList.js │ │ ├── Set.js │ │ └── Tree.js ├── 计算机组成原理+操作系统+计算机网络 │ ├── 01.计算机组成原理.md │ ├── 02.操作系统.md │ └── 03.计算机网络.md ├── 设计模式与开发实践 │ ├── 01.创建型设计模式 │ │ ├── 单例模式.md │ │ ├── 原型模式.md │ │ ├── 工厂方法模式.md │ │ ├── 建造者模式.md │ │ ├── 抽象工厂模式.md │ │ └── 简单工厂模式.md │ ├── 02.结构型设计模式 │ │ ├── 享元模式.md │ │ ├── 代理模式.md │ │ ├── 外观模式.md │ │ ├── 桥接模式.md │ │ ├── 组合模式.md │ │ ├── 装饰者模式.md │ │ └── 适配器模式.md │ ├── 03.行为型设计模式 │ │ ├── 命令模式.md │ │ ├── 模板方法模式.md │ │ ├── 状态模式.md │ │ ├── 策略模式.md │ │ ├── 职责链模式.md │ │ ├── 观察者模式.md │ │ └── 访问者模式.md │ ├── source │ │ ├── index.html │ │ ├── park.js │ │ └── park.png │ └── 面向对象的JS.md └── 高效前端:Web高效编程与优化实践 │ ├── Effective 14 │ └── 实现前端裁剪压缩图片.md │ ├── Effective 15 │ └── 实现跨浏览器的HTML5表单验证.md │ ├── Effective 26 │ └── 掌握前端本地文件操作与上传.md │ ├── Effective 27 │ └── src │ │ ├── img │ │ └── coder.jpg │ │ └── index.html │ ├── Effective 31 │ ├── src │ │ └── index.html │ └── 理解移动端click及自定义事件.md │ ├── Effective 32 │ ├── src │ │ ├── children.html │ │ ├── demo.js │ │ ├── index.html │ │ └── parent.html │ └── 学习JS高级技巧.md │ ├── Effective 33 │ ├── src │ │ ├── README.md │ │ ├── conf.js │ │ ├── demo.sh │ │ ├── karma.conf.js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ │ └── util.js │ │ ├── test-spec.js │ │ ├── test │ │ │ └── util-test.js │ │ └── util-test │ │ │ └── index.js │ └── 前端的单元测试与自动化测试.md │ ├── README.md │ └── js │ └── list.js ├── source-learn ├── collect │ ├── aop.js │ ├── factorial.js │ ├── fib.js │ ├── index.html │ ├── stack.js │ └── template.js ├── es6 │ ├── es6.html │ └── es6.js ├── jQuery │ ├── README.md │ ├── ajax.js │ ├── index.html │ ├── jquery.js │ └── lsx-jquery.js ├── promise │ ├── README.md │ ├── demo.js │ ├── promise.html │ ├── promise.js │ ├── promise_done.js │ ├── v1.0_promise.js │ ├── v2.0_promise.js │ ├── v3.0_promise.js │ └── v4.0_promise.js ├── vscode.conf.js ├── vue源码分析 │ ├── README.md │ ├── demo │ │ ├── index.html │ │ ├── observe.js │ │ └── observe1.js │ ├── observe-demo │ │ ├── index.html │ │ ├── observe.js │ │ ├── proxy-demo.js │ │ └── proxy-observe.js │ ├── source │ │ ├── index.html │ │ ├── juejin │ │ │ ├── Vue流程图.xmind │ │ │ ├── 《Vuex状态管理的工作原理》.js │ │ │ ├── 《template 模板是怎样通过 Compile 编译的》.js │ │ │ ├── 《响应式系统的依赖收集追踪原理》.js │ │ │ ├── 《响应式系统的基本原理》.js │ │ │ ├── 《实现 Virtual DOM 下的一个 VNode 节点》.js │ │ │ ├── 《批量异步更新策略及 nextTick 原理》.js │ │ │ └── 《数据状态更新时的差异 diff 及 patch 机制》.js │ │ ├── reactive.js │ │ ├── state.js │ │ ├── vue-router-src │ │ │ ├── components │ │ │ │ ├── link.js │ │ │ │ └── view.js │ │ │ ├── create-matcher.js │ │ │ ├── create-route-map.js │ │ │ ├── history │ │ │ │ ├── abstract.js │ │ │ │ ├── base.js │ │ │ │ ├── hash.js │ │ │ │ └── html5.js │ │ │ ├── index.js │ │ │ ├── install.js │ │ │ └── util │ │ │ │ ├── async.js │ │ │ │ ├── dom.js │ │ │ │ ├── location.js │ │ │ │ ├── params.js │ │ │ │ ├── path.js │ │ │ │ ├── push-state.js │ │ │ │ ├── query.js │ │ │ │ ├── resolve-components.js │ │ │ │ ├── route.js │ │ │ │ ├── scroll.js │ │ │ │ └── warn.js │ │ ├── vue-src │ │ │ ├── compiler │ │ │ │ ├── codegen │ │ │ │ │ ├── events.js │ │ │ │ │ └── index.js │ │ │ │ ├── directives │ │ │ │ │ ├── bind.js │ │ │ │ │ ├── index.js │ │ │ │ │ └── model.js │ │ │ │ ├── error-detector.js │ │ │ │ ├── helpers.js │ │ │ │ ├── index.js │ │ │ │ ├── optimizer.js │ │ │ │ └── parser │ │ │ │ │ ├── entity-decoder.js │ │ │ │ │ ├── filter-parser.js │ │ │ │ │ ├── html-parser.js │ │ │ │ │ ├── index.js │ │ │ │ │ └── text-parser.js │ │ │ ├── core │ │ │ │ ├── components │ │ │ │ │ ├── index.js │ │ │ │ │ └── keep-alive.js │ │ │ │ ├── config.js │ │ │ │ ├── global-api │ │ │ │ │ ├── assets.js │ │ │ │ │ ├── extend.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── mixin.js │ │ │ │ │ └── use.js │ │ │ │ ├── index.js │ │ │ │ ├── instance │ │ │ │ │ ├── events.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── init.js │ │ │ │ │ ├── inject.js │ │ │ │ │ ├── lifecycle.js │ │ │ │ │ ├── proxy.js │ │ │ │ │ ├── render-helpers │ │ │ │ │ │ ├── bind-object-props.js │ │ │ │ │ │ ├── check-keycodes.js │ │ │ │ │ │ ├── render-list.js │ │ │ │ │ │ ├── render-slot.js │ │ │ │ │ │ ├── render-static.js │ │ │ │ │ │ ├── resolve-filter.js │ │ │ │ │ │ └── resolve-slots.js │ │ │ │ │ ├── render.js │ │ │ │ │ └── state.js │ │ │ │ ├── observer │ │ │ │ │ ├── array.js │ │ │ │ │ ├── dep.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── scheduler.js │ │ │ │ │ └── watcher.js │ │ │ │ ├── util │ │ │ │ │ ├── debug.js │ │ │ │ │ ├── env.js │ │ │ │ │ ├── error.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── lang.js │ │ │ │ │ ├── options.js │ │ │ │ │ ├── perf.js │ │ │ │ │ └── props.js │ │ │ │ └── vdom │ │ │ │ │ ├── create-component.js │ │ │ │ │ ├── create-element.js │ │ │ │ │ ├── create-functional-component.js │ │ │ │ │ ├── helpers │ │ │ │ │ ├── extract-props.js │ │ │ │ │ ├── get-first-component-child.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── merge-hook.js │ │ │ │ │ ├── normalize-children.js │ │ │ │ │ ├── resolve-async-component.js │ │ │ │ │ └── update-listeners.js │ │ │ │ │ ├── modules │ │ │ │ │ ├── directives.js │ │ │ │ │ ├── index.js │ │ │ │ │ └── ref.js │ │ │ │ │ ├── patch.js │ │ │ │ │ └── vnode.js │ │ │ ├── platforms │ │ │ │ ├── web │ │ │ │ │ ├── compiler.js │ │ │ │ │ ├── compiler │ │ │ │ │ │ ├── directives │ │ │ │ │ │ │ ├── html.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── model.js │ │ │ │ │ │ │ └── text.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── modules │ │ │ │ │ │ │ ├── class.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ └── style.js │ │ │ │ │ │ └── util.js │ │ │ │ │ ├── runtime-with-compiler.js │ │ │ │ │ ├── runtime.js │ │ │ │ │ ├── runtime │ │ │ │ │ │ ├── class-util.js │ │ │ │ │ │ ├── components │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── transition-group.js │ │ │ │ │ │ │ └── transition.js │ │ │ │ │ │ ├── directives │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── model.js │ │ │ │ │ │ │ └── show.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── modules │ │ │ │ │ │ │ ├── attrs.js │ │ │ │ │ │ │ ├── class.js │ │ │ │ │ │ │ ├── dom-props.js │ │ │ │ │ │ │ ├── events.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── style.js │ │ │ │ │ │ │ └── transition.js │ │ │ │ │ │ ├── node-ops.js │ │ │ │ │ │ ├── patch.js │ │ │ │ │ │ └── transition-util.js │ │ │ │ │ ├── server-renderer.js │ │ │ │ │ ├── server │ │ │ │ │ │ ├── directives │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ └── show.js │ │ │ │ │ │ ├── modules │ │ │ │ │ │ │ ├── attrs.js │ │ │ │ │ │ │ ├── class.js │ │ │ │ │ │ │ ├── dom-props.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ └── style.js │ │ │ │ │ │ └── util.js │ │ │ │ │ └── util │ │ │ │ │ │ ├── attrs.js │ │ │ │ │ │ ├── class.js │ │ │ │ │ │ ├── compat.js │ │ │ │ │ │ ├── element.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ └── style.js │ │ │ │ └── weex │ │ │ │ │ ├── compiler.js │ │ │ │ │ ├── compiler │ │ │ │ │ ├── directives │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ └── model.js │ │ │ │ │ ├── index.js │ │ │ │ │ └── modules │ │ │ │ │ │ ├── append.js │ │ │ │ │ │ ├── class.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── props.js │ │ │ │ │ │ └── style.js │ │ │ │ │ ├── framework.js │ │ │ │ │ ├── runtime-factory.js │ │ │ │ │ ├── runtime │ │ │ │ │ ├── components │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── transition-group.js │ │ │ │ │ │ └── transition.js │ │ │ │ │ ├── directives │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── modules │ │ │ │ │ │ ├── attrs.js │ │ │ │ │ │ ├── class.js │ │ │ │ │ │ ├── events.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── style.js │ │ │ │ │ │ └── transition.js │ │ │ │ │ ├── node-ops.js │ │ │ │ │ ├── patch.js │ │ │ │ │ └── text-node.js │ │ │ │ │ └── util │ │ │ │ │ └── index.js │ │ │ ├── server │ │ │ │ ├── bundle-renderer │ │ │ │ │ ├── create-bundle-renderer.js │ │ │ │ │ ├── create-bundle-runner.js │ │ │ │ │ └── source-map-support.js │ │ │ │ ├── create-renderer.js │ │ │ │ ├── render-context.js │ │ │ │ ├── render-stream.js │ │ │ │ ├── render.js │ │ │ │ ├── template-renderer │ │ │ │ │ ├── create-async-file-mapper.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── parse-template.js │ │ │ │ │ └── template-stream.js │ │ │ │ ├── util.js │ │ │ │ ├── webpack-plugin │ │ │ │ │ ├── client.js │ │ │ │ │ ├── server.js │ │ │ │ │ └── util.js │ │ │ │ └── write.js │ │ │ ├── sfc │ │ │ │ └── parser.js │ │ │ └── shared │ │ │ │ ├── constants.js │ │ │ │ └── util.js │ │ └── vuex-src │ │ │ ├── helpers.js │ │ │ ├── index.esm.js │ │ │ ├── index.js │ │ │ ├── mixin.js │ │ │ ├── module │ │ │ ├── module-collection.js │ │ │ └── module.js │ │ │ ├── plugins │ │ │ ├── devtool.js │ │ │ └── logger.js │ │ │ ├── store.js │ │ │ └── util.js │ ├── vue源码分析系列1.md │ ├── vue源码分析系列2.md │ ├── vue源码分析系列3.md │ ├── vue源码分析系列4.md │ └── vue源码分析系列5.md └── 配置命令行.txt └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | .DS_Store 64 | 65 | config/* 66 | !config/default.* -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // 使用 IntelliSense 了解相关属性。 3 | // 悬停以查看现有属性的描述。 4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "启动程序", 11 | "program": "${workspaceFolder}/index.js" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.pythonPath": "/usr/local/opt/python/bin/python3.7", 3 | "python.linting.pylintEnabled": false 4 | } -------------------------------------------------------------------------------- /blog/vue3对比vue2.md: -------------------------------------------------------------------------------- 1 | 1. basic.js 2 | 2. setup.js 3 | -------------------------------------------------------------------------------- /blog/从0开始学架构.md: -------------------------------------------------------------------------------- 1 | # 从0开始学架构 2 | 3 | ## 架构到底是指什么? 4 | 5 | 对于技术人员来说,“架构”是一个再常见不过的词了。但如果深究一下“架构”到底指什么,大部分人也许并不一定能够准确地回答。例如: 6 | 7 | - 架构和框架是什么关系?有什么区别? 8 | - Linux 有架构,MySQL 有架构,JVM 也有架构,使用 Java 开发、MySQL 存储、跑在 Linux 上的业务系统也有架构,应该关注哪个架构呢? 9 | - 微信有架构,微信的登录系统也有架构,微信的支付系统也有架构,当我们谈微信架构时,到底是在谈什么架构? 10 | 11 | **系统与子系统** 12 | 13 | 子系统的定义和系统定义是一样的,只是观察的角度有差异,一个系统可能是另外一个更大系统的子系统。按照这个定义,系统和子系统比较容易理解。我们以微信为例来做一个分析。 14 | 15 | 1. 微信本身是一个系统,包含聊天、登录、支付、朋友圈等子系统。 16 | 2. 朋友圈这个系统又包括动态、评论、点赞等子系统。 17 | 3. 评论这个系统可能又包括防刷子系统、审核子系统、发布子系统、存储子系统。 18 | 4. 评论审核子系统不再包含业务意义上的子系统,而是包括各个模块或者组件,这些模块或者组件本身也是另外一个维度上的系统。例如,MySQL、Redis 等是存储系统,但不是业务子系统。 19 | 20 | **模块与组件** 21 | 22 | 模块和组件都是系统的组成部分,只是从不同的角度拆分系统而已。 23 | 24 | 从**逻辑的角度**来拆分系统后,得到的单元就是“模块”;从**物理的角度**来拆分系统后,得到的单元就是“组件”。划分模块的主要目的是职责分离;划分组件的主要目的是单元复用。 25 | 26 | > 架构是顶层设计;框架是面向编程或配置的半成品;组件是从技术维度上的复用;模块是从业务维度上职责的划分;系统是相互协同可运行的实体。 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Web-efficient-notes", 3 | "version": "1.0.0", 4 | "description": "Web高效编程阅读笔记整理", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/lsxlsxxslxsl/Web-efficient-notes.git" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/lsxlsxxslxsl/Web-efficient-notes/issues" 18 | }, 19 | "homepage": "https://github.com/lsxlsxxslxsl/Web-efficient-notes#readme", 20 | "dependencies": {}, 21 | "devDependencies": { 22 | "jasmine-core": "^3.1.0", 23 | "karma": "^2.0.5", 24 | "karma-chrome-launcher": "^2.2.0", 25 | "karma-coverage": "^1.1.2", 26 | "karma-jasmine": "^1.1.2" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /post/Javascript忍者秘籍2/02.运行时的页面构建过程.md: -------------------------------------------------------------------------------- 1 | # 02.运行时的页面构建过程 2 | 3 | - Web 应用的生命周期步骤 4 | - 从 HTML 代码到 Web 页面的处理过程 5 | - JavaScript 代码的执行顺序 6 | - 与事件交互 7 | - 事件循环 8 | 9 | ## 生命周期概览 10 | 11 | 典型客户端 Web 应用的生命周期从用户在浏览器地址栏输入一串 URL,或单击一 个链接开始。其过程如下: 12 | 13 | 1. 页面构建——创建用户界面; 14 | 2. 事件处理——进入循环从而等待事件的发生,发生后调用事件处理器。 15 | 3. 应用的生命周期随着用户关掉或离开页面而结束。 16 | 17 | ## 页面构建阶段 18 | 19 | 1. 解析 HTML 代码并构建文档对象模型 (DOM); 20 | 2. 执行 JavaScript 代码。 21 | 22 | ## 事件处理 23 | 24 | - 浏览器检查事件队列头; 25 | - 如果浏览器没有在队列中检测到事件,则继续检查; 26 | - 如果浏览器在队列头中检测到了事件,则取出该事件并执行相应的事件处理器(如果存在)。在这个过程中,余下的事件在事件队列中耐心等待,直到轮到它们被处理。 27 | 28 | ### 事件是异步的 29 | 30 | - 浏览器事件,例如当页面加载完成后或无法加载时; 31 | - 网络事件,例如来自服务器的响应(Ajax 事件和服务器端事件); 32 | - 用户事件,例如鼠标单击、鼠标移动和键盘事件; 33 | - 计时器事件,当 timeout 时间到期或又触发了一次时间间隔。 34 | 35 | ## 小结 36 | 37 | - 浏览器接收的 HTML 代码用作创建 DOM 的蓝图,它是客户端 Web 应用结构的 内部展示阶段。 38 | - 我们使用 JavaScript 代码来动态地修改 DOM 以便给 Web 应用带来动态行为。 39 | - 客户端 Web 应用的执行分为两个阶段。 40 | - 页面构建:用于创建DOM的,而全局JavaScript代码是遇到script节点时执行的。 41 | - 事件处理:在同一时刻,只能处理多个不同事件中的一个,处理顺序是事 件生成的顺序。事件处理阶段大量依赖事件队列,所有的事件都以其出现的 顺序存储在事件队列中。 -------------------------------------------------------------------------------- /post/Javascript忍者秘籍2/source/assert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test Suite 5 | 17 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /post/Javascript忍者秘籍2/source/match.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Reg 8 | 9 | 10 |
11 | 24 | 25 | -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/01.三种基础数据结构/README.md: -------------------------------------------------------------------------------- 1 | ## 三种基础数据结构 2 | 3 | - 栈 4 | - `push`:向数组末尾添加元素(进栈方法)。 5 | - 方法可以接收任意参数,并把它们逐个添加到数组末尾,并返回数组修改后的长度。 6 | - `pop`:弹出数据最末尾的一个元素(出栈方法)。 7 | - 方法会删除数组最末尾的一个元素,并返回。 8 | - 堆 9 | - 堆数据结构通常是一种树状结构。 10 | - 它的存取方式与在书架中取书的方式非常相似。书虽然整齐地摆放在书架上,但是只要知道书的名字,在书架中找到它之后就可以很方便地取出,我们甚至不用关心书的存放顺序,即不用像从乒乓球盒子中取乒乓球那样,必须将一些乒乓球拿出来之后才能取到中间的某一个乒乓球。 11 | - 队列 12 | - 队列(queue)是一种先进先出(FIFO)的数据结构。正如排队过安检一样,排在队伍前面的人一定是最先过安检的人。 -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/04.变量对象/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 04.变量对象 9 | 10 | 11 | 12 | 30 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/05.作用域与作用域链/README.md: -------------------------------------------------------------------------------- 1 | ## 作用域与作用域链 2 | 3 | 最常见的作用域有两种,分别是全局作用域与函数作用域。 4 | 5 | ### 全局作用域 6 | 7 | 全局作用域中声明的变量与函数可以在代码的任何地方被访问。 8 | 9 | 一般来说,以下三种情形拥有全局作用域。 10 | 11 | - 全局对象下拥有的属性与方法。 12 | - window.name 13 | - window.location 14 | - window.top 15 | - ... 16 | - 在最外层声明的变量与方法。 17 | - 在非严格模式下,函数作用域中未定义但直接复制的变量与方法。 18 | 19 | ### 函数作用域 20 | 21 | ```js 22 | var arr = [1, 2, 3, 4, 5]; 23 | for (var i = O; i < arr.length; i++) { 24 | console.log('do something by', i); 25 | } 26 | console.log(i); // i == 5 27 | ``` 28 | 29 | 因为没有块级作用域,因此单独的 `{}` 并不会产生新的作用域。这个时候 i 的值会被保留下来,在 for 循环结束后仍然能够访问。 30 | 31 | ### 模拟块级作用域 32 | 33 | ```js 34 | var arr = [1, 2, 3, 4, 5]; 35 | (function() { 36 | for (var i = O; i < arr.length; i++) { 37 | console.log('do something by', i); 38 | } 39 | })(); 40 | console.log(i); // i is not defined 41 | ``` 42 | 43 | 这种方式叫作**函数自执行**。 44 | 45 | 通过这种方式,我们就可以限定变量 i 值仅仅只在 for 循环中生效,而不会对其他代码造成干扰。 46 | 47 | 函数自执行时声明一个匿名函数并且立即执行,这种方式大体有如下几种写法: 48 | 49 | ```js 50 | (function() { ... })(); // 最常用 51 | +function() { ... }(); 52 | -function() { ... }(); 53 | !function() { ... }(); 54 | ~function() { ... }(); 55 | ``` 56 | 57 | ### 作用域链 58 | 59 | 作用域链(Scope Chain)是由当前执行环境与上层执行环境的一系列变量对象组成的,它保证了当前执行环境对符合访问权限的变量和函数的有序访问。 -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/06.闭包/src/demo1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/06.闭包/src/demo2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/06.闭包/src/demo3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/07.this/src/demo1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 30 | 31 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/08.函数与函数式编程/src/demo1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/09.面向对象/src/demo1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/09.面向对象/src/拖拽/drag.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 拖拽封装 9 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/09.面向对象/src/无缝滚动/scroll.js: -------------------------------------------------------------------------------- 1 | var lastTime = 0, 2 | nextFrame = window.requestAnimationFrame || 3 | window.webkitRequestAnimationFrame || 4 | window.mozRequesAnimationFrame || 5 | window.msRequestAnimationFrame || 6 | function(callback) { 7 | var currTime = +new Date, 8 | delay = Math.max(1000 / 60, 1000 / 60 - (currTime - lastTime)); 9 | lastTime = currTime + delay; 10 | return setTimeout(callback, delay); 11 | }, 12 | cancelFrame = window.cancelAnimationFrame || 13 | window.webkitCancelAnimationFrame || 14 | window.webkitCancelRequestAnimationFrame || 15 | window.mozCancelRequestAnimationFrame || 16 | window.msCancelRequestAnimationFrame || 17 | clearTimeout; 18 | 19 | var area = document.querySelector('#scroll_area'); 20 | var areaWidth = area.offsetWidth; 21 | 22 | var scrollBody = area.querySelector('.scroll_body'); 23 | var itemWidth = areaWidth/(scrollBody.children.length); 24 | 25 | scrollBody.style.width = areaWidth * 2 + 'px'; 26 | scrollBody.innerHTML = scrollBody.innerHTML + scrollBody.innerHTML; 27 | 28 | var targetPos = areaWidth; 29 | var scrollX = 0; 30 | var timer = null; 31 | 32 | function ani() { 33 | cancelFrame(timer); 34 | timer = nextFrame(function() { 35 | scrollX -= 1; 36 | 37 | if(-scrollX >= targetPos) { 38 | scrollX = 0; 39 | } 40 | 41 | scrollBody.style.left = scrollX + 'px'; 42 | ani(); 43 | }) 44 | } 45 | 46 | ani(); -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/09.面向对象/src/选项卡/tab.js: -------------------------------------------------------------------------------- 1 | var tabHeader = document.querySelector('.tab_options'); 2 | var items = tabHeader.children; 3 | var tabContent = document.querySelector('.tab_content'); 4 | var itemboxes = tabContent.children; 5 | var index = 0; 6 | 7 | tabHeader.addEventListener('click', function(e) { 8 | var a = [].slice.call(e.target.classList).indexOf('item'); 9 | if(a > -1 && index != e.target.dataset.index) { 10 | items[index].classList.remove('active'); 11 | itemboxes[index].classList.remove('active'); 12 | index = e.target.dataset.index; 13 | items[index].classList.add('active'); 14 | itemboxes[index].classList.add('active'); 15 | } 16 | }, false) -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/10.ES6 与模块化/src/es6app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | es6app 8 | 19 | 20 | 21 |
22 |
23 |
24 | 25 |
26 |
27 | 28 | 29 |
30 |
31 | 32 | 33 |
34 |
35 | width 36 | 37 | 38 |
39 |
40 | height 41 | 42 | 43 | 44 |
45 |
46 | 47 | -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/10.ES6 与模块化/src/es6app/src/box.js: -------------------------------------------------------------------------------- 1 | import { bind } from './state'; 2 | import { getStyle } from './utils'; 3 | import './register' 4 | 5 | const div = document.querySelector('.target'); 6 | 7 | // control show or hide 8 | bind('show', value => { 9 | if(value === 1) { 10 | div.classList.add('hide'); 11 | } 12 | if(value === 0) { 13 | div.classList.remove('hide'); 14 | } 15 | }) 16 | 17 | // change background color 18 | bind('backgroundColor', value => { 19 | div.style.backgroundColor = value; 20 | }) 21 | 22 | // change border color 23 | bind('borderColor', value => { 24 | const width = parseInt(getStyle(div, 'borderWidth')); 25 | if(width === 0) { 26 | div.style.border = '2px solid #ccc'; 27 | } 28 | div.style.borderColor = value; 29 | }) 30 | 31 | // change width 32 | bind('width', value => { 33 | div.style.width = `${value}px`; 34 | }) 35 | 36 | bind('height', value => { 37 | div.style.height = `${value}px`; 38 | }) -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/10.ES6 与模块化/src/es6app/src/controlBtns/bdColor.js: -------------------------------------------------------------------------------- 1 | import { setState } from '../state'; 2 | 3 | const input = document.querySelector('.bdcolor_input'); 4 | const btn = document.querySelector('.bdcolor_btn'); 5 | 6 | btn.addEventListener('click', () => { 7 | if(input.value) { 8 | setState('borderColor', input.value); 9 | } 10 | }, false); -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/10.ES6 与模块化/src/es6app/src/controlBtns/bgColor.js: -------------------------------------------------------------------------------- 1 | import { setState } from '../state'; 2 | 3 | const input = document.querySelector('.bgcolor_input'); 4 | const btn = document.querySelector('.bgcolor_btn'); 5 | 6 | btn.addEventListener('click', () => { 7 | if(input.value) { 8 | setState('backgroundColor', input.value); 9 | } 10 | }, false); -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/10.ES6 与模块化/src/es6app/src/controlBtns/height.js: -------------------------------------------------------------------------------- 1 | import { getState, setState } from '../state'; 2 | 3 | const reduce_btn = document.querySelector('.height_reduce'); 4 | const add_btn = document.querySelector('.height_add'); 5 | const height_input = document.querySelector('.height_input'); 6 | 7 | height_input.value = getState('height') || 100; 8 | 9 | reduce_btn.addEventListener('click', () => { 10 | const cur = getState('height'); 11 | if(cur > 50) { 12 | setState('height', cur - 5); 13 | height_input.value = cur - 5; 14 | } 15 | }, false); 16 | 17 | add_btn.addEventListener('click', () => { 18 | const cur = getState('height'); 19 | if(cur < 400) { 20 | setState('height', cur + 5); 21 | height_input.value = cur + 5; 22 | } 23 | }, false); -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/10.ES6 与模块化/src/es6app/src/controlBtns/index.js: -------------------------------------------------------------------------------- 1 | import './showBtn'; 2 | import './bgColor'; 3 | import './bdColor'; 4 | import './width'; 5 | import './height'; -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/10.ES6 与模块化/src/es6app/src/controlBtns/showBtn.js: -------------------------------------------------------------------------------- 1 | import { getState, setState } from '../state'; 2 | 3 | const btn = document.querySelector('.show'); 4 | 5 | btn.addEventListener('click', () => { 6 | if(getState('show') == 0) { 7 | setState('show', 1); 8 | } else { 9 | setState('show', 0); 10 | } 11 | }, false); -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/10.ES6 与模块化/src/es6app/src/controlBtns/width.js: -------------------------------------------------------------------------------- 1 | import { getState, setState } from '../state'; 2 | 3 | const reduce_btn = document.querySelector('.width_reduce'); 4 | const add_btn = document.querySelector('.width_add'); 5 | 6 | reduce_btn.addEventListener('click', () => { 7 | const cur = getState('width'); 8 | if(cur > 50) { 9 | setState('width', cur - 5); 10 | } 11 | }, false); 12 | 13 | add_btn.addEventListener('click', () => { 14 | const cur = getState('width'); 15 | if(cur < 400) { 16 | setState('width', cur + 5); 17 | } 18 | }, false); -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/10.ES6 与模块化/src/es6app/src/index.js: -------------------------------------------------------------------------------- 1 | import './controlBtns'; 2 | import './box'; 3 | 4 | import './index.css'; -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/10.ES6 与模块化/src/es6app/src/register.js: -------------------------------------------------------------------------------- 1 | import { registerState } from './state'; 2 | 3 | // 控制显示隐藏 4 | registerState('show', 0); 5 | registerState('backgroundColor', '#FFF'); 6 | registerState('borderColor', '#000'); 7 | registerState('width', 100); 8 | registerState('height', 100); 9 | // ... and more -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/10.ES6 与模块化/src/es6app/src/state.js: -------------------------------------------------------------------------------- 1 | const store = {} 2 | const events = {} 3 | 4 | // 往store中添加一个状态值,并确保传入一个初始值 5 | export const registerState = (status, value) => { 6 | if(store[status]) { 7 | throw new Error('状态已经存在。'); 8 | return; 9 | } 10 | store[status] = value; 11 | return value; 12 | } 13 | 14 | // 获取整个状态树 15 | export const getStore = () => store 16 | 17 | // 获取某个状态的位 18 | export const getState = status => store[status] 19 | 20 | // 设置某个状态的值 21 | export const setState = (status, value) => { 22 | store[status] = value; 23 | dispatch(status, value); 24 | return value; 25 | } 26 | 27 | // 将状态值与事件绑定在一起,通过 status-events 的形式保存在 events 对象中 28 | export const bind = (status, eventFn) => { 29 | events[status] = eventFn; 30 | } 31 | 32 | // 移除绑定 33 | export const remove = status => { 34 | events[status] = null; 35 | return status; 36 | } 37 | 38 | // 需要在状态值改变时触发UI的变化,因此在 setState 方法中调用了该方法 39 | export const dispatch = (status, value) => { 40 | if(!events[status]) { 41 | throw new Error('未绑定任何事件!'); 42 | } 43 | events[status](value); 44 | return value; 45 | } -------------------------------------------------------------------------------- /post/Javascript核心技术开发解密/10.ES6 与模块化/src/es6app/src/utils.js: -------------------------------------------------------------------------------- 1 | // 获取DOM元素属性值 2 | export const getStyle = (obj, key) => { 3 | return obj.currentStyle ? obj.currentStyle[key] : document.defaultView.getComputedStyle(obj, false)[key]; 4 | } -------------------------------------------------------------------------------- /post/Javascript高级程序设计/README.md: -------------------------------------------------------------------------------- 1 | # Javascript高级程序设计笔记整理 2 | 3 | - [x] [高程 4-6 章](https://github.com/lsxlsxxslxsl/Read-Books-Notes/tree/master/post/Javascript%E9%AB%98%E7%BA%A7%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/4-6) 4 | - [x] [高程 7-10 章](https://github.com/lsxlsxxslxsl/Read-Books-Notes/tree/master/post/Javascript%E9%AB%98%E7%BA%A7%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/7-10) 5 | - [x] [高程 13-14 章](https://github.com/lsxlsxxslxsl/Read-Books-Notes/tree/master/post/Javascript%E9%AB%98%E7%BA%A7%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/13-14) 6 | - [x] [高程 15-20 章](https://github.com/lsxlsxxslxsl/Read-Books-Notes/tree/master/post/Javascript%E9%AB%98%E7%BA%A7%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/15-20) 7 | - [x] [高程 21-25 章](https://github.com/lsxlsxxslxsl/Read-Books-Notes/tree/master/post/Javascript%E9%AB%98%E7%BA%A7%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/21-25) 8 | -------------------------------------------------------------------------------- /post/Nodejs微服务/source/index.js: -------------------------------------------------------------------------------- 1 | var seneca = require('seneca')(); 2 | 3 | seneca.add({ role: 'math', cmd: 'sum' }, function(msg, respond) { 4 | var sum = msg.left + msg.right; 5 | respond(null, { answer: sum }); 6 | }); 7 | 8 | seneca.add({ role: 'math', cmd: 'product' }, function(msg, respond) { 9 | var product = msg.left * msg.right; 10 | respond(null, { answer: product }); 11 | }); 12 | 13 | // seneca.act({ role: 'math', cmd: 'sum', left: 1, right: 2 }, console.log); 14 | seneca.act({role: 'math', cmd: 'sum', left: 1, right: 2}, 15 | function(err, data) { 16 | if (err) { 17 | return console.error(err); 18 | } 19 | console.log(data); 20 | } 21 | ); 22 | // seneca.act({ role: 'math', cmd: 'product', left: 3, right: 4 }, console.log); 23 | seneca.act({role: 'math', cmd: 'product', left: 3, right: 4}, 24 | function(err, data) { 25 | if (err) { 26 | return console.error(err); 27 | } 28 | console.log(data); 29 | } 30 | ); -------------------------------------------------------------------------------- /post/Nodejs微服务/source/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "source", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "express": "^4.16.3", 14 | "seneca": "^3.7.0" 15 | }, 16 | "devDependencies": { 17 | "html-webpack-plugin": "^3.2.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /post/Nodejs微服务/source/report/email.js: -------------------------------------------------------------------------------- 1 | module.exports = function (options) { 2 | /** 3 | * 发送邮件 4 | */ 5 | this.add({channel: 'email', action: 'send'}, function(msg, respond) { 6 | // 发送邮件代码实现 7 | respond(null, {}); 8 | }); 9 | 10 | /** 11 | * 获取未读邮件列表 12 | */ 13 | this.add({channel: 'email', action: 'pending'}, function(msg, respond) { 14 | // 读取未读邮件代码实现 15 | respond(null, {}); 16 | }); 17 | 18 | /** 19 | * 将信息标记为已读 20 | */ 21 | this.add({channel: 'email', action: 'read'}, function(msg, respond) { 22 | // 标记信息为已读代码实现 23 | respond(null, {}); 24 | }); 25 | } -------------------------------------------------------------------------------- /post/Nodejs微服务/source/report/index.js: -------------------------------------------------------------------------------- 1 | var seneca = require('seneca')() 2 | .use('email') 3 | .use('sms') 4 | .use('post'); 5 | 6 | seneca.listen({ port: 1932, host: '127.0.0.1' }); -------------------------------------------------------------------------------- /post/Nodejs微服务/source/report/post.js: -------------------------------------------------------------------------------- 1 | module.exports = function (options) { 2 | /** 3 | * 将待打印、邮寄的信息放入队列 4 | */ 5 | this.add({channel: 'post', action: 'queue'}, function(msg, respond) { 6 | // 邮寄信息放入队列代码实现 7 | respond(null, {}); 8 | }); 9 | } -------------------------------------------------------------------------------- /post/Nodejs微服务/source/report/sms.js: -------------------------------------------------------------------------------- 1 | module.exports = function (options) { 2 | /** 3 | * 发送短信 4 | */ 5 | this.add({channel: 'sms', action: 'send'}, function(msg, respond) { 6 | // 发送短信代码实现 7 | respond(null, {}); 8 | }); 9 | 10 | /** 11 | * 获取未读短信 12 | */ 13 | this.add({channel: 'sms', action: 'pending'}, function(msg, respond) { 14 | // 读取未读短信代码实现 15 | respond(null, {}); 16 | }); 17 | } -------------------------------------------------------------------------------- /post/Nodejs微服务/source/seneca/demo.js: -------------------------------------------------------------------------------- 1 | var seneca = require('seneca')(); 2 | 3 | seneca.add({cmd: 'wordcount'}, function(msg, respond) { 4 | var length = msg.phrase.split(' ').length; 5 | respond(null, {words: length}); 6 | }); 7 | 8 | seneca.act({cmd: 'wordcount', phrase: 'Hello world this is Seneca'}, function(err, response) { 9 | console.log(response); 10 | }); -------------------------------------------------------------------------------- /post/Nodejs微服务/source/seneca/minimal-plugin.js: -------------------------------------------------------------------------------- 1 | function init(msg, respond) { 2 | console.log("plugin initialized!"); 3 | console.log("expensive operation taking place now... DONE!"); 4 | respond(); 5 | } 6 | 7 | function math( options ) { 8 | this.add({role:'math', cmd: 'sum'}, function( msg, respond ) { 9 | respond( null, { answer: msg.left + msg.right } ) 10 | }) 11 | this.add({role:'math', cmd: 'product'}, function( msg, respond ) { 12 | respond( null, { answer: msg.left * msg.right } ) 13 | }) 14 | this.add({init: "math"}, init); 15 | } 16 | require('seneca')().use(math).act('role:math,cmd:sum,left:1,right:2', console.log) -------------------------------------------------------------------------------- /post/Nodejs微服务/source/seneca/plugin.js: -------------------------------------------------------------------------------- 1 | module.exports = function(options) { 2 | this.add({role: 'employee', cmd: 'add'}, function(msg, respond){ 3 | this.make('employee').data$(msg.data).save$(respond); 4 | }); 5 | 6 | this.find({role: 'employee', cmd: 'get'}, function(msg, respond){ 7 | this.make('employee').load$(msg.id, respond); 8 | }); 9 | } 10 | 11 | var seneca = require('seneca')().use('employees-storage') 12 | var employee = { 13 | name: "David", 14 | surname: "Gonzalez", 15 | position: "Software Developer" 16 | } 17 | 18 | function add_employee() { 19 | seneca.act({role: 'employee', cmd: 'add', data: employee}, 20 | function (err, msg) { 21 | console.log(msg); 22 | } 23 | ); 24 | } 25 | add_employee(); -------------------------------------------------------------------------------- /post/Nodejs微服务/source/seneca/sum.js: -------------------------------------------------------------------------------- 1 | var seneca = require( 'seneca' )() 2 | 3 | seneca.add({role: 'math', cmd: 'sum'}, function (msg, respond) { 4 | var sum = msg.left + msg.right 5 | respond(null, {answer: sum}) 6 | }); 7 | 8 | seneca.add({role: 'math', cmd: 'sum', integer: true}, function (msg, respond) { 9 | this.act({ 10 | role: 'math', 11 | cmd: 'sum', 12 | left: Math.floor(msg.left), 13 | right: Math.floor(msg.right)}, 14 | respond 15 | ); 16 | }); 17 | 18 | seneca.act({role: 'math', cmd: 'sum', left: 1.5, right: 2.5}, console.log) 19 | 20 | seneca.act({role: 'math', cmd: 'sum', left: 1.5, right: 2.5, integer: true}, console.log) -------------------------------------------------------------------------------- /post/Nodejs微服务/source/seneca/web.js: -------------------------------------------------------------------------------- 1 | var seneca = require('seneca')(); 2 | 3 | seneca.add('role:api,cmd:bazinga', function(args, done) { 4 | done(null, { bar: 'Bazinga!' }); 5 | }); 6 | seneca.act('role:web', { 7 | use: { 8 | prefix: '/my-api', 9 | pin: { role: 'api', cmd: '*' }, 10 | map: { 11 | bazinga: { GET: true } 12 | } 13 | } 14 | }); 15 | var express = require('express'); 16 | var app = express(); 17 | app.use(seneca.export('web')); 18 | app.listen(3000); -------------------------------------------------------------------------------- /post/Nodejs微服务/source/seneca/word.js: -------------------------------------------------------------------------------- 1 | var seneca = require('seneca')(); 2 | 3 | seneca.add({cmd: 'wordcount'}, function(msg, respond) { 4 | var length = msg.phrase.split(' ').length; 5 | respond(null, {words: length}); 6 | }); 7 | 8 | seneca.add({cmd: 'wordcount', skipShort: true}, function(msg, respond) { 9 | var words = msg.phrase.split(' '); 10 | var validWords = 0; 11 | for (var i = 0; i < words.length; i++) { 12 | if (words[i].length > 3) { 13 | validWords++; 14 | } 15 | } 16 | respond(null, {words: validWords}); 17 | }); 18 | 19 | seneca.act({cmd: 'wordcount', phrase: 'Hello world this is Seneca'}, function(err, response) { 20 | console.log(response); 21 | }); 22 | 23 | seneca.act({cmd: 'wordcount', skipShort: true, phrase: 'Hello world this is Seneca'}, function(err, response) { 24 | console.log(response); 25 | }); -------------------------------------------------------------------------------- /post/Python学习笔记/source/Requests.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | import requests 4 | 5 | 6 | class SimpleCrawler: 7 | init_url = "https://zhuanlan.zhihu.com/api/columns/pythoneer/followers" 8 | offset = 0 9 | 10 | def crawl(self, params=None): 11 | # 必须指定UA,否则知乎服务器会判定请求不合法 12 | headers = { 13 | "Host": "zhuanlan.zhihu.com", 14 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " 15 | "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36", 16 | } 17 | response = requests.get(self.init_url, headers=headers, params=params) 18 | print(response.url) 19 | data = response.json() 20 | # 7000表示所有关注量 21 | # 分页加载更多,递归调用 22 | while self.offset < 7000: 23 | self.parse(data) 24 | self.offset += 20 25 | params = {"limit": 20, "offset": self.offset} 26 | self.crawl(params) 27 | 28 | def parse(self, data): 29 | # 以json格式存储到文件 30 | with open("followers.json", "a", encoding="utf-8") as f: 31 | for item in data: 32 | f.write(json.dumps(item)) 33 | f.write('\n') 34 | 35 | 36 | if __name__ == '__main__': 37 | SimpleCrawler().crawl() -------------------------------------------------------------------------------- /post/Python学习笔记/source/hello.py: -------------------------------------------------------------------------------- 1 | s = requests.Session() 2 | s.cookies = requests.utils.cookiejar_from_dict({"a": "c"}) 3 | r = s.get('http://httpbin.org/cookies') 4 | print(r.text) -------------------------------------------------------------------------------- /post/js基础/1.js基础知识(上).html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 基础知识 6 | 7 | 8 | 14 | 40 | 41 | -------------------------------------------------------------------------------- /post/js基础/1.js基础知识(中).html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 基础知识 6 | 7 | 8 | 41 | 71 | 72 | -------------------------------------------------------------------------------- /post/js基础/2.JS-Web-API(上).html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 基础知识 6 | 7 | 8 | 23 | 40 | 43 | 44 | -------------------------------------------------------------------------------- /post/js基础/3.开发环境.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 开发环境 6 | 7 | 8 | 45 | 46 | 47 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /post/js基础/4.运行环境.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 运行环境 6 | 7 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /post/js基础/AMD/a-util.js: -------------------------------------------------------------------------------- 1 | // define(['./util.js'], function(util) { 2 | // var aUtil = { 3 | // aGetFormatDate: function(date) { 4 | // return util.getFormatDate(date, 2) 5 | // } 6 | // } 7 | // return aUtil 8 | // }) 9 | define(function() { 10 | return { 11 | aGetFormatDate: function() { 12 | return '2047' 13 | } 14 | } 15 | }) -------------------------------------------------------------------------------- /post/js基础/AMD/a.js: -------------------------------------------------------------------------------- 1 | define(['./a-util.js'], function(aUtil) { 2 | var a = { 3 | printDate: function(date) { 4 | console.log(aUtil.aGetFormatDate(date)) 5 | } 6 | } 7 | return a 8 | }) -------------------------------------------------------------------------------- /post/js基础/AMD/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | require.js 6 | 7 | 8 |

AMD test

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /post/js基础/AMD/main.js: -------------------------------------------------------------------------------- 1 | require(['./a.js'], function(a) { 2 | var date = new Date() 3 | a.printDate(date) 4 | }) -------------------------------------------------------------------------------- /post/js基础/AMD/util.js: -------------------------------------------------------------------------------- 1 | define(function() { 2 | var util = { 3 | getFormatDate: function(date, type) { 4 | if (type === 1) { 5 | return '2017-06-20' 6 | } 7 | if (type === 2) { 8 | return '2017年6月20日' 9 | } 10 | } 11 | } 12 | return util 13 | }) -------------------------------------------------------------------------------- /post/js基础/CMD/dist/bundle.js: -------------------------------------------------------------------------------- 1 | !function(n){function t(e){if(r[e])return r[e].exports;var o=r[e]={i:e,l:!1,exports:{}};return n[e].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var r={};t.m=n,t.c=r,t.d=function(n,r,e){t.o(n,r)||Object.defineProperty(n,r,{configurable:!1,enumerable:!0,get:e})},t.n=function(n){var r=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(r,"a",r),r},t.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},t.p="",t(t.s=0)}([function(n,t,r){r(1).print()},function(n,t){n.exports={print:function(){console.log(123)}}}]); -------------------------------------------------------------------------------- /post/js基础/CMD/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Common.js 6 | 7 | 8 |

CMD test

9 |
123
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /post/js基础/CMD/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-test", 3 | "version": "1.0.0", 4 | "description": "webpack test", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "webpack" 9 | }, 10 | "author": "liusixin", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "webpack": "^3.0.0" 14 | }, 15 | "dependencies": { 16 | "jquery": "^3.5.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /post/js基础/CMD/src/a-util.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | print: function() { 3 | console.log(123) 4 | } 5 | } -------------------------------------------------------------------------------- /post/js基础/CMD/src/app.js: -------------------------------------------------------------------------------- 1 | // var $ = require('jquery') 2 | 3 | // var $root = $('#root') 4 | // $root.html('

这是jquery插入的文字

') 5 | 6 | var aUtil = require('./a-util.js') 7 | aUtil.print() -------------------------------------------------------------------------------- /post/js基础/CMD/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | 4 | module.exports = { 5 | context: path.resolve(__dirname, './src'), 6 | entry: { 7 | app: './app.js' 8 | }, 9 | output: { 10 | path: path.resolve(__dirname, './dist'), 11 | filename: 'bundle.js' 12 | }, 13 | plugins: [ 14 | new webpack.optimize.UglifyJsPlugin() 15 | ] 16 | } -------------------------------------------------------------------------------- /post/js基础/JS-Web-API(上).md: -------------------------------------------------------------------------------- 1 | JS-Web-API(上) 2 | 3 | ·JS基础知识:ECMA262标准 4 | ·JS-Web-API:W3C标准 5 | 关于JS的规定: 6 | ·DOM操作 7 | ·BOM操作 8 | ·事件绑定 9 | ·ajax请求(包括http协议) 10 | ·存储 11 | 12 | ###DOM操作: 13 | Document 14 | Object 15 | Model 16 | ·题目 17 | ·DOM是哪种基本的数据结构 18 | ·DOM操作的常用API有哪些 19 | ·DOM节点的attr和property有何区别 20 | ·知识点 21 | ·DOM本质 22 | 23 | 24 | ·DOM节点操作 25 | ·获取DOM节点 26 | ·prototype 27 | 获取样式dom.style.width 28 | 获取nodeName和nodeType 29 | ·Attribute 30 | 获取属性getAttribute,setAttribute 31 | ·DOM结构操作 32 | ·新增节点 33 | ·获取父节点 34 | ·获取子元素 35 | ·删除节点 36 | ·解答 37 | ·DOM是哪种基本的数据结构? 38 | ·树 39 | ·DOM操作的常用API有哪些? 40 | ·获取DOM节点,以及节点的property和Attribute 41 | ·获取父节点,获取子节点 42 | ·新增节点,删除节点 43 | ·DOM节点的attr和property有何区别? 44 | ·property只是一个JS对象的属性的修改 45 | ·Attribute是对html标签属性的修改 46 | 47 | ###BOM操作 48 | ·题目: 49 | ·如何检测浏览器的类型 50 | ·拆解url各部分 51 | ·知识点: 52 | ·navigator 53 | ·screen 54 | ·location 55 | ·history 56 | ·解答: 57 | ·如何检测浏览器的类型? 58 | var ua = navigator.userAgent 59 | var isChrome = ua.indexOf('Chrome') -------------------------------------------------------------------------------- /post/js基础/原型对象.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/js基础/原型对象.png -------------------------------------------------------------------------------- /post/js基础/开发环境.md: -------------------------------------------------------------------------------- 1 | 开发环境 2 | 3 | ###关于开发环境 4 | ·IDE 5 | ·git 6 | ·js模块化 7 | ·打包工具 8 | ·上线回滚的流程 9 | 10 | ###Git 11 | 国内coding.net 12 | ·常用git命令 13 | ·git add 14 | ·git checkout xxx 15 | ·git commit -m "xxx" 16 | ·git push origin master //提交远程仓库 17 | ·git pull origin master 18 | ·多人 19 | ·git branch 20 | ·git checkout -b xxx/git checkout xxx //新建分支/切换分支 21 | ·git merge xxx 22 | 23 | ###模块化 24 | ·AMD 25 | ·require.js 26 | ·全局define函数 27 | ·全局require函数 28 | ·依赖js会自动、异步加载 29 | ·CommonJs(CMD) 30 | ·nodejs模块化规范,现在被大量用前端,原因: 31 | ·前端开发依赖的插件和库,都可以从npm中获取 32 | ·构建工具的高度自动化,使得使用npm的成本非常低 33 | ·commonjs不会异步加载js,而是同步一次性加载出来 34 | ·AMD和CommonJs(CMD)的使用场景 35 | ·需要异步加载js,使用AMD 36 | ·使用了npm之后建议使用CommonJs 37 | ·重点总结 38 | ·AMD 39 | ·CommonJs 40 | ·两者的区别 41 | 42 | ·上线和回滚 43 | ·上线和回滚的基本流程 44 | ·上线回滚流程介绍 45 | ·是非常重要的开发环节 46 | ·各个公司的具体流程不同 47 | ·由专门的工具者系统完成,我们无需关心细节 48 | ·如果你没有参与过,面试时也要说出要点 49 | ·只讲要点,具体实现无法讲解 50 | ·上线流程要点 51 | ·将测试完成的代码提交到git版本库的master分支 52 | ·将当前服务器的代码全部打包并记录版本号,备份 53 | ·将master分支的代码提交覆盖到线上服务器,生成新版本号 54 | ·回滚流程要点 55 | ·将当前服务器的代码全部打包并记录版本号,备份 56 | ·将备份的上一个版本号解压,覆盖到线上服务器,并生成新的版本号 57 | ·linux基本命令 58 | ·服务器使用linux居多,server版,只有命令行 59 | ·测试环境要匹配线上环境,因此也是linux 60 | ·经常需要登录测试机来自己配置,获取数据 -------------------------------------------------------------------------------- /post/js高级面试/code/async/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "a": 100, 3 | "b": 200 4 | } -------------------------------------------------------------------------------- /post/js高级面试/code/async/deferred.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 |

deferred test

9 | 10 | 11 | 50 | 51 | -------------------------------------------------------------------------------- /post/js高级面试/code/es6/class/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test 6 | 7 | 8 |

构造函数测试

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /post/js高级面试/code/es6/class/index.js: -------------------------------------------------------------------------------- 1 | // function MathHandle(x, y) { 2 | // this.x = x 3 | // this.y = y 4 | // } 5 | 6 | // MathHandle.prototype.add = function () { 7 | // return this.x + this.y 8 | // } 9 | 10 | // var m = new MathHandle(1, 2) 11 | // // console.log(m.add()) 12 | 13 | // typeof MathHandle // 'function' 14 | // MathHandle.prototype.constructor === MathHandle // true 15 | // m.__proto__ === MathHandle.prototype // true 16 | 17 | // // 动物 18 | // function Animal() { 19 | // this.eat = function () { 20 | // alert('Animal eat') 21 | // } 22 | // } 23 | 24 | // // 狗 25 | // function Dog() { 26 | // this.bark = function () { 27 | // alert('Dog bark') 28 | // } 29 | // } 30 | 31 | // // 绑定原型,实现继承 32 | // Dog.prototype = new Animal() 33 | 34 | // var hashiqi = new Dog() 35 | // hashiqi.bark() 36 | // hashiqi.eat() 37 | 38 | function fn() { 39 | console.log('real', this) // real {a: 100} 40 | 41 | var arr = [1, 2, 3] 42 | arr.map(function (item) { 43 | console.log(this) // window 44 | }) 45 | } 46 | fn.call({a: 100}) 47 | 48 | // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} 49 | // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} 50 | // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /post/js高级面试/code/es6/rollup/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["latest", { 4 | "es2015": { 5 | "modules": false 6 | } 7 | }] 8 | ], 9 | "plugins": ["external-helpers", "babel-plugin-transform-regenerator"] 10 | } -------------------------------------------------------------------------------- /post/js高级面试/code/es6/rollup/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 |

test

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /post/js高级面试/code/es6/rollup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rollup-wfp", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "rollup -c rollup.config.js" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "babel-core": "^6.26.0", 13 | "babel-plugin-external-helpers": "^6.22.0", 14 | "babel-plugin-syntax-async-functions": "^6.13.0", 15 | "babel-plugin-transform-runtime": "^6.23.0", 16 | "babel-polyfill": "^6.26.0", 17 | "babel-preset-latest": "^6.24.1", 18 | "babel-runtime": "^6.26.0", 19 | "rollup": "^0.52.3", 20 | "rollup-plugin-babel": "^3.0.3", 21 | "rollup-plugin-node-resolve": "^3.0.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /post/js高级面试/code/es6/rollup/rollup.config.js: -------------------------------------------------------------------------------- 1 | import babel from 'rollup-plugin-babel' 2 | import resolve from 'rollup-plugin-node-resolve' 3 | 4 | export default { 5 | entry: 'src/index.js', 6 | format: 'umd', 7 | plugins: [ 8 | resolve(), 9 | babel({ 10 | exclude: 'node_modules/**' 11 | }) 12 | ], 13 | dest: 'build/bundle.js' 14 | } -------------------------------------------------------------------------------- /post/js高级面试/code/es6/rollup/src/index-1.js: -------------------------------------------------------------------------------- 1 | // ES6 其他常用功能 2 | 3 | // var arr = [1, 2, 3]; 4 | // arr.map(function (item) { 5 | // return item + 1; 6 | // }) 7 | 8 | const arr = [1, 2, 3]; 9 | arr.map(item => item + 1); 10 | arr.map((item, index) => { 11 | console.log(item); 12 | return item + 1; 13 | }); -------------------------------------------------------------------------------- /post/js高级面试/code/es6/rollup/src/util1.js: -------------------------------------------------------------------------------- 1 | export default { 2 | a: 100 3 | } -------------------------------------------------------------------------------- /post/js高级面试/code/es6/rollup/src/util2.js: -------------------------------------------------------------------------------- 1 | export function fn1() { 2 | alert('fn1') 3 | } 4 | export function fn2() { 5 | alert('fn2') 6 | } -------------------------------------------------------------------------------- /post/js高级面试/code/es6/webpack-wfp/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "latest"], 3 | "plugins": [] 4 | } -------------------------------------------------------------------------------- /post/js高级面试/code/es6/webpack-wfp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 |

test

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /post/js高级面试/code/es6/webpack-wfp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-wfp", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "babel-core": "^6.26.0", 14 | "babel-loader": "^7.1.2", 15 | "babel-preset-es2015": "^6.24.1", 16 | "babel-preset-latest": "^6.24.1", 17 | "webpack": "^3.11.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /post/js高级面试/code/es6/webpack-wfp/src/index.js: -------------------------------------------------------------------------------- 1 | import util1 from './util1.js' 2 | import { fn1, fn2 } from './util2.js' 3 | 4 | console.log(util1) 5 | fn1() 6 | fn2() 7 | 8 | // [1, 2, 3].map(item => item + 1) 9 | -------------------------------------------------------------------------------- /post/js高级面试/code/es6/webpack-wfp/src/util1.js: -------------------------------------------------------------------------------- 1 | export default { 2 | a: 100 3 | } -------------------------------------------------------------------------------- /post/js高级面试/code/es6/webpack-wfp/src/util2.js: -------------------------------------------------------------------------------- 1 | export function fn1() { 2 | alert('fn1') 3 | } 4 | 5 | export function fn2() { 6 | alert('fn2') 7 | } -------------------------------------------------------------------------------- /post/js高级面试/code/es6/webpack-wfp/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: './src/index.js', 3 | output: { 4 | path: __dirname, 5 | filename: './build/bundle.js' 6 | }, 7 | module: { 8 | rules: [{ 9 | test: /\.js?$/, 10 | exclude: /(node_modules)/, 11 | loader: 'babel-loader' 12 | }] 13 | } 14 | } -------------------------------------------------------------------------------- /post/js高级面试/code/es6/webpack/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "latest"], 3 | "plugins": [] 4 | } -------------------------------------------------------------------------------- /post/js高级面试/code/es6/webpack/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |

webpack test

10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /post/js高级面试/code/es6/webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-wfp", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "babel-core": "^6.26.0", 13 | "babel-loader": "^7.1.2", 14 | "babel-polyfill": "^6.26.0", 15 | "babel-preset-es2015": "^6.24.1", 16 | "babel-preset-latest": "^6.24.1", 17 | "webpack": "^3.10.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /post/js高级面试/code/es6/webpack/src/index.js: -------------------------------------------------------------------------------- 1 | // import util1 from './util1.js' 2 | // import { fn1, fn2 } from './util2.js' 3 | 4 | // console.log(util1) 5 | // fn1() 6 | // fn2() 7 | 8 | // // [1, 2, 3].map(item => item + 1) 9 | 10 | import 'babel-polyfill' 11 | 12 | function loadImg(src) { 13 | var promise = new Promise(function (resolve, reject) { 14 | var img = document.createElement('img') 15 | img.onload = function () { 16 | resolve(img) 17 | } 18 | img.onerror = function () { 19 | reject('图片加载失败') 20 | } 21 | img.src = src 22 | }) 23 | return promise 24 | } 25 | 26 | var src1 = 'https://www.imooc.com/static/img/index/logo_new.png' 27 | var src2 = 'https://img1.mukewang.com/545862fe00017c2602200220-100-100.jpg' 28 | 29 | const load = async function () { 30 | const result1 = await loadImg(src1) 31 | console.log(result1) 32 | const result2 = await loadImg(src2) 33 | console.log(result2) 34 | } 35 | load() 36 | 37 | -------------------------------------------------------------------------------- /post/js高级面试/code/es6/webpack/src/util1.js: -------------------------------------------------------------------------------- 1 | export default { 2 | a: 100 3 | } -------------------------------------------------------------------------------- /post/js高级面试/code/es6/webpack/src/util2.js: -------------------------------------------------------------------------------- 1 | export function fn1() { 2 | alert('fn1') 3 | } 4 | export function fn2() { 5 | alert('fn2') 6 | } -------------------------------------------------------------------------------- /post/js高级面试/code/es6/webpack/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: './src/index.js', 3 | output: { 4 | path: __dirname, 5 | filename: './build/bundle.js' 6 | }, 7 | module: { 8 | rules: [{ 9 | test: /\.js?$/, 10 | exclude: /(node_modules)/, 11 | loader: 'babel-loader' 12 | }] 13 | } 14 | } -------------------------------------------------------------------------------- /post/js高级面试/code/framework/jsx-test/.babelrc: -------------------------------------------------------------------------------- 1 | {"plugins": ["transform-react-jsx"]} -------------------------------------------------------------------------------- /post/js高级面试/code/framework/jsx-test/demo.jsx: -------------------------------------------------------------------------------- 1 | // import Input from './input/index.js' 2 | // import List from './list/index.js' 3 | 4 | // function render() { 5 | // return ( 6 | //
7 | //

this is demo

8 | // 9 | // 10 | //
11 | // ) 12 | // } 13 | 14 | // var profile =
15 | // 16 | //

{[user.firstName, user.lastName].join(' ')}

17 | //
; 18 | 19 | // class Input extends Component { 20 | // render() { 21 | // return ( 22 | //
23 | // 24 | // 25 | //
26 | // ); 27 | // } 28 | // } -------------------------------------------------------------------------------- /post/js高级面试/code/framework/jsx-test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jsx-test", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "babel-plugin-transform-react-jsx": "^6.24.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /post/js高级面试/code/framework/jsx-test/test.jsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /post/js高级面试/code/framework/mvvm/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 | 9 |
10 |

{{price}}

11 |
12 | 13 | 49 | 50 | -------------------------------------------------------------------------------- /post/js高级面试/code/framework/mvvm/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 |

test

9 | 10 | 35 | 36 | -------------------------------------------------------------------------------- /post/js高级面试/code/framework/to-do-list/jquery/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | to-do-list by jquery 6 | 7 | 8 |
9 | 10 | 11 |
12 |
13 | 14 |
15 | 16 | 17 | 31 | 32 | -------------------------------------------------------------------------------- /post/js高级面试/code/framework/to-do-list/react-test/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /post/js高级面试/code/framework/to-do-list/react-test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-test", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "react": "^16.2.0", 7 | "react-dom": "^16.2.0", 8 | "react-scripts": "1.1.0" 9 | }, 10 | "scripts": { 11 | "start": "react-scripts start", 12 | "build": "react-scripts build", 13 | "test": "react-scripts test --env=jsdom", 14 | "eject": "react-scripts eject" 15 | } 16 | } -------------------------------------------------------------------------------- /post/js高级面试/code/framework/to-do-list/react-test/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/js高级面试/code/framework/to-do-list/react-test/public/favicon.ico -------------------------------------------------------------------------------- /post/js高级面试/code/framework/to-do-list/react-test/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /post/js高级面试/code/framework/to-do-list/react-test/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 80px; 8 | } 9 | 10 | .App-header { 11 | background-color: #222; 12 | height: 150px; 13 | padding: 20px; 14 | color: white; 15 | } 16 | 17 | .App-title { 18 | font-size: 1.5em; 19 | } 20 | 21 | .App-intro { 22 | font-size: large; 23 | } 24 | 25 | @keyframes App-logo-spin { 26 | from { transform: rotate(0deg); } 27 | to { transform: rotate(360deg); } 28 | } 29 | -------------------------------------------------------------------------------- /post/js高级面试/code/framework/to-do-list/react-test/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import logo from './logo.svg'; 3 | import './App.css'; 4 | 5 | import Todo from './components/todo/index.js' 6 | 7 | class App extends Component { 8 | render() { 9 | return ( 10 |
11 | 12 |
13 | ); 14 | } 15 | } 16 | 17 | /* 18 | React.createElement( 19 | "div", 20 | null, 21 | React.createElement(Todo, null) 22 | ); 23 | 24 | var todo = new Todo() 25 | return todo.render() 26 | */ 27 | 28 | export default App; 29 | -------------------------------------------------------------------------------- /post/js高级面试/code/framework/to-do-list/react-test/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /post/js高级面试/code/framework/to-do-list/react-test/src/components/todo/input/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | class Input extends Component { 4 | constructor(props) { 5 | super(props) 6 | this.state = { 7 | title: '' 8 | } 9 | } 10 | render() { 11 | return ( 12 |
13 | 14 | 15 |
16 | ) 17 | } 18 | changeHandle(event) { 19 | this.setState({ 20 | title: event.target.value 21 | }) 22 | } 23 | clickHandle() { 24 | const title = this.state.title 25 | const addTitle = this.props.addTitle 26 | addTitle(title) // 重点!!! 27 | this.setState({ 28 | title: '' 29 | }) 30 | } 31 | } 32 | 33 | export default Input -------------------------------------------------------------------------------- /post/js高级面试/code/framework/to-do-list/react-test/src/components/todo/list/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | 3 | class List extends Component { 4 | constructor(props) { 5 | super(props) 6 | } 7 | render() { 8 | const list = this.props.data 9 | return ( 10 | 17 | ) 18 | 19 | /* 20 | React.createElement( 21 | "ul", 22 | null, 23 | list.map((item, index) => { 24 | return React.createElement( 25 | "li", 26 | { key: index }, 27 | item 28 | ); 29 | }) 30 | ); 31 | */ 32 | } 33 | } 34 | 35 | export default List -------------------------------------------------------------------------------- /post/js高级面试/code/framework/to-do-list/react-test/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | -------------------------------------------------------------------------------- /post/js高级面试/code/framework/to-do-list/react-test/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import registerServiceWorker from './registerServiceWorker'; 6 | 7 | // patch(container, vnode) 8 | ReactDOM.render(, document.getElementById('root')); 9 | registerServiceWorker(); 10 | 11 | /* 12 | React.createElement(App, null); 13 | var app = new App() 14 | return app.render() 15 | */ 16 | -------------------------------------------------------------------------------- /post/js高级面试/code/framework/to-do-list/vue/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 | 9 |
10 |

{{name}}

11 |

{{age}}

12 |
13 | 14 | 26 | 27 | -------------------------------------------------------------------------------- /post/js高级面试/code/framework/vdom/diff/log1.txt: -------------------------------------------------------------------------------- 1 | 123 2 | 123 3 | 123 4 | 123 5 | 123 6 | 123 7 | 123 8 | 123 9 | 123 10 | -------------------------------------------------------------------------------- /post/js高级面试/code/framework/vdom/diff/log2.txt: -------------------------------------------------------------------------------- 1 | 123 2 | 222 3 | 123 4 | 123 5 | 123wfsdfg 6 | 123 7 | 123 8 | 333 9 | abc 10 | 123 11 | 123 12 | 123 13 | 123 14 | -------------------------------------------------------------------------------- /post/js高级面试/code/framework/vdom/source/createElement.js: -------------------------------------------------------------------------------- 1 | function createElement(vnode) { 2 | var tag = vnode.tag // 'ul' 3 | var attrs = vnode.attrs || {} 4 | var children = vnode.children || [] 5 | if (!tag) { 6 | return null 7 | } 8 | 9 | // 创建真实的 DOM 元素 10 | var elem = document.createElement(tag) 11 | // 属性 12 | var attrName 13 | for (attrName in attrs) { 14 | if (attrs.hasOwnProperty(attrName)) { 15 | // 给 elem 添加属性 16 | elem.setAttribute(attrName, attrs[attrName]) 17 | } 18 | } 19 | // 子元素 20 | children.forEach(function (childVnode) { 21 | // 给 elem 添加子元素 22 | elem.appendChild(createElement(childVnode)) // 递归 23 | }) 24 | 25 | // 返回真实的 DOM 元素 26 | return elem 27 | } -------------------------------------------------------------------------------- /post/js高级面试/code/framework/vdom/source/updateChildren.js: -------------------------------------------------------------------------------- 1 | function updateChildren(vnode, newVnode) { 2 | var children = vnode.children || [] 3 | var newChildren = newVnode.children || [] 4 | 5 | children.forEach(function (childVnode, index) { 6 | var newChildVnode = newChildren[index] 7 | if (childVnode.tag === newChildVnode.tag) { 8 | // 深层次对比,递归 9 | updateChildren(childVnode, newChildVnode) 10 | } else { 11 | // 替换 12 | replaceNode(childVnode, newChildVnode) 13 | } 14 | }) 15 | } 16 | 17 | function replaceNode(vnode, newVnode) { 18 | var elem = vnode.elem // 真实的 DOM 节点 19 | var newElem = createElement(newVnode) 20 | 21 | // 替换 22 | } -------------------------------------------------------------------------------- /post/js高级面试/code/index.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/js高级面试/code/index.txt -------------------------------------------------------------------------------- /post/js高级面试/code/prototype/jquery/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 |

jquery test 1

9 |

jquery test 2

10 |

jquery test 3

11 | 12 |
13 |

jquery test in div

14 |
15 | 16 | 17 | 24 | 31 | 32 | -------------------------------------------------------------------------------- /post/js高级面试/code/prototype/jquery/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 |

jquery test 1

9 |

jquery test 2

10 |

jquery test 3

11 | 12 |
13 |

jquery test in div

14 |
15 | 16 | 17 | 26 | 27 | -------------------------------------------------------------------------------- /post/js高级面试/code/prototype/jquery/my-jquery.js: -------------------------------------------------------------------------------- 1 | (function (window) { 2 | 3 | var jQuery = function (selector) { 4 | return new jQuery.fn.init(selector) 5 | } 6 | 7 | jQuery.fn = { 8 | css: function (key, value) { 9 | alert('css') 10 | }, 11 | html: function (value) { 12 | return 'html' 13 | } 14 | } 15 | 16 | var init = jQuery.fn.init = function (selector) { 17 | var slice = Array.prototype.slice 18 | var dom = slice.call(document.querySelectorAll(selector)) 19 | 20 | var i, len = dom ? dom.length : 0 21 | for (i = 0; i < len; i++) { 22 | this[i] = dom[i] 23 | } 24 | this.length = len 25 | this.selector = selector || '' 26 | } 27 | 28 | init.prototype = jQuery.fn 29 | 30 | window.$ = jQuery 31 | 32 | })(window) -------------------------------------------------------------------------------- /post/js高级面试/code/prototype/zepto/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 |

zepto test 1

9 |

zepto test 2

10 |

zepto test 3

11 | 12 |
13 |

zepto test in div

14 |
15 | 16 | 17 | 26 | 27 | -------------------------------------------------------------------------------- /post/js高级面试/code/prototype/zepto/my-zepto.js: -------------------------------------------------------------------------------- 1 | (function (window) { 2 | 3 | var zepto = {} 4 | 5 | function Z(dom, selector) { 6 | var i, len = dom ? dom.length : 0 7 | for (i = 0; i < len; i++) { 8 | this[i] = dom[i] 9 | } 10 | this.length = len 11 | this.selector = selector || '' 12 | } 13 | 14 | zepto.Z = function (dom, selector) { 15 | return new Z(dom, selector) 16 | } 17 | 18 | zepto.init = function (selector) { 19 | var slice = Array.prototype.slice 20 | var dom = slice.call(document.querySelectorAll(selector)) 21 | return zepto.Z(dom, selector) 22 | } 23 | 24 | var $ = function (selector) { 25 | return zepto.init(selector) 26 | } 27 | window.$ = $ 28 | 29 | $.fn = { 30 | css: function (key, value) { 31 | alert('css') 32 | }, 33 | html: function (value) { 34 | return '这是一个模拟的 html 函数' 35 | } 36 | } 37 | Z.prototype = $.fn 38 | })(window) -------------------------------------------------------------------------------- /post/js高级面试/面向切面.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 | 37 | 38 | -------------------------------------------------------------------------------- /post/one-light/01.JavaScript/01.预读班/README.md: -------------------------------------------------------------------------------- 1 | ## 01.预读班 2 | 3 | - [x] [01.你不知道的HTML](./01.你不知道的HTML.md) 4 | - [x] [02.CSS3构建3D的世界](./02.CSS3构建3D的世界.md) 5 | - [x] [03.CSS高级实用技巧](./03.CSS高级实用技巧.md) 6 | - [x] [04.CSS与数学的巧妙运用](./04.CSS与数学的巧妙运用.md) 7 | - [x] [05.ES5核心技术](./05.ES5核心技术.md) 8 | - [x] [06.jQuery技术内幕](./06.jQuery技术内幕.md) 9 | - [x] [07.走进后端工程师的世界](./07.走进后端工程师的世界.md) 10 | - [x] [08.常用后端语言的介绍](./08.常用后端语言的介绍.md) 11 | -------------------------------------------------------------------------------- /post/one-light/01.JavaScript/04.php与mysql开发入门/README.md: -------------------------------------------------------------------------------- 1 | ## 04.php与mysql开发入门 2 | 3 | - [x] [01.PHP基础入门](./01.PHP基础入门.md) 4 | - [x] [02.PHP面向对象](./02.PHP面向对象.md) 5 | - [x] [03.PHP与MySQL操作](./03.PHP与MySQL操作.md) 6 | -------------------------------------------------------------------------------- /post/one-light/01.JavaScript/05.ES6/README.md: -------------------------------------------------------------------------------- 1 | > 参考文档 [ECMAScript 6 入门](http://es6.ruanyifeng.com/) 2 | 3 | - 前言 4 | - ECMAScript 6简介 5 | - let 和 const 命令 6 | - 变量的解构赋值 7 | - 字符串的扩展 8 | - 正则的扩展 9 | - 数值的扩展 10 | - 函数的扩展 11 | - 数组的扩展 12 | - 对象的扩展 13 | - 对象的新增方法 14 | - Symbol 15 | - Set 和 Map 数据结构 16 | - Proxy 17 | - Reflect 18 | - Promise 对象 19 | - Iterator 和 for...of 循环 20 | - Generator 函数的语法 21 | - Generator 函数的异步应用 22 | - async 函数 23 | - Class 的基本语法 24 | - Class 的继承 25 | - Module 的语法 26 | - Module 的加载实现 27 | - 编程风格 28 | - 读懂规格 29 | - ArrayBuffer 30 | - 最新提案 31 | - Decorator 32 | - 参考链接 33 | -------------------------------------------------------------------------------- /post/one-light/01.JavaScript/06.深度实践课/Javascript语言新发展【深度实践课】.md: -------------------------------------------------------------------------------- 1 | ## 【深度实践课】 2 | 3 | ### 三. ES6在企业中的应用 4 | 5 | 1. 模块语法 6 | 7 | ```js 8 | import {$} from 'jquery.js'; // es6 9 | var $ = require('jquery.js')['$']; // amd 10 | 11 | export {$}; // es6 12 | export.$ = $; // amd 13 | ``` 14 | 15 | - 按需引入 vs 全局引入 16 | - 多点暴露 vs 全局暴露 17 | 18 | ```js 19 | import {each, ...} from 'underscore.js'; // es6 20 | var _ = require('underscore.js'); // amd 21 | 22 | export {each, map, ...}; // es6 23 | module.exports = _; // amd 24 | ``` 25 | 26 | 2. 实战 27 | 28 | - 在线编译器(https://babeljs.io/repl/) 29 | 30 | 3. 参考资料 31 | 32 | - http://es6.ruanyifeng.com/ 33 | - http://www.infoq.com/cn/es6-in-depth/ 34 | - http://www.ecma-international.org/ecma-262/6.0/ 35 | - http://es6-features.org/ 36 | - https://github.com/lukehoban/es6features 37 | - https://github.com/es6-org/exploring-es6 38 | - http://yanhaijing.com/es5/ 39 | -------------------------------------------------------------------------------- /post/one-light/01.JavaScript/06.深度实践课/README.md: -------------------------------------------------------------------------------- 1 | ## 06.深度实践课 2 | 3 | - [x] [JavaScript与QA工程师](./01.JavaScript与QA工程师.md) 4 | -------------------------------------------------------------------------------- /post/one-light/01.JavaScript/06.深度实践课/source/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /post/one-light/01.JavaScript/06.深度实践课/source/paper.js: -------------------------------------------------------------------------------- 1 | var a = 20 2 | function init () { 3 | var a = 30 4 | var s = new Function('console.log(a)') 5 | s() 6 | s = new Function(console.log(a)) 7 | s() 8 | } 9 | init() 10 | -------------------------------------------------------------------------------- /post/one-light/01.JavaScript/README.md: -------------------------------------------------------------------------------- 1 | ## 01.JavaScript语言新发展 2 | 3 | - [x] [预读](./01.预读班) 4 | - [x] [你不知道的HTML](./01.预读班/01.你不知道的HTML.md) 5 | - [x] [CSS3构建3D的世界](./01.预读班/02.CSS3构建3D的世界.md) 6 | - [x] [CSS高级实用技巧](./01.预读班/03.CSS高级实用技巧.md) 7 | - [x] [CSS与数学的巧妙运用](./01.预读班/04.CSS与数学的巧妙运用.md) 8 | - [x] [ES5核心技术](./01.预读班/05.ES5核心技术.md) 9 | - [x] [jQuery技术内幕](./01.预读班/06.jQuery技术内幕.md) 10 | - [x] [走进后端工程师的世界](./01.预读班/07.走进后端工程师的世界.md) 11 | - [x] [常用后端语言的介绍](./01.预读班/08.常用后端语言的介绍.md) 12 | - [x] [linux基础入门](./02.linux基础入门) 13 | - [x] [ECMAScript5.1新增语法](./03.ECMAScript5.1新增语法) 14 | - [x] [php与mysql开发入门](./04.php与mysql开发入门) 15 | - [x] [PHP基础入门](./04.php与mysql开发入门/01.PHP基础入门.md) 16 | - [x] [PHP面向对象](./04.php与mysql开发入门/02.PHP面向对象.md) 17 | - [x] [PHP与MySQL操作](./04.php与mysql开发入门/03.PHP与MySQL操作.md) 18 | - [x] [ES6](./05.ES6) 19 | - [x] [深度实践课](./06.深度实践课) 20 | - [x] [JavaScript与QA工程师](./06.深度实践课/01.JavaScript与QA工程师.md) 21 | -------------------------------------------------------------------------------- /post/one-light/README.md: -------------------------------------------------------------------------------- 1 | ## 笔记记录 2 | 3 | 个人笔记请点击这里 [思鑫的小站](http://coder.liusixin.cn) 4 | 5 | - [x] [01.JavaScript](./01.JavaScript) 6 | - [ ] [02.NodeJS](/02.大话NodeJS72般变化) 7 | - [ ] [03.前端工程化](/03.前端工程化) 8 | - [ ] [04.前端性能优化与工程化](/04.前端性能优化与工程化) 9 | - [ ] [05.CSS](/05.CSS古话今说与网站重构) 10 | - [ ] [06.MVC MVVM框架](/06.MVC%20MVVM框架那些事) 11 | - [ ] [07.前端跨界AI、iOS、PC、Android、IOT](/07.前端跨界AI、iOS、PC、Android、IOT) 12 | - [ ] [08.数据结构与算法](/08.数据结构与算法JavaScript实践) 13 | - [ ] [09.JavaScript图形学](/09.JavaScript图形学和H5游戏) 14 | - [ ] [10.设计模式与网络安全](/10.设计模式与网络安全专场) 15 | -------------------------------------------------------------------------------- /post/one-light/other.md: -------------------------------------------------------------------------------- 1 | ### 笔记收集 2 | 3 | - [https://github.com/Martin-Shao/yideng-note](https://github.com/Martin-Shao/yideng-note) 4 | - [https://github.com/weisuoke/big-FE-note](https://github.com/weisuoke/big-FE-note) 5 | - [https://github.com/hubvue/nota](https://github.com/hubvue/nota) 6 | - [https://68wangxianming.github.io/index.html](https://68wangxianming.github.io/index.html) 7 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/project.zip -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = tab 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": true, 6 | "node": true 7 | }, 8 | "extends": "eslint:recommended", 9 | "parserOptions": { 10 | "sourceType": "module", 11 | "ecmaVersion": 2017 12 | }, 13 | "rules": { 14 | "indent": [ 15 | "error", 16 | "tab" 17 | ], 18 | "linebreak-style": [ 19 | "error", 20 | "unix" 21 | ], 22 | "quotes": [ 23 | "error", 24 | "single" 25 | ], 26 | "semi": [ 27 | "error", 28 | "always" 29 | ], 30 | "no-console": "off" 31 | } 32 | }; -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/.gitignore: -------------------------------------------------------------------------------- 1 | jspm_packages 2 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/controllers/user.js: -------------------------------------------------------------------------------- 1 | const bluebird = require('bluebird'); 2 | const connectionModel = require('../models/connection'); 3 | 4 | exports.login = async function(ctx, next){ 5 | ctx.render('login'); 6 | }; 7 | 8 | exports.doLogin = async function(ctx, next){ 9 | try{ 10 | 11 | const data = ctx.request.body; 12 | const connection = connectionModel.getConnection(); 13 | const query = bluebird.promisify(connection.query.bind(connection)); 14 | const results = await query( 15 | `select * from user where 16 | username = '${data.username}' 17 | and password = '${data.password}'` 18 | ); 19 | if(results.length){ 20 | let user = results[0]; 21 | 22 | // 登录成功,设置cookie 23 | ctx.cookies.set('userId', user.id, {httpOnly:false}); 24 | 25 | ctx.body = { 26 | status: 0, 27 | data:{ 28 | id: user.id, 29 | name: user.name 30 | } 31 | }; 32 | }else{ 33 | throw new Error('登录失败'); 34 | } 35 | 36 | connection.end(); 37 | }catch(e){ 38 | console.log('[/user/login] error:', e.message, e.stack); 39 | ctx.body = { 40 | status: e.code || -1, 41 | body: e.message 42 | }; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/models/connection.js: -------------------------------------------------------------------------------- 1 | const mysql = require('mysql'); 2 | exports.getConnection = function(){ 3 | let connection = mysql.createConnection({ 4 | host: 'localhost', 5 | database: 'safety', 6 | user: 'root', 7 | password: 'xl941201@' 8 | }); 9 | connection.connect(); 10 | return connection; 11 | }; 12 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/other/Untitled.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/other/Untitled.sketch -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/other/clickhijack.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | csrf demo 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/other/clickhijack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/other/clickhijack.png -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/other/csrf.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | csrf demo 6 | 7 | 8 | hello,这里什么也没有。 9 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "safety-code", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "dev": "NODE_ENV=development nodemon server.js -e\"js pug\"", 9 | "start": "node server.js" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "eslint": "^4.18.2", 15 | "jspm": "^0.16.53" 16 | }, 17 | "dependencies": { 18 | "bluebird": "^3.5.0", 19 | "cheerio": "^1.0.0-rc.2", 20 | "koa": "^2.2.0", 21 | "koa-bodyparser": "^4.2.0", 22 | "koa-pug": "^3.0.0-2", 23 | "koa-router": "^7.1.1", 24 | "koa-static": "^3.0.0", 25 | "mysql": "^2.13.0", 26 | "sequelize": "^5.15.1" 27 | }, 28 | "jspm": { 29 | "directories": { 30 | "baseURL": "static" 31 | }, 32 | "dependencies": { 33 | "axios": "npm:axios@^0.16.0", 34 | "form-serialize": "npm:form-serialize@^0.7.1" 35 | }, 36 | "devDependencies": {} 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/routes/site.js: -------------------------------------------------------------------------------- 1 | const Router = require('koa-router'); 2 | const router = new Router({ 3 | prefix: '' 4 | }); 5 | 6 | const site = require('../controllers/site'); 7 | 8 | router.all('/*', async function(ctx, next){ 9 | console.log('enter site.js'); 10 | await next(); 11 | }); 12 | 13 | router.get('/', site.index); 14 | router.get('/post/:id', site.post); 15 | router.post('/post/addComment', site.addComment); 16 | 17 | 18 | module.exports = router; 19 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/routes/user.js: -------------------------------------------------------------------------------- 1 | const Router = require('koa-router'); 2 | const router = new Router({ 3 | prefix: '/user' 4 | }); 5 | 6 | const user = require('../controllers/user'); 7 | 8 | /*router.all('/*', async function(ctx, next){ 9 | await next(); 10 | });*/ 11 | 12 | router.get('/login', user.login); 13 | router.post('/login', user.doLogin); 14 | 15 | module.exports = router; 16 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/server.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa'); 2 | const app = new Koa(); 3 | 4 | const koaStatic = require('koa-static'); 5 | app.use(koaStatic('./static', { 6 | hidden: true, 7 | maxage: 365*24*3600*1000 8 | })); 9 | const bodyParser = require('koa-bodyparser'); 10 | app.use(bodyParser()); 11 | 12 | const Pug = require('koa-pug'); 13 | /*const pug = */new Pug({ 14 | app, 15 | viewPath: './views', 16 | noCache: process.env.NODE_ENV === 'development' 17 | }); 18 | 19 | const routes = ['site', 'user']; 20 | routes.forEach((route) => { 21 | app.use(require(`./routes/${route}`).routes()); 22 | }); 23 | 24 | app.listen(1521, function(){ 25 | console.log('App is listening on port 1521'); 26 | }); 27 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2017 Materialize 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/css/main.css: -------------------------------------------------------------------------------- 1 | .top-nav{ 2 | /*height:30px;*/ 3 | /*line-height: 30px;*/ 4 | font-size:32px; 5 | } 6 | .indexBody{ 7 | padding-top:30px; 8 | } 9 | 10 | img.cover{ 11 | width:100%; 12 | height:300px; 13 | } 14 | 15 | .postWrapper{ 16 | border-bottom:1px solid #f0f0f0; 17 | } 18 | .postWrapper .row{ 19 | margin-top:10px; 20 | margin-bottom:10px; 21 | } 22 | .postWrapper img{ 23 | width:100%; 24 | height:150px; 25 | } 26 | .postWrapper a{ 27 | color: #333; 28 | } 29 | .postWrapper a:hover{ 30 | color:#039be5; 31 | } 32 | .postWrapper .info span{ 33 | color:#999; 34 | margin-right:15px; 35 | } 36 | 37 | .commentTitle{ 38 | margin-top:0; 39 | } 40 | 41 | .commentWrapper li{ 42 | border-bottom:1px solid #f0f0f0; 43 | margin-top:10px; 44 | padding-bottom:10px; 45 | } 46 | .commentWrapper li .nick{ 47 | color:#999; 48 | } 49 | .commentWrapper li .info{ 50 | color:#999; 51 | } 52 | 53 | .postTitle{ 54 | text-align: center; 55 | } 56 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Bold.eot -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Bold.ttf -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Bold.woff -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Bold.woff2 -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Light.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Light.eot -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Light.ttf -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Light.woff -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Light.woff2 -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Medium.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Medium.eot -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Medium.ttf -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Medium.woff -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Medium.woff2 -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Regular.eot -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Regular.ttf -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Regular.woff -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Regular.woff2 -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Thin.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Thin.eot -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Thin.ttf -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Thin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Thin.woff -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/source/t1eexx/static/materialize/fonts/roboto/Roboto-Thin.woff2 -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/static/scripts/login.js: -------------------------------------------------------------------------------- 1 | var formSerialize = require('form-serialize'); 2 | var axios = require('axios'); 3 | var modal = require('./ui/modal'); 4 | 5 | var $form = document.querySelector('[name=loginForm]'); 6 | 7 | $form.addEventListener('submit', (e) => { 8 | e.preventDefault(); 9 | let data = formSerialize($form, { 10 | hash: true 11 | }); 12 | 13 | axios.post('/user/login', data).then((data) => { 14 | if(data.status === 200 && data.data.status === 0){ 15 | location.href = '/'; 16 | console.log('登录成功'); 17 | }else{ 18 | modal.show({ 19 | content: '登录失败' 20 | }); 21 | console.log('登录失败'); 22 | } 23 | }); 24 | 25 | console.log('form submit', data); 26 | 27 | }); 28 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/todo.todo: -------------------------------------------------------------------------------- 1 | 用户系统: 2 | ✔ DB设计 @done (4/7/2017, 3:19:32 PM) 3 | ✔ 登录接口 @done (4/7/2017, 4:24:05 PM) 4 | ✔ 登录页面 @done (4/7/2017, 6:33:48 PM) 5 | 6 | 文章: 7 | ✔ DB设计 @done (4/7/2017, 10:19:45 PM) 8 | ✔ 文章读取 @done (4/20/2017, 7:48:28 PM) 9 | ✔ 文章列表页 @done (4/7/2017, 10:12:36 PM) 10 | ✔ 文章页面 @done (4/20/2017, 7:48:27 PM) 11 | 12 | 评论: 13 | ✔ DB设计 @done (4/21/2017, 3:55:15 PM) 14 | ✔ 评论读取 @done (4/21/2017, 3:55:18 PM) 15 | ✔ 评论显示 @done (4/21/2017, 3:55:24 PM) 16 | ✔ 发表评论接口 @done (4/21/2017, 3:55:25 PM) 17 | ☐ 上传图片 18 | 19 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/views/login.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title 登录 5 | meta(name="viewport",content="width=device-width, initial-scale=1") 6 | link(rel="stylesheet",href="/materialize/css/materialize.css") 7 | body 8 | .loginWrapper.container 9 | .row.section 10 | .col.s6.offset-s3 11 | h4 登录 12 | form(name="loginForm") 13 | .input-field 14 | input(name="username",placeholder="用户名") 15 | .input-field 16 | input(name="password",type="password",placeholder="密码") 17 | .input-field 18 | button.waves-effect.waves-light.btn 登录 19 | script(src="/jspm_packages/system.js") 20 | script(src="/config.js") 21 | script. 22 | System.import('scripts/login'); 23 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/source/t1eexx/views/post.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title #{post.title} 5 | meta(name="viewport",content="width=device-width, initial-scale=1") 6 | link(rel="stylesheet",href="/materialize/css/materialize.css") 7 | link(rel="stylesheet",href="/materialize/css/main.css") 8 | body 9 | .indexWrapper 10 | nav.top-nav 11 | .nav-wrapper.container 12 | a.page-title(href="/") 13 | span 昨日头条 14 | .container 15 | .row.section 16 | .col.s12 17 | h4.postTitle #{post.title} 18 | .post !{post.content} 19 | .row.section 20 | .col.s12 21 | .commentWrapper 22 | ul 23 | li.card.lighten-5 24 | .card-content 25 | form(name="commentForm",method="post",action="/post/addComment") 26 | input(name="postId",type="hidden",value=post.id) 27 | //- .input-field 28 | input(name="username",placeholder="名字") 29 | .input-field 30 | textarea(placeholder="内容",name="content",class="materialize-textarea") 31 | .input-field 32 | button.waves-effect.waves-light.btn 发表 33 | each comment in comments 34 | li.card.lighten-5 35 | .card-content 36 | p.info #{comment.username || '匿名用户'} #{comment.createdAt.toISOString().replace(/T.*/,'')} 37 | p.content !{comment.content} 38 | 39 | script(src="/jspm_packages/system.js") 40 | script(src="/config.js") 41 | script. 42 | //- System.import('scripts/post'); 43 | -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/xss攻击原理.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/xss攻击原理.png -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/明文密码泄露.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/明文密码泄露.png -------------------------------------------------------------------------------- /post/web前后端漏洞分析与防御/确定服务器身份.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/web前后端漏洞分析与防御/确定服务器身份.png -------------------------------------------------------------------------------- /post/前端性能优化/serviceWorker/app.js: -------------------------------------------------------------------------------- 1 | if (navigator.serviceWorker) { 2 | navigator.serviceWorker.register('./service-worker.js', {scope: './'}) 3 | .then(function(req){ 4 | console.log(req) 5 | }) 6 | .catch(function(e){ 7 | console.log(e) 8 | }) 9 | } else{ 10 | alert('Service Worker is not supported') 11 | } -------------------------------------------------------------------------------- /post/前端性能优化/serviceWorker/main.css: -------------------------------------------------------------------------------- 1 | #container{ 2 | color: red; 3 | } -------------------------------------------------------------------------------- /post/前端性能优化/serviceWorker/msg-demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /post/前端性能优化/serviceWorker/msgapp.js: -------------------------------------------------------------------------------- 1 | if (navigator.serviceWorker) { 2 | var sendBtn = document.querySelector('#send-msg-button') 3 | var msgInput = document.querySelector('#msg-input') 4 | var msgBox = document.querySelector('#msg-box') 5 | 6 | sendBtn.addEventListener('click', function(){ 7 | // 主页面发送信息到serviceworker 8 | navigator.serviceWorker.controller.postMessage(msgInput.value) 9 | }) 10 | 11 | navigator.serviceWorker.addEventListener('message', function(event){ 12 | msgBox.innerHTML = msgBox.innerHTML + ('
  • '+event.data.message+'
  • ') 13 | }) 14 | 15 | navigator.serviceWorker.register('./msgsw.js', {scope: './'}) 16 | .then(function(req){ 17 | console.log(req) 18 | }) 19 | .catch(function(e){ 20 | console.log(e) 21 | }) 22 | } else{ 23 | alert('Service Worker is not supported') 24 | } -------------------------------------------------------------------------------- /post/前端性能优化/serviceWorker/msgsw.js: -------------------------------------------------------------------------------- 1 | self.addEventListener('message',function(event){ 2 | var promise = self.clients.matchAll().then(function(clientList){ 3 | var senderID = event.source ? event.source.id : 'unknown' 4 | clientList.forEach(function(client){ 5 | if(client.id == senderID){ 6 | return 7 | }else{ 8 | client.postMessage({ 9 | client: senderID, 10 | message: event.data 11 | }) 12 | } 13 | }) 14 | }) 15 | event.waitUntil(promise) 16 | }) -------------------------------------------------------------------------------- /post/前端性能优化/serviceWorker/service-worker.js: -------------------------------------------------------------------------------- 1 | self.addEventListener('install', function(e){ 2 | e.waitUntil( 3 | caches.open('app-v1') 4 | .then(function(cache){ 5 | console.log('open cache') 6 | return cache.addAll([ 7 | './app.js', 8 | './main.css', 9 | './serviceWorker.html' 10 | ]) 11 | }) 12 | ) 13 | }) 14 | 15 | self.addEventListener('fetch', function(event){ 16 | event.respondWith( 17 | caches.match(event.request).then(function(res){ 18 | if(res) return res 19 | else { 20 | // 通过fetch方法向网络发起请求 21 | // fetch(url).then(function(res){ 22 | // if(res){ 23 | // //对于新请求的资源存储到我们的cachestorage中 24 | // caches 25 | // }else { 26 | // //用户提示 27 | // } 28 | // }) 29 | } 30 | }) 31 | ) 32 | }) -------------------------------------------------------------------------------- /post/前端性能优化/serviceWorker/serviceWorker.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | service worker 6 | 7 | 8 | 9 |
    10 | service worker 11 |
    12 | 13 | 14 | -------------------------------------------------------------------------------- /post/前端性能优化/workspace/css、js的加载与执行.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/前端性能优化/workspace/css、js的加载与执行.pptx -------------------------------------------------------------------------------- /post/前端性能优化/workspace/图片相关的优化.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/前端性能优化/workspace/图片相关的优化.pptx -------------------------------------------------------------------------------- /post/前端性能优化/workspace/懒加载与预加载.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/前端性能优化/workspace/懒加载与预加载.pptx -------------------------------------------------------------------------------- /post/前端性能优化/workspace/浏览器存储.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/前端性能优化/workspace/浏览器存储.pptx -------------------------------------------------------------------------------- /post/前端性能优化/workspace/资源合并与压缩.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/前端性能优化/workspace/资源合并与压缩.pptx -------------------------------------------------------------------------------- /post/前端性能优化/workspace/重绘与回流.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/前端性能优化/workspace/重绘与回流.pptx -------------------------------------------------------------------------------- /post/前端性能优化/缓存/assets/view.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/前端性能优化/缓存/assets/view.jpg -------------------------------------------------------------------------------- /post/前端性能优化/缓存/config.js: -------------------------------------------------------------------------------- 1 | exports.Expires = { 2 | fileMatch: /^(gif|jpg|png|js|css)$/ig, 3 | maxAge: 60 * 60 * 24 * 365 4 | } -------------------------------------------------------------------------------- /post/前端性能优化/缓存/mime.js: -------------------------------------------------------------------------------- 1 | exports.types = { 2 | 'jpg': 'image/jpeg', 3 | 'json': 'application/json' 4 | } -------------------------------------------------------------------------------- /post/数据结构与算法/02.栈.md: -------------------------------------------------------------------------------- 1 | # 2. 栈 2 | 3 | > 栈是一种遵从先进后出(LIFO)原则的有序集合。新添加的或待删除的元素都保存在栈的末尾,称作栈顶,另一端就叫栈底。在栈里,新元素都靠近栈顶,旧元素都接近栈底。 4 | 5 | 而栈主要是在编程语言的编译器里用来保存变量和方法调用等。 6 | 7 | ## 创建栈 8 | 9 | ```js 10 | function Stack() { 11 | this.dataStore = []; //保存栈内元素 12 | this.top = 0; //标记可以插入新元素的位置 13 | this.push = push; //入栈操作 14 | this.pop = pop; //出栈操作 15 | this.peek = peek; //返回栈顶元素 16 | this.clear = clear; //清空栈 17 | this.length = length; //栈的长度 18 | } 19 | //向栈中压入元素 同时让指针top+1 一定注意++ 20 | function push(element) { 21 | this.dataStore[this.top++] = element; 22 | } 23 | //出栈操作 同时将top-1 24 | function pop() { 25 | return this.dataStore[--this.top]; 26 | } 27 | //返回栈顶元素,变量top值减1 返回不删除 28 | function peek() { 29 | return this.dataStore[this.top - 1]; 30 | } 31 | //返回栈内元素个数 32 | function length() { 33 | return this.top; 34 | } 35 | //清空一个栈 36 | function clear() { 37 | this.top = 0; 38 | } 39 | ``` 40 | 41 | ### 回文算法 42 | 43 | ```js 44 | //回文算法 45 | 46 | function isPalindrome(word){ 47 | var s = new Stack(); 48 | for(var i=0;i0){ 53 | rword+=s.pop(); 54 | } 55 | if(rword == word){ 56 | return true; 57 | }else{ 58 | return false 59 | } 60 | } 61 | var word = "12321"; 62 | console.log(isPalindrome(word)); 63 | ``` 64 | -------------------------------------------------------------------------------- /post/数据结构与算法/06.字典.md: -------------------------------------------------------------------------------- 1 | # 6. 字典 2 | 3 | - 字典以一种键-值对形式存储 4 | - JavaScript的Object类就是以字典的形式设计的。我们要实现一个Dictionary类,这样会比Object方便,比如显示字典中的所有元素,对属性进行排序等 5 | 6 | ```js 7 | function Dictionary(){ 8 | this.dataStore = new Array(); 9 | this.add = add; 10 | this.find = find; 11 | this.count = count; 12 | this.clear = clear; 13 | this.remove = remove; 14 | this.showAll = showAll; 15 | } 16 | function add(key, value){ 17 | this.dataStore[key] = value; 18 | } 19 | function find(key){ 20 | return this.dataStore[key]; 21 | } 22 | function remove(key){ 23 | delete this.dataStore[key]; 24 | } 25 | function showAll(){ 26 | var datakeys = Object.keys(this.dataStore).sort(); 27 | for(var keys in datakeys){ 28 | console.log(datakeys[keys]+"-->"+this.dataStore[datakeys[keys]]); 29 | } 30 | } 31 | function count(){ 32 | return Object.keys(this.dataStore).length; 33 | } 34 | function clear(){ 35 | var datakeys = Object.keys(this.dataStore); 36 | for(var keys in datakeys){ 37 | delete this.dataStore[datakeys[keys]]; 38 | } 39 | } 40 | var pbook = new Dictionary(); 41 | pbook.add('e','1'); 42 | pbook.add('b','2'); 43 | pbook.add('f','3'); 44 | pbook.add('d','4'); 45 | //console.log(pbook.find('c')); 46 | pbook.showAll(); 47 | ``` 48 | -------------------------------------------------------------------------------- /post/数据结构与算法/source/Dictionary.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 字典 3 | */ 4 | class Dictionary { 5 | constructor() { 6 | this.dataStore = new Array(); 7 | } 8 | add (key, value) { 9 | this.dataStore[key] = value; 10 | } 11 | find (key) { 12 | return this.dataStore[key]; 13 | } 14 | remove (key) { 15 | delete this.dataStore[key]; 16 | } 17 | showAll () { 18 | var datakeys = Object.keys(this.dataStore).sort(); 19 | for (var keys in datakeys) { 20 | console.log(datakeys[keys] + "-->" + this.dataStore[datakeys[keys]]); 21 | } 22 | } 23 | count () { 24 | return Object.keys(this.dataStore).length; 25 | } 26 | clear () { 27 | var datakeys = Object.keys(this.dataStore); 28 | for (var keys in datakeys) { 29 | delete this.dataStore[datakeys[keys]]; 30 | } 31 | } 32 | } 33 | 34 | var pbook = new Dictionary(); 35 | pbook.add('a', '111'); 36 | pbook.add('b', '222'); 37 | pbook.add('c', '333'); 38 | pbook.add('d', '444'); 39 | pbook.showAll(); 40 | -------------------------------------------------------------------------------- /post/数据结构与算法/source/Tree.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 二叉树 3 | */ 4 | class Node { 5 | constructor(data, left, right) { 6 | this.data = data 7 | this.left = left 8 | this.right = right 9 | } 10 | } 11 | 12 | class BST { 13 | constructor() { 14 | this.root = null 15 | } 16 | insert (data) { 17 | let node = new Node(data, null, null) 18 | if (!this.root) this.root = node 19 | else { 20 | let current = this.root, parent 21 | while (true) { 22 | parent = current 23 | if (node.data < current.data) { 24 | current = current.left 25 | if (!current) { 26 | parent.left = node 27 | break 28 | } 29 | } else { 30 | current = current.right 31 | if (!current) { 32 | parent.right = node 33 | break 34 | } 35 | } 36 | } 37 | } 38 | } 39 | inOrder (node) { 40 | if (node) { 41 | this.inOrder(node.left) 42 | console.log(node.data) 43 | this.inOrder(node.right) 44 | } 45 | } 46 | } 47 | 48 | let nums = new BST(); 49 | nums.insert(23); 50 | nums.insert(45); 51 | nums.insert(26); 52 | nums.insert(47); 53 | nums.insert(37); 54 | nums.insert(3); 55 | nums.insert(101); 56 | //console.log(nums.getMin()) 57 | // nums.remove(3); 58 | nums.inOrder(nums.root); 59 | -------------------------------------------------------------------------------- /post/计算机组成原理+操作系统+计算机网络/02.操作系统.md: -------------------------------------------------------------------------------- 1 | # 操作系统 2 | 3 | - 基础 4 | - 进程管理 5 | - 存储管理 6 | - 文件管理 7 | - 作业管理 8 | - linux系统 9 | - 提升 10 | - 线程同步 11 | - 进程同步 12 | - 线程协程 13 | - 用户态与内核态 14 | - 上下文切换 15 | - 综合实践 16 | - 线程安全 17 | - 线程池 18 | - 同步任务 19 | - 异步任务 20 | -------------------------------------------------------------------------------- /post/计算机组成原理+操作系统+计算机网络/03.计算机网络.md: -------------------------------------------------------------------------------- 1 | # 操作系统 2 | 3 | - 概述 4 | - 七层模型 5 | - 四层协议 6 | - 物理层 7 | - 数据链路层 8 | - 底层协议 9 | - 网络层 10 | - IP协议 11 | - ICMP协议 12 | - 子网划分 13 | - 路由算法 14 | - IPv6 15 | - 传输层 16 | - TCP协议 17 | - UDP协议 18 | - 超时重传机制 19 | - 拥塞避免算法 20 | - 心跳保护机制 21 | - 应用层 22 | - HTTP协议 23 | - URL资源 24 | - HTTP结构 25 | - HTTPS安全 26 | - HTTP服务 27 | - 综合实践 28 | - 使用线程池 29 | - IP报文 30 | - ICMP报文 31 | - TCP报文 32 | - UDP报文 33 | -------------------------------------------------------------------------------- /post/设计模式与开发实践/01.创建型设计模式/单例模式.md: -------------------------------------------------------------------------------- 1 | # 六. 单例模式 2 | 3 | > 单例模式又称为单体模式,其实就是只允许实例化一个对象,有时我们也可以用一个对象类规划命名空间,仅仅有条的管理对象的属性和方法。 4 | 5 | ```js 6 | //命名空间管理 7 | var obj = { 8 | g: function(id) { 9 | return document.getElementById(id); 10 | }, 11 | css: function(id, key, value) { 12 | this.g(id).style[key] = value; 13 | } 14 | //... 15 | }; 16 | //模块分明 17 | var A = { 18 | Util: { 19 | util_method1: function() {}, 20 | util_method2: function() {} 21 | }, 22 | Tool: { 23 | tool_method1: function() {}, 24 | tool_method2: function() {} 25 | } 26 | //... 27 | }; 28 | //惰性单例 29 | var LazySingle = (function() { 30 | //单例实例引用 31 | var _instance = null; 32 | //单例 33 | function Single() { 34 | return { 35 | publicMethod: function() {}, 36 | publicProperty: '1.0' 37 | }; 38 | } 39 | //获取单例接口 40 | return function() { 41 | if (!_instance) { 42 | _instance = Single(); 43 | } 44 | //返回单例 45 | return _instance; 46 | }; 47 | })(); 48 | ``` 49 | -------------------------------------------------------------------------------- /post/设计模式与开发实践/02.结构型设计模式/代理模式.md: -------------------------------------------------------------------------------- 1 | # 三. 代理模式 2 | 3 | > 由于一个对象不能直接引用另一个对象,所以需要代理对象在这两个对象之间起到中介的作用 4 | 5 | ```js 6 | // 先声明美女对象 7 | var girl = function(name) { 8 | this.name = name; 9 | }; 10 | 11 | // 这是dudu 12 | var dudu = function(girl) { 13 | this.girl = girl; 14 | this.sendGift = function(gift) { 15 | alert('Hi ' + girl.name + ', dudu送你一个礼物:' + gift); 16 | }; 17 | }; 18 | 19 | // 大叔是代理 20 | var proxyTom = function(girl) { 21 | this.girl = girl; 22 | this.sendGift = function(gift) { 23 | new dudu(girl).sendGift(gift); // 替dudu送花咯 24 | }; 25 | }; 26 | 27 | var proxy = new proxyTom(new girl('酸奶小妹')); 28 | proxy.sendGift('999朵玫瑰'); 29 | ``` 30 | 31 | 假如 dudu 要送酸奶小妹玫瑰花,却不知道她的联系方式或者不好意思,想委托大叔去送这些玫瑰,那大叔就是个代理 32 | 33 | 其实在日常开发中,我们遇到很多这种情况,比如跨域,之前总结过跨域的所有东西,其中的 jsonp,window.name 还是 location.hash 都是通过代理模式来实现的。 34 | -------------------------------------------------------------------------------- /post/设计模式与开发实践/02.结构型设计模式/外观模式.md: -------------------------------------------------------------------------------- 1 | # 一. 外观模式 2 | 3 | > 为一组复杂子系统接口提供一个更高级的统一接口,通过这个接口使得对子系统访问更加的容易。 4 | 5 | ```js 6 | // 使用外观模式注册事件监听 7 | function addEvent(dom, type, fn) { 8 | if (dom.addEventListener) { 9 | dom.addEventListener(type, fn, false); 10 | } else if (dom.attachEvent) { 11 | dom.attachEvent('on' + type, fn); 12 | } else { 13 | dom['on' + type] = fn; 14 | } 15 | } 16 | // 使用外观模式获取事件对象 17 | 18 | var getEvent = function(event) { 19 | return event || window.event; 20 | }; 21 | ``` 22 | 23 | 通过对接口的二次封装,使其简单易用,隐藏起内部的复杂度,外观模式就是对接口的外层包装,以供上层代码调用。因此外观模式封装的接口方法不需要接口的具体实现,只需要按照接口的使用规则使用即可。 24 | -------------------------------------------------------------------------------- /post/设计模式与开发实践/02.结构型设计模式/桥接模式.md: -------------------------------------------------------------------------------- 1 | # 五. 桥接模式 2 | 3 | > 在系统沿着多个维度变化的时候,不增加起复杂度已达到解耦的目的 4 | 5 | ## 场景 6 | 7 | 在我们日常开发中,需要对相同的逻辑做抽象的处理。桥接模式就是为了解决这类的需求。 8 | 9 | 桥接模式最主要的特点就是将实现层和抽象层解耦分离,是两部分可以独立变化 10 | 11 | 比如我们写一个跑步游戏,对于游戏中的人和精灵都是动作单元。而他们的动作也是非常的统一。比如人和精灵和球运动都是 x,y 坐标的改变,球的颜色和精灵的颜色绘制方式也非常的类似。 我们就可以将这些方法给抽象出来。 12 | 13 | ```js 14 | //运动单元 15 | function Speed(x, y) { 16 | this.x = x; 17 | this.y = y; 18 | } 19 | Speed.prototype.run = function() { 20 | console.log('动起来'); 21 | }; 22 | // 着色单元 23 | function Color(cl) { 24 | this.color = cl; 25 | } 26 | Color.prototype.draw = function() { 27 | console.log('绘制色彩'); 28 | }; 29 | 30 | // 变形单元 31 | function Shape(ap) { 32 | this.shape = ap; 33 | } 34 | Shape.prototype.change = function() { 35 | console.log('改变形状'); 36 | }; 37 | //说话单元 38 | function Speak(wd) { 39 | this.word = wd; 40 | } 41 | Speak.prototype.say = function() { 42 | console.log('请开始你的表演'); 43 | }; 44 | 45 | //创建球类,并且它可以运动可以着色 46 | function Ball(x, y, c) { 47 | this.speed = new Speed(x, y); 48 | this.color = new Color(c); 49 | } 50 | Ball.prototype.init = function() { 51 | //实现运动和着色 52 | this.speed.run(); 53 | this.color.draw(); 54 | }; 55 | 56 | function People(x, y, f) { 57 | this.speed = new Speed(x, y); 58 | this.speak = new Speak(f); 59 | } 60 | 61 | People.prototype.init = function() { 62 | this.speed.run(); 63 | this.speak.say(); 64 | }; 65 | //... 66 | 67 | //当我们实例化一个人物对象的时候,他就可以有对应的方法实现了 68 | 69 | var p = new People(10, 12, '我是一个人'); 70 | p.init(); 71 | ``` -------------------------------------------------------------------------------- /post/设计模式与开发实践/02.结构型设计模式/装饰者模式.md: -------------------------------------------------------------------------------- 1 | # 四. 装饰者模式 2 | 3 | > 在不改变源对象的基础上,通过对其进行包装拓展使原有对象可以满足用户的更复杂需求 4 | 5 | 这里拿给输入框添加事件举例 6 | 7 | ```js 8 | var decorator = function(input, fn) { 9 | //获取时间源 10 | var input = document.getElementById(input); 11 | if (typeof input.onclick === 'function') { 12 | //缓存事件源原有的回调函数 13 | var oldClickFn = input.onclick; 14 | input.onclick = function(ev) { 15 | oldClickFn(); 16 | fn(); 17 | }; 18 | } else { 19 | input.onclick = fn; 20 | } 21 | }; 22 | ``` 23 | 24 | 装饰着模式很简单,就是对原有对象的属性和方法的添加。相比于之前说的适配器模式是对原有对象的适配,添加的方法和原有的方法功能上大致相似。但是装饰着提供的方法和原有方法功能项则有一定的区别,且不需要去了解原有对象的功能。只要原封不动的去使用就行。不需要知道具体的实现细节。 25 | -------------------------------------------------------------------------------- /post/设计模式与开发实践/03.行为型设计模式/命令模式.md: -------------------------------------------------------------------------------- 1 | # 六. 命令模式 2 | 3 | > 用来对方法调用进行参数化处理和传送,经过这样处理过的方法调用可以在任何需要的时候执行。也就是说该模式旨在将函数的调用、请求和操作封装成一个单一的对象,然后对这个对象进行一些列的处理。他也可以用来消除调用操作的对象和实现操作的对象之间的耦合。这为各种具体的类的更换带来了极大的灵活性。 4 | 5 | ```js 6 | //1.一个连有炮兵和步兵,司令可以下命令调动军队打仗 7 | var lian = {}; 8 | lian.paobing = function(pao_num) { 9 | console.log(pao_num + '门炮准备战斗'); 10 | }; 11 | lian.bubing = function(bubing_num) { 12 | console.log(bubing_num + '人准备战斗'); 13 | }; 14 | lian.lianzhang = function(mingling) { 15 | lian[mingling.type](mingling.num); 16 | }; 17 | 18 | //司令下命令 19 | lian.lianzhang({ 20 | type: 'paobing', 21 | num: 10 22 | }); 23 | lian.lianzhang({ 24 | type: 'bubing', 25 | num: 100 26 | }); 27 | ``` 28 | -------------------------------------------------------------------------------- /post/设计模式与开发实践/03.行为型设计模式/状态模式.md: -------------------------------------------------------------------------------- 1 | # 三. 状态模式 2 | 3 | > 当一个对象内部状态发生变化的时候,会导致起行为变化,看起来就像改变了对象 4 | 5 | 状态模式定义了一个对象,这个对象可以通过管理其内部状态从而是其行为发生变化。状态模式是一个非常出色的设计模式,主要由两个角色构成 6 | 7 | - 环境类:拥有一个状态成员,可以修改其状态并做出反应 8 | - 状态类:表示一种状态,包含相应的处理方法 9 | 10 | ### 演示 11 | 12 | 一个简单的例子,我们可以将不同的判断结构封装在一个状态对象内,然后该状态对象返回一个可被调用的状态方法,用于调用对象内部某个方法。 13 | 14 | ```js 15 | var ResultState = (function() { 16 | var States = { 17 | state0: function() { 18 | console.log('这是第一种结果'); 19 | }, 20 | state1: function() { 21 | console.log('这是第二种结果'); 22 | }, 23 | state2: function() { 24 | console.log('这是第三种结果'); 25 | }, 26 | state3: function() { 27 | console.log('这是第四种结果'); 28 | } 29 | }; 30 | //获取某一种状态并执行相应的方法 31 | function show(result) { 32 | States['state' + result] && States['state' + result](); 33 | } 34 | 35 | return { 36 | show: show 37 | }; 38 | })(); 39 | 40 | ResultState.show(4); 41 | ``` 42 | 43 | 上面代码只是一个雏形,对于状态模式主要目的就是将条件判断的不同结构,转化为状态对象的内部状态,既然是状态对象的内部状态,所以一般是作为状态对象的私有变量,然后提供一个能够调用状态对象内部状态的接口方法对象 44 | -------------------------------------------------------------------------------- /post/设计模式与开发实践/03.行为型设计模式/策略模式.md: -------------------------------------------------------------------------------- 1 | # 四. 策略模式 2 | 3 | > 将定义的一组算法封装起来,使其相互之间可以替代。封装的算法具有一定的独立性,不会随着客户端变化而变化 4 | 5 | 从结构上看,他和状态模式非常的相似,也是在内部封装一个对象,然后通过返回的借口对象实现对内部对象的调用,不同的是,策略模式不需要管理状态,状态之间没有依赖关系,策略之间可以相互替换,在策略对象内部保存的是一些相对独立的一些算法。 6 | -------------------------------------------------------------------------------- /post/设计模式与开发实践/03.行为型设计模式/访问者模式.md: -------------------------------------------------------------------------------- 1 | # 七. 访问者模式 2 | 3 | > 针对于对象结构中的元素,定义在不改变对象的前提下访问结构中元素的方法 4 | 5 | 在访问者模式中,主要包括下面几个角色 6 | 7 | 1. 抽象访问者:抽象类或者接口,声明访问者可以访问哪些元素,具体到程序中就是 visit 方法中的参数定义哪些对象是可以被访问的。 8 | 2. 访问者:实现抽象访问者所声明的方法,它影响到访问者访问到一个类后该干什么,要做什么事情。 9 | 3. 抽象元素类:接口或者抽象类,声明接受哪一类访问者访问,程序上是通过 accept 方法中的参数来定义的。抽象元素一般有两类方法,一部分是本身的业务逻辑,另外就是允许接收哪类访问者来访问。 10 | 4. 元素类:实现抽象元素类所声明的 accept 方法,通常都是`visitor.visit(this)`,基本上已经形成一种定式了。 11 | 5. 结构对象:一个元素的容器,一般包含一个容纳多个不同类、不同接口的容器,如 List、Set、Map 等,在项目中一般很少抽象出这个角色。 12 | 13 | ```js 14 | // 访问者 15 | function Visitor() { 16 | this.visit = function(concreteElement) { 17 | concreteElement.doSomething(); 18 | }; 19 | } 20 | // 元素类 21 | function ConceteElement() { 22 | this.doSomething = function() { 23 | console.log('这是一个具体元素'); 24 | }; 25 | this.accept = function(visitor) { 26 | visitor.visit(this); 27 | }; 28 | } 29 | // Client 30 | var ele = new ConceteElement(); 31 | var v = new Visitor(); 32 | ele.accept(v); 33 | ``` -------------------------------------------------------------------------------- /post/设计模式与开发实践/source/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 设计模式 8 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /post/设计模式与开发实践/source/park.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/设计模式与开发实践/source/park.png -------------------------------------------------------------------------------- /post/高效前端:Web高效编程与优化实践/Effective 27/src/img/coder.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/post/高效前端:Web高效编程与优化实践/Effective 27/src/img/coder.jpg -------------------------------------------------------------------------------- /post/高效前端:Web高效编程与优化实践/Effective 27/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | CSS 居中 9 | 23 | 24 | 25 | 26 |
    27 | 28 |
    29 | 30 | 31 | -------------------------------------------------------------------------------- /post/高效前端:Web高效编程与优化实践/Effective 32/src/children.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | JS 高级技巧 - children 9 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /post/高效前端:Web高效编程与优化实践/Effective 32/src/demo.js: -------------------------------------------------------------------------------- 1 | let data = [1, 2, 3]; 2 | console.log(data instanceof Array); //true 3 | 4 | var toString = Object.prototype.toString; 5 | toString.call([1, 2, 3]); // [object Array] 6 | toString.call({}); // [object Object] 7 | toString.call(function(){}); // [object Function] 8 | toString.call(""); // [object String] 9 | toString.call(1); // [object Number] 10 | toString.call(null); // [object Null] 11 | toString.call(undefined); // [object Undefined] 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /post/高效前端:Web高效编程与优化实践/Effective 32/src/parent.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | JS 高级技巧 - parent 9 | 10 | 11 | 12 | 13 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /post/高效前端:Web高效编程与优化实践/Effective 33/src/README.md: -------------------------------------------------------------------------------- 1 | 2 | 需要安装: 3 | ```shell 4 | npm install karma jasmine-core karma-jasmine karma-chrome-launcher 5 | 6 | npm install karma -g 7 | ``` -------------------------------------------------------------------------------- /post/高效前端:Web高效编程与优化实践/Effective 33/src/conf.js: -------------------------------------------------------------------------------- 1 | exports.config = { 2 | seleniumAddress: 'http://localhost:4444/wd/hub', 3 | specs: ['test-spec.js'] 4 | } -------------------------------------------------------------------------------- /post/高效前端:Web高效编程与优化实践/Effective 33/src/demo.sh: -------------------------------------------------------------------------------- 1 | worker_processes 1; 2 | events { 3 | worker_connections 1024; 4 | } 5 | http { 6 | include mime.types; 7 | default_type application/octet-stream; 8 | server_names_hash_bucket_size 64; 9 | access_log off; 10 | 11 | sendfile on; 12 | keepalive_timeout 65; 13 | 14 | server { 15 | listen 3001; 16 | location / { 17 | proxy_pass http://127.0.0.1:8000; 18 | proxy_redirect default; 19 | proxy_http_version 1.1; 20 | proxy_set_header Upgrade $http_upgrade; 21 | proxy_set_header Connection $http_connection; 22 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 23 | proxy_set_header Host $http_host; 24 | } 25 | } 26 | } 27 | 28 | DOCKER OPTS = "--dns 8.8.8.8" -------------------------------------------------------------------------------- /post/高效前端:Web高效编程与优化实践/Effective 33/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "src", 3 | "version": "1.0.0", 4 | "description": "需要安装: ```shell npm install karma jasmine-core karma-jasmine karma-chrome-launcher", 5 | "main": "karma.conf.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "devDependencies": { 16 | "jasmine-core": "^3.1.0", 17 | "karma": "^2.0.5", 18 | "karma-chrome-launcher": "^2.2.0", 19 | "karma-coverage": "^1.1.2", 20 | "karma-jasmine": "^1.1.2", 21 | "karma-webpack": "^3.0.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /post/高效前端:Web高效编程与优化实践/Effective 33/src/src/util.js: -------------------------------------------------------------------------------- 1 | var util = { 2 | reverse(str) { 3 | if(typeof str !== "string") throw "util.reverse should pass a string argument"; 4 | if(str.length <= 1) return str; 5 | else return str.split("").reverse().join(""); 6 | } 7 | } -------------------------------------------------------------------------------- /post/高效前端:Web高效编程与优化实践/Effective 33/src/test-spec.js: -------------------------------------------------------------------------------- 1 | describe("site", function() { 2 | it("登录框正常使用", function() { 3 | browser.waitForAngularEnabled(false); 4 | browser.get("https://test.com"); 5 | expect(browser.getTitle()).toEqual("Search Listings in Las Vegas - tes"); 6 | $$("nav .sign-icon + li.sign-in").click(); 7 | expect($$(".sign-log").count()).toEqual(1); 8 | $$(".sign-log input[name=account]").sendKeys("yin@abc.com"); 9 | $$(".sign-log input[name=password]").sendKeys("3345983893"); 10 | $$(".sign-log input[type=submit]").click(); 11 | browser.driver.sleep(1000); 12 | expect($$(".sign-log").count()).toEqual(0); 13 | }); 14 | }); -------------------------------------------------------------------------------- /post/高效前端:Web高效编程与优化实践/Effective 33/src/test/util-test.js: -------------------------------------------------------------------------------- 1 | describe("reverse", function() { 2 | it("reverse word", function() { 3 | expect(util.reverse("abc")).toEqual("cba"); 4 | }); 5 | 6 | it("reverse字符串长度为1时返回自已", function() { 7 | expect(util.reverse("a")).toBe("a"); 8 | }); 9 | 10 | it("reverse传值不是字符串时会抛异常", function() { 11 | expect(function() { 12 | util.reverse(null) 13 | }).toThrow(); 14 | }); 15 | }); -------------------------------------------------------------------------------- /post/高效前端:Web高效编程与优化实践/Effective 33/src/util-test/index.js: -------------------------------------------------------------------------------- 1 | // 加载 `unit-test/test/*.js` 里所有的测试文件 2 | const tests = require.context('./test', true, /\.js$/); 3 | tests.keys().forEach(tests); 4 | // 加载 `js/lib/*.js` 里的lib文件 5 | const libs = require.context('../js/lib', true, /util\.js$/); 6 | libs.keys().forEach(libs); 7 | // 加载 `js/module/*.js` 里所有的 module 文件 8 | const modules = require.context('../js/module', true, /\.js$/); 9 | modules.keys().forEach(modules); -------------------------------------------------------------------------------- /source-learn/collect/aop.js: -------------------------------------------------------------------------------- 1 | /** 2 | * AOP面向切面编程 3 | */ 4 | Function.prototype.before = function (beforeFn) { 5 | let _self = this 6 | return function () { 7 | beforeFn.apply(this, arguments) // 执行当前函数 8 | return _self.apply(this, arguments) // 执行原函数 9 | } 10 | } 11 | 12 | Function.prototype.after = function (beforeFn) { 13 | let _self = this 14 | return function () { 15 | let result = _self.apply(this, arguments) // 执行原函数 16 | beforeFn.apply(this, arguments) // 执行当前函数 17 | return result 18 | } 19 | } 20 | 21 | let func = () => console.log('func', this); 22 | func = func.before(() => { 23 | console.log('===before===', this); 24 | }).after(() => { 25 | console.log('===after===', this); 26 | }) 27 | 28 | func(); 29 | -------------------------------------------------------------------------------- /source-learn/collect/factorial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 阶乘(尾递归优化) 3 | */ 4 | function factorial (n) { 5 | if (n <= 1) return 1 6 | return n * factorial(n - 1) 7 | } 8 | 9 | function factorial1 (n, total = 1) { 10 | if (n <= 1) return total 11 | return factorial1(n - 1, total * n) 12 | } 13 | 14 | console.log(factorial(5), factorial1(5)) 15 | -------------------------------------------------------------------------------- /source-learn/collect/fib.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 斐波那契数列 3 | * 斐波那契数列从第三项开始,每一项都等于前两项之和。 4 | * 指的是这样一个数列:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144 … 5 | */ 6 | 7 | // 递归 O(2^n) 8 | function fib (n) { 9 | if (n === 1 || n === 2) return n - 1 10 | return fib(n - 1) + fib(n - 2) 11 | } 12 | 13 | // 循环 O(n) 14 | function fib1 (n) { 15 | let a = 0; 16 | let b = 1; 17 | let c = a + b; 18 | let index = 3 19 | while (index < n) { 20 | a = b; 21 | b = c; 22 | c = a + b; 23 | index++ 24 | } 25 | return c; 26 | } 27 | 28 | console.log(fib(10), fib1(10)) 29 | -------------------------------------------------------------------------------- /source-learn/collect/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 |
    12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /source-learn/collect/stack.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 栈结构 3 | */ 4 | class Stack { 5 | constructor() { 6 | let wm = new WeakMap() 7 | this.store = wm.set(this, []) 8 | this.top = 0 9 | } 10 | } 11 | const Stack = (() => { 12 | const wm = new WeakMap() 13 | class Stack { 14 | constructor() { 15 | wm.set(this, []) 16 | this.top = 0 17 | } 18 | 19 | push (...nums) { 20 | let list = wm.get(this) 21 | nums.forEach(item => { 22 | list[this.top++] = item 23 | }) 24 | } 25 | 26 | pop () { 27 | let list = wm.get(this) 28 | let last = list[--this.top] 29 | list.length = this.top 30 | return last 31 | } 32 | 33 | peek () { 34 | let list = wm.get(this) 35 | return list[this.top - 1] 36 | } 37 | 38 | clear () { 39 | let list = wm.get(this) 40 | list.length = 0 41 | } 42 | 43 | size () { 44 | return this.top 45 | } 46 | 47 | output () { 48 | return wm.get(this) 49 | } 50 | 51 | isEmpty () { 52 | return wm.get(this).length === 0 53 | } 54 | } 55 | return Stack 56 | })() 57 | 58 | let s = new Stack() 59 | 60 | s.push(1, 2, 3, 4, 5) 61 | console.log(s.output()) // [ 1, 2, 3, 4, 5 ] 62 | -------------------------------------------------------------------------------- /source-learn/collect/template.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 模板编译函数 3 | */ 4 | 5 | let template = ` 6 |
      7 | <% for(let i=0; i < data.supplies.length; i++) { %> 8 |
    • <%= data.supplies[i] %>
    • 9 | <% } %> 10 |
    11 | `; 12 | 13 | function compile (template) { 14 | const evalExpr = /<%=(.+?)%>/g; 15 | const expr = /<%([\s\S]+?)%>/g; 16 | 17 | template = template 18 | .replace(evalExpr, '`); \n echo( $1 ); \n echo(`') 19 | .replace(expr, '`); \n $1 \n echo(`'); 20 | 21 | template = 'echo(`' + template + '`);'; 22 | 23 | let script = 24 | `(function parse(data){ 25 | let output = ""; 26 | 27 | function echo(html){ 28 | output += html; 29 | } 30 | 31 | ${ template} 32 | 33 | return output; 34 | })`; 35 | 36 | return script; 37 | } 38 | 39 | let parse = eval(compile(template)); 40 | document.querySelector('#app').innerHTML = parse({ supplies: ["broom", "mop", "cleaner"] }); 41 | -------------------------------------------------------------------------------- /source-learn/es6/es6.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /source-learn/es6/es6.js: -------------------------------------------------------------------------------- 1 | // map 循环 2 | const map = (f, array) => { 3 | const newArray = []; 4 | for (let i = 0; i < array.length; ++i) { 5 | newArray[i] = f(array[i]); 6 | } 7 | return newArray; 8 | } 9 | 10 | const filter = (f, array) => { 11 | const newArray = []; 12 | for (let i = 0; i < array.length; ++i) { 13 | if (f(array[i])) { 14 | newArray[array.length] = array[i]; 15 | } 16 | } 17 | return newArray; 18 | } 19 | 20 | const reduce = (f, start, array) => { 21 | var acc = start; 22 | for (var i = 0; i < array.length; ++i) { 23 | acc = f(array[i], acc); // f() takes 2 parameters 24 | } 25 | return acc; 26 | } 27 | const a = reduce((x,y) => x+y,0,[3,4,5]); 28 | console.log(a) 29 | -------------------------------------------------------------------------------- /source-learn/jQuery/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /source-learn/promise/demo.js: -------------------------------------------------------------------------------- 1 | function myPromise(constructor) { 2 | var self = this; 3 | self.status = "pending"; 4 | self.value = undefined; 5 | self.reason = undefined; 6 | function resolve(value) { 7 | if(self.status = "pending") { 8 | self.value = value; 9 | self.status = "resolved"; 10 | } 11 | } 12 | function reject(reason) { 13 | if(self.status = "pending") { 14 | self.reason = reason; 15 | self.status = "rejected"; 16 | } 17 | } 18 | try { 19 | constructor(resolve, reject); 20 | } catch(e) { 21 | reject(e); 22 | } 23 | } -------------------------------------------------------------------------------- /source-learn/promise/promise.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Promise 8 | 9 | 10 | 11 | 17 | 18 | -------------------------------------------------------------------------------- /source-learn/promise/promise.js: -------------------------------------------------------------------------------- 1 | var Promise = function() {}; 2 | 3 | var isPromise = function(value) { 4 | return value instanceof Promise; 5 | }; 6 | 7 | var defer = function() { 8 | var pending = [], 9 | value; 10 | var promise = new Promise(); // 声明promise对象 11 | promise.then = function(callback) { // 给promise对象增加then方法 12 | if (pending) { 13 | pending.push(callback); 14 | } else { 15 | callback(value); 16 | } 17 | }; 18 | return { // 给defer对象返回resolve和promise 19 | resolve: function(_value) { 20 | if (pending) { 21 | value = _value; // 在resolve事件里传参,是第几个就执行第几个 22 | for (var i = 0, ii = pending.length; i < ii; i++) { 23 | var callback = pending[i]; 24 | callback(value); 25 | } 26 | pending = undefined; 27 | } 28 | }, 29 | promise: promise 30 | }; 31 | }; -------------------------------------------------------------------------------- /source-learn/promise/v1.0_promise.js: -------------------------------------------------------------------------------- 1 | function myPromise(constructor) { 2 | let self = this; 3 | self.status = "pending"; // 定义状态改变前的初始状态 4 | self.value = undefined; // 定义状态为resolved的时候的状态 5 | self.reason = undefined; // 定义状态为rejected的时候的状态 6 | function resolve(value) { 7 | // 两个==="pending",保证了状态的改变是不可逆的 8 | if(self.status === "pending") { 9 | self.value = value; 10 | self.status = "resolved"; 11 | } 12 | } 13 | function reject(reason) { 14 | // 两个==="pending",保证了状态的改变是不可逆的 15 | if(self.status === "pending") { 16 | self.reason = reason; 17 | self.status = "rejected"; 18 | } 19 | } 20 | // 捕获构造异常 21 | try { 22 | constructor(resolve, reject); 23 | } catch(e) { 24 | reject(e); 25 | } 26 | } 27 | 28 | // 在myPromise的原型上定义链式调用的then方法: 29 | myPromise.prototype.then = function(onFullfilled, onRejected) { 30 | let self = this; 31 | switch (self.status) { 32 | case "resolved": 33 | onFullfilled(self.value); 34 | break; 35 | case "rejected": 36 | onRejected(self.value); 37 | break; 38 | default: 39 | } 40 | } 41 | 42 | // 但是这里myPromise无法处理异步的resolve.比如: 43 | var p = new myPromise(function(resolve,reject){setTimeout(function(){resolve(1)},1000)}); 44 | p.then(function(x){console.log(x)}) 45 | //无输出 -------------------------------------------------------------------------------- /source-learn/vue源码分析/demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/demo/observe.js: -------------------------------------------------------------------------------- 1 | const oldProto = Array.prototype; 2 | const _arrProto = Object.create(oldProto); 3 | 4 | ['pop', 'push', 'shift', 'unshift', 'splice'].forEach(methodName => { 5 | _arrProto[methodName] = function () { 6 | updateView() 7 | oldProto[methodName].call(this, ...arguments) 8 | } 9 | }) 10 | 11 | const defineReactive = (target, key, value) => { 12 | // 深度监听 13 | observer(value) 14 | 15 | Object.defineProperty(target, key, { 16 | get () { 17 | return value 18 | }, 19 | set (newVal) { 20 | if (newVal !== value) { 21 | observer(newVal) 22 | 23 | value = newVal 24 | updateView(newVal) 25 | } 26 | } 27 | }) 28 | } 29 | 30 | const observer = (target) => { 31 | // 不是对象或者数组 32 | if (typeof target !== 'object' || target === null) return target 33 | 34 | if (Array.isArray(target)) { 35 | console.log(target, target.prototype, target.__proto__) 36 | target.__proto__ = _arrProto 37 | } 38 | 39 | for (let key in target) { 40 | defineReactive(target, key, target[key]) 41 | } 42 | } 43 | 44 | const updateView = () => { 45 | console.log('更新视图') 46 | } 47 | 48 | const data = { 49 | name: 'liusixin', 50 | age: 18, 51 | info: { 52 | job: '前端' 53 | }, 54 | hobby: ['打球', '游泳', '上网'] 55 | } 56 | 57 | observer(data) 58 | console.log('数据', data) 59 | // data.info = { 60 | // job: '后端' 61 | // } 62 | // data.info.job = '全栈' 63 | data.hobby.push('泡妞') 64 | console.log('数据', data) 65 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/observe-demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Observe demo 9 | 10 | 11 | 12 |

    响应式 demo

    13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/observe-demo/proxy-demo.js: -------------------------------------------------------------------------------- 1 | // const data = { 2 | // name: 'zhangsan', 3 | // age: 20, 4 | // } 5 | const data = ['a', 'b', 'c'] 6 | 7 | const proxyData = new Proxy(data, { 8 | get(target, key, receiver) { 9 | // 只处理本身(非原型的)属性 10 | const ownKeys = Reflect.ownKeys(target) 11 | if (ownKeys.includes(key)) { 12 | console.log('get', key) // 监听 13 | } 14 | 15 | const result = Reflect.get(target, key, receiver) 16 | return result // 返回结果 17 | }, 18 | set(target, key, val, receiver) { 19 | // 重复的数据,不处理 20 | if (val === target[key]) { 21 | return true 22 | } 23 | 24 | const result = Reflect.set(target, key, val, receiver) 25 | console.log('set', key, val) 26 | // console.log('result', result) // true 27 | return result // 是否设置成功 28 | }, 29 | deleteProperty(target, key) { 30 | const result = Reflect.deleteProperty(target, key) 31 | console.log('delete property', key) 32 | // console.log('result', result) // true 33 | return result // 是否删除成功 34 | } 35 | }) 36 | 37 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vue 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/juejin/Vue流程图.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LesixCoder/Notes-And-Blog/99c1d2b5998f9fa7f211c0bd660f1dcac946dda9/source-learn/vue源码分析/source/juejin/Vue流程图.xmind -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/juejin/《Vuex状态管理的工作原理》.js: -------------------------------------------------------------------------------- 1 | let Vue; 2 | 3 | class Store { 4 | constructor () { 5 | this._vm = new Vue({ 6 | data: { 7 | $$state: this.state 8 | } 9 | }) 10 | } 11 | 12 | commit (type, payload, _options) { 13 | const entry = this._mutations[type]; 14 | entry.forEach(function commitIterator (handler) { 15 | handler(payload); 16 | }); 17 | } 18 | 19 | dispatch (type, payload) { 20 | const entry = this._actions[type]; 21 | 22 | return entry.length > 1 23 | ? Promise.all(entry.map(handler => handler(payload))) 24 | : entry[0](payload); 25 | } 26 | } 27 | 28 | function vuexInit () { 29 | const options = this.$options; 30 | if (options.store) { 31 | this.$store = options.store; 32 | } else { 33 | this.$store = options.parent.$store; 34 | } 35 | } 36 | 37 | export default install (_Vue) { 38 | Vue.mixin({ beforeCreate: vuexInit }); 39 | Vue = _Vue; 40 | } -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/juejin/《响应式系统的基本原理》.js: -------------------------------------------------------------------------------- 1 | function observer (value) { 2 | if (!value || (typeof value !== 'object')) { 3 | return; 4 | } 5 | 6 | Object.keys(value).forEach((key) => { 7 | defineReactive(value, key, value[key]); 8 | }); 9 | } 10 | 11 | function cb (val) { 12 | console.log("视图更新啦~", val); 13 | } 14 | 15 | function defineReactive (obj, key, val) { 16 | Object.defineProperty(obj, key, { 17 | enumerable: true, 18 | configurable: true, 19 | get: function reactiveGetter () { 20 | return val; 21 | }, 22 | set: function reactiveSetter (newVal) { 23 | if (newVal === val) return; 24 | val = newVal; 25 | cb(newVal); 26 | } 27 | }); 28 | } 29 | 30 | class Vue { 31 | constructor(options) { 32 | this._data = options.data; 33 | observer(this._data); 34 | } 35 | } 36 | 37 | let o = new Vue({ 38 | data: { 39 | test: "I am test." 40 | } 41 | }); 42 | o._data.test = "hello,test."; -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/juejin/《实现 Virtual DOM 下的一个 VNode 节点》.js: -------------------------------------------------------------------------------- 1 | class VNode { 2 | constructor (tag, data, children, text, elm) { 3 | this.tag = tag; 4 | this.data = data; 5 | this.children = children; 6 | this.text = text; 7 | this.elm = elm; 8 | } 9 | } 10 | 11 | function createEmptyVNode () { 12 | const node = new VNode(); 13 | node.text = ''; 14 | return node; 15 | } 16 | 17 | function createTextVNode (val) { 18 | return new VNode(undefined, undefined, undefined, String(val)); 19 | } 20 | 21 | function cloneVNode (node) { 22 | const cloneVnode = new VNode( 23 | node.tag, 24 | node.data, 25 | node.children, 26 | node.text, 27 | node.elm 28 | ); 29 | 30 | return cloneVnode; 31 | } -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-router-src/util/async.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | export function runQueue (queue: Array, fn: Function, cb: Function) { 4 | const step = index => { 5 | if (index >= queue.length) { 6 | cb() 7 | } else { 8 | if (queue[index]) { 9 | fn(queue[index], () => { 10 | step(index + 1) 11 | }) 12 | } else { 13 | step(index + 1) 14 | } 15 | } 16 | } 17 | step(0) 18 | } 19 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-router-src/util/dom.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | export const inBrowser = typeof window !== 'undefined' 4 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-router-src/util/params.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { warn } from './warn' 4 | import Regexp from 'path-to-regexp' 5 | 6 | // $flow-disable-line 7 | const regexpCompileCache: { 8 | [key: string]: Function 9 | } = Object.create(null) 10 | 11 | export function fillParams ( 12 | path: string, 13 | params: ?Object, 14 | routeMsg: string 15 | ): string { 16 | try { 17 | const filler = 18 | regexpCompileCache[path] || 19 | (regexpCompileCache[path] = Regexp.compile(path)) 20 | return filler(params || {}, { pretty: true }) 21 | } catch (e) { 22 | if (process.env.NODE_ENV !== 'production') { 23 | warn(false, `missing param for ${routeMsg}: ${e.message}`) 24 | } 25 | return '' 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-router-src/util/warn.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | export function assert (condition: any, message: string) { 4 | if (!condition) { 5 | throw new Error(`[vue-router] ${message}`) 6 | } 7 | } 8 | 9 | export function warn (condition: any, message: string) { 10 | if (process.env.NODE_ENV !== 'production' && !condition) { 11 | typeof console !== 'undefined' && console.warn(`[vue-router] ${message}`) 12 | } 13 | } 14 | 15 | export function isError (err: any): boolean { 16 | return Object.prototype.toString.call(err).indexOf('Error') > -1 17 | } 18 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/compiler/directives/bind.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | /*Github:https://github.com/answershuto*/ 3 | export default function bind (el: ASTElement, dir: ASTDirective) { 4 | el.wrapData = (code: string) => { 5 | return `_b(${code},'${el.tag}',${dir.value}${ 6 | dir.modifiers && dir.modifiers.prop ? ',true' : '' 7 | })` 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/compiler/directives/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import bind from './bind' 4 | import { noop } from 'shared/util' 5 | /*Github:https://github.com/answershuto*/ 6 | export default { 7 | bind, 8 | cloak: noop 9 | } 10 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/compiler/parser/entity-decoder.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | let decoder 4 | 5 | export function decode (html: string): string { 6 | decoder = decoder || document.createElement('div') 7 | decoder.innerHTML = html 8 | return decoder.textContent 9 | } 10 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/compiler/parser/text-parser.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { cached } from 'shared/util' 4 | import { parseFilters } from './filter-parser' 5 | 6 | const defaultTagRE = /\{\{((?:.|\n)+?)\}\}/g 7 | const regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g 8 | 9 | const buildRegex = cached(delimiters => { 10 | const open = delimiters[0].replace(regexEscapeRE, '\\$&') 11 | const close = delimiters[1].replace(regexEscapeRE, '\\$&') 12 | return new RegExp(open + '((?:.|\\n)+?)' + close, 'g') 13 | }) 14 | /*Github:https://github.com/answershuto*/ 15 | export function parseText ( 16 | text: string, 17 | delimiters?: [string, string] 18 | ): string | void { 19 | const tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE 20 | if (!tagRE.test(text)) { 21 | return 22 | } 23 | const tokens = [] 24 | let lastIndex = tagRE.lastIndex = 0 25 | let match, index 26 | while ((match = tagRE.exec(text))) { 27 | index = match.index 28 | // push text token 29 | if (index > lastIndex) { 30 | tokens.push(JSON.stringify(text.slice(lastIndex, index))) 31 | } 32 | // tag token 33 | const exp = parseFilters(match[1].trim()) 34 | tokens.push(`_s(${exp})`) 35 | lastIndex = index + match[0].length 36 | } 37 | if (lastIndex < text.length) { 38 | tokens.push(JSON.stringify(text.slice(lastIndex))) 39 | } 40 | return tokens.join('+') 41 | } 42 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/components/index.js: -------------------------------------------------------------------------------- 1 | import KeepAlive from './keep-alive' 2 | 3 | export default { 4 | KeepAlive 5 | } 6 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/global-api/assets.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import config from '../config' 4 | import { ASSET_TYPES } from 'shared/constants' 5 | import { warn, isPlainObject } from '../util/index' 6 | 7 | export function initAssetRegisters (Vue: GlobalAPI) { 8 | /** 9 | * Create asset registration methods. 10 | */ 11 | ASSET_TYPES.forEach(type => { 12 | Vue[type] = function ( 13 | id: string, 14 | definition: Function | Object 15 | ): Function | Object | void { 16 | if (!definition) { 17 | return this.options[type + 's'][id] 18 | } else { 19 | /* istanbul ignore if */ 20 | if (process.env.NODE_ENV !== 'production') { 21 | if (type === 'component' && config.isReservedTag(id)) { 22 | warn( 23 | 'Do not use built-in or reserved HTML elements as component ' + 24 | 'id: ' + id 25 | ) 26 | } 27 | } 28 | if (type === 'component' && isPlainObject(definition)) { 29 | definition.name = definition.name || id 30 | definition = this.options._base.extend(definition) 31 | } 32 | if (type === 'directive' && typeof definition === 'function') { 33 | definition = { bind: definition, update: definition } 34 | } 35 | this.options[type + 's'][id] = definition 36 | return definition 37 | } 38 | } 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/global-api/mixin.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { mergeOptions } from '../util/index' 4 | 5 | /*初始化mixin*/ 6 | export function initMixin (Vue: GlobalAPI) { 7 | /*https://cn.vuejs.org/v2/api/#Vue-mixin*/ 8 | Vue.mixin = function (mixin: Object) { 9 | /*mergeOptions合并optiuons*/ 10 | this.options = mergeOptions(this.options, mixin) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/global-api/use.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { toArray } from '../util/index' 4 | 5 | /*初始化use*/ 6 | export function initUse (Vue: GlobalAPI) { 7 | /*https://cn.vuejs.org/v2/api/#Vue-use*/ 8 | Vue.use = function (plugin: Function | Object) { 9 | /* istanbul ignore if */ 10 | /*标识位检测该插件是否已经被安装*/ 11 | if (plugin.installed) { 12 | return 13 | } 14 | // additional parameters 15 | const args = toArray(arguments, 1) 16 | /*a*/ 17 | args.unshift(this) 18 | if (typeof plugin.install === 'function') { 19 | /*install执行插件安装*/ 20 | plugin.install.apply(plugin, args) 21 | } else if (typeof plugin === 'function') { 22 | plugin.apply(null, args) 23 | } 24 | plugin.installed = true 25 | return this 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/index.js: -------------------------------------------------------------------------------- 1 | import Vue from './instance/index' 2 | import { initGlobalAPI } from './global-api/index' 3 | import { isServerRendering } from 'core/util/env' 4 | 5 | initGlobalAPI(Vue) 6 | 7 | Object.defineProperty(Vue.prototype, '$isServer', { 8 | get: isServerRendering 9 | }) 10 | 11 | Vue.version = '__VERSION__' 12 | 13 | export default Vue 14 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/instance/index.js: -------------------------------------------------------------------------------- 1 | import { initMixin } from './init' 2 | import { stateMixin } from './state' 3 | import { renderMixin } from './render' 4 | import { eventsMixin } from './events' 5 | import { lifecycleMixin } from './lifecycle' 6 | import { warn } from '../util/index' 7 | /*Github:https://github.com/answershuto*/ 8 | function Vue (options) { 9 | if (process.env.NODE_ENV !== 'production' && 10 | !(this instanceof Vue)) { 11 | warn('Vue is a constructor and should be called with the `new` keyword') 12 | } 13 | /*初始化*/ 14 | this._init(options) 15 | } 16 | 17 | initMixin(Vue) 18 | stateMixin(Vue) 19 | eventsMixin(Vue) 20 | lifecycleMixin(Vue) 21 | renderMixin(Vue) 22 | 23 | export default Vue 24 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/instance/render-helpers/bind-object-props.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import config from 'core/config' 4 | import { isObject, warn, toObject } from 'core/util/index' 5 | 6 | /** 7 | * Runtime helper for merging v-bind="object" into a VNode's data. 8 | */ 9 | /*合并v-bind指令到VNode中*/ 10 | export function bindObjectProps ( 11 | data: any, 12 | tag: string, 13 | value: any, 14 | asProp?: boolean 15 | ): VNodeData { 16 | if (value) { 17 | if (!isObject(value)) { 18 | /*v-bind必须提供一个Object或者Array作为参数*/ 19 | process.env.NODE_ENV !== 'production' && warn( 20 | 'v-bind without argument expects an Object or Array value', 21 | this 22 | ) 23 | } else { 24 | if (Array.isArray(value)) { 25 | /*合并Array数组中的每一个对象到一个新的Object中*/ 26 | value = toObject(value) 27 | } 28 | let hash 29 | for (const key in value) { 30 | if (key === 'class' || key === 'style') { 31 | hash = data 32 | } else { 33 | const type = data.attrs && data.attrs.type 34 | hash = asProp || config.mustUseProp(tag, type, key) 35 | ? data.domProps || (data.domProps = {}) 36 | : data.attrs || (data.attrs = {}) 37 | } 38 | if (!(key in hash)) { 39 | hash[key] = value[key] 40 | } 41 | } 42 | } 43 | } 44 | return data 45 | } 46 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/instance/render-helpers/check-keycodes.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import config from 'core/config' 4 | 5 | /** 6 | * Runtime helper for checking keyCodes from config. 7 | */ 8 | /*从config配置中检查eventKeyCode是否存在*/ 9 | export function checkKeyCodes ( 10 | eventKeyCode: number, 11 | key: string, 12 | builtInAlias: number | Array | void 13 | ): boolean { 14 | const keyCodes = config.keyCodes[key] || builtInAlias 15 | if (Array.isArray(keyCodes)) { 16 | return keyCodes.indexOf(eventKeyCode) === -1 17 | } else { 18 | return keyCodes !== eventKeyCode 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/instance/render-helpers/render-list.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { isObject } from 'core/util/index' 4 | 5 | /** 6 | * Runtime helper for rendering v-for lists. 7 | */ 8 | /*处理v-for列表渲染*/ 9 | export function renderList ( 10 | val: any, 11 | render: () => VNode 12 | ): ?Array { 13 | /*根据类型循环render*/ 14 | let ret: ?Array, i, l, keys, key 15 | if (Array.isArray(val) || typeof val === 'string') { 16 | ret = new Array(val.length) 17 | for (i = 0, l = val.length; i < l; i++) { 18 | ret[i] = render(val[i], i) 19 | } 20 | } else if (typeof val === 'number') { 21 | ret = new Array(val) 22 | for (i = 0; i < val; i++) { 23 | ret[i] = render(i + 1, i) 24 | } 25 | } else if (isObject(val)) { 26 | keys = Object.keys(val) 27 | ret = new Array(keys.length) 28 | for (i = 0, l = keys.length; i < l; i++) { 29 | key = keys[i] 30 | ret[i] = render(val[key], key, i) 31 | } 32 | } 33 | return ret 34 | } 35 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/instance/render-helpers/render-slot.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { extend, warn } from 'core/util/index' 4 | 5 | /** 6 | * Runtime helper for rendering 7 | */ 8 | /*处理slot的渲染*/ 9 | export function renderSlot ( 10 | name: string, 11 | fallback: ?Array, 12 | props: ?Object, 13 | bindObject: ?Object 14 | ): ?Array { 15 | const scopedSlotFn = this.$scopedSlots[name] 16 | if (scopedSlotFn) { // scoped slot 17 | props = props || {} 18 | if (bindObject) { 19 | extend(props, bindObject) 20 | } 21 | return scopedSlotFn(props) || fallback 22 | } else { 23 | const slotNodes = this.$slots[name] 24 | // warn duplicate slot usage 25 | if (slotNodes && process.env.NODE_ENV !== 'production') { 26 | slotNodes._rendered && warn( 27 | `Duplicate presence of slot "${name}" found in the same render tree ` + 28 | `- this will likely cause render errors.`, 29 | this 30 | ) 31 | slotNodes._rendered = true 32 | } 33 | return slotNodes || fallback 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/instance/render-helpers/resolve-filter.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { identity, resolveAsset } from 'core/util/index' 4 | 5 | /** 6 | * Runtime helper for resolving filters 7 | */ 8 | /*处理filters*/ 9 | export function resolveFilter (id: string): Function { 10 | return resolveAsset(this.$options, 'filters', id, true) || identity 11 | } 12 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/util/error.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import config from '../config' 4 | import { warn } from './debug' 5 | import { inBrowser } from './env' 6 | 7 | export function handleError (err: Error, vm: any, info: string) { 8 | if (config.errorHandler) { 9 | config.errorHandler.call(null, err, vm, info) 10 | } else { 11 | if (process.env.NODE_ENV !== 'production') { 12 | warn(`Error in ${info}: "${err.toString()}"`, vm) 13 | } 14 | /* istanbul ignore else */ 15 | if (inBrowser && typeof console !== 'undefined') { 16 | console.error(err) 17 | } else { 18 | throw err 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/util/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | export * from 'shared/util' 4 | export * from './lang' 5 | export * from './env' 6 | export * from './options' 7 | export * from './debug' 8 | export * from './props' 9 | export * from './error' 10 | export { defineReactive } from '../observer/index' 11 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/util/lang.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | export const emptyObject = Object.freeze({}) 4 | 5 | /** 6 | * Check if a string starts with $ or _ 7 | */ 8 | export function isReserved (str: string): boolean { 9 | const c = (str + '').charCodeAt(0) 10 | return c === 0x24 || c === 0x5F 11 | } 12 | 13 | /** 14 | * Define a property. 15 | */ 16 | export function def (obj: Object, key: string, val: any, enumerable?: boolean) { 17 | Object.defineProperty(obj, key, { 18 | value: val, 19 | enumerable: !!enumerable, 20 | writable: true, 21 | configurable: true 22 | }) 23 | } 24 | 25 | /** 26 | * Parse simple path. 27 | */ 28 | const bailRE = /[^\w.$]/ 29 | export function parsePath (path: string): any { 30 | if (bailRE.test(path)) { 31 | return 32 | } 33 | const segments = path.split('.') 34 | return function (obj) { 35 | for (let i = 0; i < segments.length; i++) { 36 | if (!obj) return 37 | obj = obj[segments[i]] 38 | } 39 | return obj 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/util/perf.js: -------------------------------------------------------------------------------- 1 | import { inBrowser } from './env' 2 | 3 | export let mark 4 | export let measure 5 | 6 | if (process.env.NODE_ENV !== 'production') { 7 | const perf = inBrowser && window.performance 8 | /* istanbul ignore if */ 9 | if ( 10 | perf && 11 | perf.mark && 12 | perf.measure && 13 | perf.clearMarks && 14 | perf.clearMeasures 15 | ) { 16 | mark = tag => perf.mark(tag) 17 | measure = (name, startTag, endTag) => { 18 | perf.measure(name, startTag, endTag) 19 | perf.clearMarks(startTag) 20 | perf.clearMarks(endTag) 21 | perf.clearMeasures(name) 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/vdom/helpers/get-first-component-child.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { isDef } from 'shared/util' 4 | 5 | /* 获取第一个子组件 */ 6 | export function getFirstComponentChild (children: ?Array): ?VNode { 7 | if (Array.isArray(children)) { 8 | for (let i = 0; i < children.length; i++) { 9 | const c = children[i] 10 | if (isDef(c) && isDef(c.componentOptions)) { 11 | return c 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/vdom/helpers/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | export * from './merge-hook' 4 | export * from './extract-props' 5 | export * from './update-listeners' 6 | export * from './normalize-children' 7 | export * from './resolve-async-component' 8 | export * from './get-first-component-child' 9 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/vdom/helpers/merge-hook.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { createFnInvoker } from './update-listeners' 4 | import { remove, isDef, isUndef, isTrue } from 'shared/util' 5 | 6 | export function mergeVNodeHook (def: Object, hookKey: string, hook: Function) { 7 | let invoker 8 | const oldHook = def[hookKey] 9 | 10 | function wrappedHook () { 11 | hook.apply(this, arguments) 12 | // important: remove merged hook to ensure it's called only once 13 | // and prevent memory leak 14 | remove(invoker.fns, wrappedHook) 15 | } 16 | 17 | if (isUndef(oldHook)) { 18 | // no existing hook 19 | invoker = createFnInvoker([wrappedHook]) 20 | } else { 21 | /* istanbul ignore if */ 22 | if (isDef(oldHook.fns) && isTrue(oldHook.merged)) { 23 | // already a merged invoker 24 | invoker = oldHook 25 | invoker.fns.push(wrappedHook) 26 | } else { 27 | // existing plain hook 28 | invoker = createFnInvoker([oldHook, wrappedHook]) 29 | } 30 | } 31 | 32 | invoker.merged = true 33 | def[hookKey] = invoker 34 | } 35 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/vdom/modules/index.js: -------------------------------------------------------------------------------- 1 | import directives from './directives' 2 | import ref from './ref' 3 | 4 | export default [ 5 | ref, 6 | directives 7 | ] 8 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/core/vdom/modules/ref.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { remove } from 'shared/util' 4 | 5 | export default { 6 | create (_: any, vnode: VNodeWithData) { 7 | registerRef(vnode) 8 | }, 9 | update (oldVnode: VNodeWithData, vnode: VNodeWithData) { 10 | if (oldVnode.data.ref !== vnode.data.ref) { 11 | registerRef(oldVnode, true) 12 | registerRef(vnode) 13 | } 14 | }, 15 | destroy (vnode: VNodeWithData) { 16 | registerRef(vnode, true) 17 | } 18 | } 19 | 20 | /*注册一个ref(即在$refs中添加或者删除对应的Dom实例),isRemoval代表是增加还是移除,*/ 21 | export function registerRef (vnode: VNodeWithData, isRemoval: ?boolean) { 22 | const key = vnode.data.ref 23 | if (!key) return 24 | 25 | const vm = vnode.context 26 | const ref = vnode.componentInstance || vnode.elm 27 | const refs = vm.$refs 28 | if (isRemoval) { 29 | /*移除一个ref*/ 30 | if (Array.isArray(refs[key])) { 31 | remove(refs[key], ref) 32 | } else if (refs[key] === ref) { 33 | refs[key] = undefined 34 | } 35 | } else { 36 | /*增加一个ref*/ 37 | if (vnode.data.refInFor) { 38 | /*如果是在一个for循环中,则refs中key对应的是一个数组,里面存放了所有ref指向的Dom实例*/ 39 | if (Array.isArray(refs[key]) && refs[key].indexOf(ref) < 0) { 40 | refs[key].push(ref) 41 | } else { 42 | refs[key] = [ref] 43 | } 44 | } else { 45 | /*不在一个for循环中则直接放入refs即可,ref指向Dom实例*/ 46 | refs[key] = ref 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/compiler.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | export { parseComponent } from 'sfc/parser' 4 | export { compile, compileToFunctions } from './compiler/index' 5 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/compiler/directives/html.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { addProp } from 'compiler/helpers' 4 | /*Github:https://github.com/answershuto*/ 5 | export default function html (el: ASTElement, dir: ASTDirective) { 6 | if (dir.value) { 7 | addProp(el, 'innerHTML', `_s(${dir.value})`) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/compiler/directives/index.js: -------------------------------------------------------------------------------- 1 | import model from './model' 2 | import text from './text' 3 | import html from './html' 4 | 5 | export default { 6 | model, 7 | text, 8 | html 9 | } 10 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/compiler/directives/text.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { addProp } from 'compiler/helpers' 4 | /*Github:https://github.com/answershuto*/ 5 | export default function text (el: ASTElement, dir: ASTDirective) { 6 | if (dir.value) { 7 | addProp(el, 'textContent', `_s(${dir.value})`) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/compiler/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { isUnaryTag, canBeLeftOpenTag } from './util' 4 | import { genStaticKeys } from 'shared/util' 5 | import { createCompiler } from 'compiler/index' 6 | 7 | import modules from './modules/index' 8 | import directives from './directives/index' 9 | 10 | import { 11 | isPreTag, 12 | mustUseProp, 13 | isReservedTag, 14 | getTagNamespace 15 | } from '../util/index' 16 | 17 | export const baseOptions: CompilerOptions = { 18 | expectHTML: true, 19 | modules, 20 | directives, 21 | isPreTag, 22 | isUnaryTag, 23 | mustUseProp, 24 | canBeLeftOpenTag, 25 | isReservedTag, 26 | getTagNamespace, 27 | staticKeys: genStaticKeys(modules) 28 | } 29 | 30 | /*这里会根据不同平台传递不同的baseOptions创建编译器*/ 31 | const { compile, compileToFunctions } = createCompiler(baseOptions) 32 | export { compile, compileToFunctions } 33 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/compiler/modules/class.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { parseText } from 'compiler/parser/text-parser' 4 | import { 5 | getAndRemoveAttr, 6 | getBindingAttr, 7 | baseWarn 8 | } from 'compiler/helpers' 9 | 10 | function transformNode (el: ASTElement, options: CompilerOptions) { 11 | const warn = options.warn || baseWarn 12 | const staticClass = getAndRemoveAttr(el, 'class') 13 | if (process.env.NODE_ENV !== 'production' && staticClass) { 14 | const expression = parseText(staticClass, options.delimiters) 15 | if (expression) { 16 | warn( 17 | `class="${staticClass}": ` + 18 | 'Interpolation inside attributes has been removed. ' + 19 | 'Use v-bind or the colon shorthand instead. For example, ' + 20 | 'instead of
    , use
    .' 21 | ) 22 | } 23 | } 24 | if (staticClass) { 25 | el.staticClass = JSON.stringify(staticClass) 26 | } 27 | const classBinding = getBindingAttr(el, 'class', false /* getStatic */) 28 | if (classBinding) { 29 | el.classBinding = classBinding 30 | } 31 | } 32 | 33 | function genData (el: ASTElement): string { 34 | let data = '' 35 | if (el.staticClass) { 36 | data += `staticClass:${el.staticClass},` 37 | } 38 | if (el.classBinding) { 39 | data += `class:${el.classBinding},` 40 | } 41 | return data 42 | } 43 | 44 | export default { 45 | staticKeys: ['staticClass'], 46 | transformNode, 47 | genData 48 | } 49 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/compiler/modules/index.js: -------------------------------------------------------------------------------- 1 | import klass from './class' 2 | import style from './style' 3 | 4 | export default [ 5 | klass, 6 | style 7 | ] 8 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/compiler/util.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { makeMap } from 'shared/util' 4 | /*Github:https://github.com/answershuto*/ 5 | export const isUnaryTag = makeMap( 6 | 'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' + 7 | 'link,meta,param,source,track,wbr' 8 | ) 9 | 10 | // Elements that you can, intentionally, leave open 11 | // (and which close themselves) 12 | export const canBeLeftOpenTag = makeMap( 13 | 'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source' 14 | ) 15 | /*Github:https://github.com/answershuto*/ 16 | // HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3 17 | // Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content 18 | export const isNonPhrasingTag = makeMap( 19 | 'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' + 20 | 'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' + 21 | 'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' + 22 | 'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' + 23 | 'title,tr,track' 24 | ) 25 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/runtime.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import Vue from './runtime/index' 4 | /*Github:https://github.com/answershuto*/ 5 | export default Vue 6 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/runtime/components/index.js: -------------------------------------------------------------------------------- 1 | import Transition from './transition' 2 | import TransitionGroup from './transition-group' 3 | 4 | export default { 5 | Transition, 6 | TransitionGroup 7 | } 8 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/runtime/directives/index.js: -------------------------------------------------------------------------------- 1 | import model from './model' 2 | import show from './show' 3 | 4 | export default { 5 | model, 6 | show 7 | } 8 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/runtime/modules/class.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { 4 | isDef, 5 | isUndef 6 | } from 'shared/util' 7 | 8 | import { 9 | concat, 10 | stringifyClass, 11 | genClassForVnode 12 | } from 'web/util/index' 13 | 14 | /*更新VNode的class*/ 15 | function updateClass (oldVnode: any, vnode: any) { 16 | const el = vnode.elm 17 | const data: VNodeData = vnode.data 18 | const oldData: VNodeData = oldVnode.data 19 | if ( 20 | isUndef(data.staticClass) && 21 | isUndef(data.class) && ( 22 | isUndef(oldData) || ( 23 | isUndef(oldData.staticClass) && 24 | isUndef(oldData.class) 25 | ) 26 | ) 27 | ) { 28 | return 29 | } 30 | 31 | let cls = genClassForVnode(vnode) 32 | 33 | // handle transition classes 34 | const transitionClass = el._transitionClasses 35 | if (isDef(transitionClass)) { 36 | cls = concat(cls, stringifyClass(transitionClass)) 37 | } 38 | 39 | // set the class 40 | if (cls !== el._prevClass) { 41 | el.setAttribute('class', cls) 42 | el._prevClass = cls 43 | } 44 | } 45 | 46 | export default { 47 | create: updateClass, 48 | update: updateClass 49 | } 50 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/runtime/modules/index.js: -------------------------------------------------------------------------------- 1 | import attrs from './attrs' 2 | import klass from './class' 3 | import events from './events' 4 | import domProps from './dom-props' 5 | import style from './style' 6 | import transition from './transition' 7 | 8 | export default [ 9 | attrs, 10 | klass, 11 | events, 12 | domProps, 13 | style, 14 | transition 15 | ] 16 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/runtime/patch.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import * as nodeOps from 'web/runtime/node-ops' 4 | import { createPatchFunction } from 'core/vdom/patch' 5 | import baseModules from 'core/vdom/modules/index' 6 | import platformModules from 'web/runtime/modules/index' 7 | 8 | // the directive module should be applied last, after all 9 | // built-in modules have been applied. 10 | const modules = platformModules.concat(baseModules) 11 | 12 | export const patch: Function = createPatchFunction({ nodeOps, modules }) 13 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/server-renderer.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | process.env.VUE_ENV = 'server' 4 | 5 | import modules from './server/modules/index' 6 | import baseDirectives from './server/directives/index' 7 | import { isUnaryTag, canBeLeftOpenTag } from './compiler/util' 8 | 9 | import { createRenderer as _createRenderer } from 'server/create-renderer' 10 | import { createBundleRendererCreator } from 'server/bundle-renderer/create-bundle-renderer' 11 | 12 | export function createRenderer (options?: Object = {}): { 13 | renderToString: Function, 14 | renderToStream: Function 15 | } { 16 | return _createRenderer(Object.assign({}, options, { 17 | isUnaryTag, 18 | canBeLeftOpenTag, 19 | modules, 20 | // user can provide server-side implementations for custom directives 21 | // when creating the renderer. 22 | directives: Object.assign(baseDirectives, options.directives) 23 | })) 24 | } 25 | 26 | export const createBundleRenderer = createBundleRendererCreator(createRenderer) 27 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/server/directives/index.js: -------------------------------------------------------------------------------- 1 | import show from './show' 2 | 3 | export default { 4 | show 5 | } 6 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/server/directives/show.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | /*Github:https://github.com/answershuto*/ 3 | export default function show (node: VNodeWithData, dir: VNodeDirective) { 4 | if (!dir.value) { 5 | const style: any = node.data.style || (node.data.style = {}) 6 | style.display = 'none' 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/server/modules/attrs.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { escape } from 'he' 4 | 5 | import { 6 | isDef, 7 | isUndef 8 | } from 'shared/util' 9 | 10 | import { 11 | isBooleanAttr, 12 | isEnumeratedAttr, 13 | isFalsyAttrValue 14 | } from 'web/util/attrs' 15 | 16 | export default function renderAttrs (node: VNodeWithData): string { 17 | let attrs = node.data.attrs 18 | let res = '' 19 | 20 | let parent = node.parent 21 | while (isDef(parent)) { 22 | if (isDef(parent.data) && isDef(parent.data.attrs)) { 23 | attrs = Object.assign({}, attrs, parent.data.attrs) 24 | } 25 | parent = parent.parent 26 | } 27 | 28 | if (isUndef(attrs)) { 29 | return res 30 | } 31 | 32 | for (const key in attrs) { 33 | if (key === 'style') { 34 | // leave it to the style module 35 | continue 36 | } 37 | res += renderAttr(key, attrs[key]) 38 | } 39 | return res 40 | } 41 | 42 | export function renderAttr (key: string, value: string): string { 43 | if (isBooleanAttr(key)) { 44 | if (!isFalsyAttrValue(value)) { 45 | return ` ${key}="${key}"` 46 | } 47 | } else if (isEnumeratedAttr(key)) { 48 | return ` ${key}="${isFalsyAttrValue(value) || value === 'false' ? 'false' : 'true'}"` 49 | } else if (!isFalsyAttrValue(value)) { 50 | return ` ${key}="${typeof value === 'string' ? escape(value) : value}"` 51 | } 52 | return '' 53 | } 54 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/server/modules/class.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { escape } from 'he' 4 | import { genClassForVnode } from 'web/util/index' 5 | 6 | export default function renderClass (node: VNodeWithData): ?string { 7 | const classList = genClassForVnode(node) 8 | if (classList !== '') { 9 | return ` class="${escape(classList)}"` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/server/modules/dom-props.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import VNode from 'core/vdom/vnode' 4 | import { renderAttr } from './attrs' 5 | import { isDef, isUndef } from 'shared/util' 6 | import { propsToAttrMap, isRenderableAttr } from '../util' 7 | 8 | export default function renderDOMProps (node: VNodeWithData): string { 9 | let props = node.data.domProps 10 | let res = '' 11 | 12 | let parent = node.parent 13 | while (isDef(parent)) { 14 | if (parent.data && parent.data.domProps) { 15 | props = Object.assign({}, props, parent.data.domProps) 16 | } 17 | parent = parent.parent 18 | } 19 | 20 | if (isUndef(props)) { 21 | return res 22 | } 23 | 24 | const attrs = node.data.attrs 25 | for (const key in props) { 26 | if (key === 'innerHTML') { 27 | setText(node, props[key], true) 28 | } else if (key === 'textContent') { 29 | setText(node, props[key], false) 30 | } else { 31 | const attr = propsToAttrMap[key] || key.toLowerCase() 32 | if (isRenderableAttr(attr) && 33 | // avoid rendering double-bound props/attrs twice 34 | !(isDef(attrs) && isDef(attrs[attr]))) { 35 | res += renderAttr(attr, props[key]) 36 | } 37 | } 38 | } 39 | return res 40 | } 41 | 42 | function setText (node, text, raw) { 43 | const child = new VNode(undefined, undefined, undefined, text) 44 | child.raw = raw 45 | node.children = [child] 46 | } 47 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/server/modules/index.js: -------------------------------------------------------------------------------- 1 | import attrs from './attrs' 2 | import domProps from './dom-props' 3 | import klass from './class' 4 | import style from './style' 5 | 6 | export default [ 7 | attrs, 8 | domProps, 9 | klass, 10 | style 11 | ] 12 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/server/modules/style.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { escape } from 'he' 4 | import { hyphenate } from 'shared/util' 5 | import { getStyle } from 'web/util/style' 6 | 7 | function genStyleText (vnode: VNode): string { 8 | let styleText = '' 9 | const style = getStyle(vnode, false) 10 | for (const key in style) { 11 | const value = style[key] 12 | const hyphenatedKey = hyphenate(key) 13 | if (Array.isArray(value)) { 14 | for (let i = 0, len = value.length; i < len; i++) { 15 | styleText += `${hyphenatedKey}:${value[i]};` 16 | } 17 | } else { 18 | styleText += `${hyphenatedKey}:${value};` 19 | } 20 | } 21 | return styleText 22 | } 23 | 24 | export default function renderStyle (vnode: VNodeWithData): ?string { 25 | const styleText = genStyleText(vnode) 26 | if (styleText !== '') { 27 | return ` style=${JSON.stringify(escape(styleText))}` 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/util/compat.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { inBrowser } from 'core/util/index' 4 | 5 | // check whether current browser encodes a char inside attribute values 6 | function shouldDecode (content: string, encoded: string): boolean { 7 | const div = document.createElement('div') 8 | div.innerHTML = `
    ` 9 | return div.innerHTML.indexOf(encoded) > 0 10 | } 11 | 12 | // #3663 13 | // IE encodes newlines inside attribute values while other browsers don't 14 | export const shouldDecodeNewlines = inBrowser ? shouldDecode('\n', ' ') : false 15 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/web/util/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { warn } from 'core/util/index' 4 | 5 | export * from './attrs' 6 | export * from './class' 7 | export * from './element' 8 | 9 | /** 10 | * Query an element selector if it's not an element already. 11 | */ 12 | /*返回一个元素的DOM实例对象*/ 13 | export function query (el: string | Element): Element { 14 | if (typeof el === 'string') { 15 | const selected = document.querySelector(el) 16 | if (!selected) { 17 | process.env.NODE_ENV !== 'production' && warn( 18 | 'Cannot find element: ' + el 19 | ) 20 | return document.createElement('div') 21 | } 22 | return selected 23 | } else { 24 | return el 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/compiler.js: -------------------------------------------------------------------------------- 1 | export { compile } from 'weex/compiler/index' 2 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/compiler/directives/index.js: -------------------------------------------------------------------------------- 1 | import model from './model' 2 | 3 | export default { 4 | model 5 | } 6 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/compiler/directives/model.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { addHandler, addAttr } from 'compiler/helpers' 4 | import { genComponentModel, genAssignmentCode } from 'compiler/directives/model' 5 | 6 | export default function model ( 7 | el: ASTElement, 8 | dir: ASTDirective, 9 | _warn: Function 10 | ): ?boolean { 11 | if (el.tag === 'input' || el.tag === 'textarea') { 12 | genDefaultModel(el, dir.value, dir.modifiers) 13 | } else { 14 | genComponentModel(el, dir.value, dir.modifiers) 15 | } 16 | } 17 | 18 | function genDefaultModel ( 19 | el: ASTElement, 20 | value: string, 21 | modifiers: ?ASTModifiers 22 | ): ?boolean { 23 | const { lazy, trim, number } = modifiers || {} 24 | const event = lazy ? 'change' : 'input' 25 | 26 | let valueExpression = `$event.target.attr.value${trim ? '.trim()' : ''}` 27 | if (number) { 28 | valueExpression = `_n(${valueExpression})` 29 | } 30 | 31 | const code = genAssignmentCode(value, valueExpression) 32 | addAttr(el, 'value', `(${value})`) 33 | addHandler(el, event, code, null, true) 34 | } 35 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/compiler/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { genStaticKeys } from 'shared/util' 4 | import { createCompiler } from 'compiler/index' 5 | 6 | import modules from './modules/index' 7 | import directives from './directives/index' 8 | 9 | import { 10 | isUnaryTag, 11 | mustUseProp, 12 | isReservedTag, 13 | canBeLeftOpenTag, 14 | getTagNamespace 15 | } from '../util/index' 16 | 17 | export const baseOptions: CompilerOptions = { 18 | modules, 19 | directives, 20 | isUnaryTag, 21 | mustUseProp, 22 | canBeLeftOpenTag, 23 | isReservedTag, 24 | getTagNamespace, 25 | preserveWhitespace: false, 26 | staticKeys: genStaticKeys(modules) 27 | } 28 | 29 | const { compile, compileToFunctions } = createCompiler(baseOptions) 30 | export { compile, compileToFunctions } 31 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/compiler/modules/append.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | function preTransformNode (el: ASTElement, options: CompilerOptions) { 4 | if (el.tag === 'cell' && !el.attrsList.some(item => item.name === 'append')) { 5 | el.attrsMap.append = 'tree' 6 | el.attrsList.push({ name: 'append', value: 'tree' }) 7 | } 8 | if (el.attrsMap.append === 'tree') { 9 | el.appendAsTree = true 10 | } 11 | } 12 | 13 | function genData (el: ASTElement): string { 14 | return el.appendAsTree ? `appendAsTree:true,` : '' 15 | } 16 | 17 | export default { 18 | staticKeys: ['appendAsTree'], 19 | preTransformNode, 20 | genData 21 | } 22 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/compiler/modules/index.js: -------------------------------------------------------------------------------- 1 | import klass from './class' 2 | import style from './style' 3 | import props from './props' 4 | import append from './append' 5 | 6 | export default [ 7 | klass, 8 | style, 9 | props, 10 | append 11 | ] 12 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/compiler/modules/props.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { cached, camelize } from 'shared/util' 4 | 5 | const normalize = cached(camelize) 6 | 7 | function normalizeKeyName (str: string) : string { 8 | if (str.match(/^v\-/)) { 9 | return str.replace(/(v-[a-z\-]+\:)([a-z\-]+)$/i, ($, directive, prop) => { 10 | return directive + normalize(prop) 11 | }) 12 | } 13 | return normalize(str) 14 | } 15 | 16 | function transformNode (el: ASTElement, options: CompilerOptions) { 17 | if (Array.isArray(el.attrsList)) { 18 | el.attrsList.forEach(attr => { 19 | if (attr.name && attr.name.match(/\-/)) { 20 | const realName = normalizeKeyName(attr.name) 21 | if (el.attrsMap) { 22 | el.attrsMap[realName] = el.attrsMap[attr.name] 23 | delete el.attrsMap[attr.name] 24 | } 25 | attr.name = realName 26 | } 27 | }) 28 | } 29 | } 30 | export default { 31 | transformNode 32 | } 33 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/runtime-factory.js: -------------------------------------------------------------------------------- 1 | // this entry is built and wrapped with a factory function 2 | // used to generate a fresh copy of Vue for every Weex instance. 3 | 4 | import Vue from './runtime/index' 5 | 6 | exports.Vue = Vue 7 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/runtime/components/index.js: -------------------------------------------------------------------------------- 1 | import Transition from './transition' 2 | import TransitionGroup from './transition-group' 3 | 4 | export default { 5 | Transition, 6 | TransitionGroup 7 | } 8 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/runtime/components/transition.js: -------------------------------------------------------------------------------- 1 | // reuse same transition component logic from web 2 | export { 3 | transitionProps, 4 | extractTransitionData 5 | } from 'web/runtime/components/transition' 6 | 7 | import Transition from 'web/runtime/components/transition' 8 | 9 | export default Transition 10 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/runtime/directives/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | } 3 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/runtime/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import Vue from 'core/index' 4 | import { patch } from 'weex/runtime/patch' 5 | import { mountComponent } from 'core/instance/lifecycle' 6 | import platformDirectives from 'weex/runtime/directives/index' 7 | import platformComponents from 'weex/runtime/components/index' 8 | 9 | import { 10 | query, 11 | mustUseProp, 12 | isReservedTag, 13 | isUnknownElement 14 | } from 'weex/util/index' 15 | 16 | // install platform specific utils 17 | Vue.config.mustUseProp = mustUseProp 18 | Vue.config.isReservedTag = isReservedTag 19 | Vue.config.isUnknownElement = isUnknownElement 20 | 21 | // install platform runtime directives and components 22 | Vue.options.directives = platformDirectives 23 | Vue.options.components = platformComponents 24 | 25 | // install platform patch function 26 | Vue.prototype.__patch__ = patch 27 | 28 | // wrap mount 29 | Vue.prototype.$mount = function ( 30 | el?: any, 31 | hydrating?: boolean 32 | ): Component { 33 | return mountComponent( 34 | this, 35 | el && query(el, this.$document), 36 | hydrating 37 | ) 38 | } 39 | 40 | export default Vue 41 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/runtime/modules/attrs.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { extend } from 'shared/util' 4 | 5 | function updateAttrs (oldVnode: VNodeWithData, vnode: VNodeWithData) { 6 | if (!oldVnode.data.attrs && !vnode.data.attrs) { 7 | return 8 | } 9 | let key, cur, old 10 | const elm = vnode.elm 11 | const oldAttrs = oldVnode.data.attrs || {} 12 | let attrs = vnode.data.attrs || {} 13 | // clone observed objects, as the user probably wants to mutate it 14 | if (attrs.__ob__) { 15 | attrs = vnode.data.attrs = extend({}, attrs) 16 | } 17 | 18 | for (key in attrs) { 19 | cur = attrs[key] 20 | old = oldAttrs[key] 21 | if (old !== cur) { 22 | elm.setAttr(key, cur) 23 | } 24 | } 25 | for (key in oldAttrs) { 26 | if (attrs[key] == null) { 27 | elm.setAttr(key) 28 | } 29 | } 30 | } 31 | 32 | export default { 33 | create: updateAttrs, 34 | update: updateAttrs 35 | } 36 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/runtime/modules/events.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { updateListeners } from 'core/vdom/helpers/update-listeners' 4 | 5 | let target: any 6 | 7 | function add ( 8 | event: string, 9 | handler: Function, 10 | once: boolean, 11 | capture: boolean 12 | ) { 13 | if (capture) { 14 | console.log('Weex do not support event in bubble phase.') 15 | return 16 | } 17 | if (once) { 18 | const oldHandler = handler 19 | const _target = target // save current target element in closure 20 | handler = function (ev) { 21 | const res = arguments.length === 1 22 | ? oldHandler(ev) 23 | : oldHandler.apply(null, arguments) 24 | if (res !== null) { 25 | remove(event, null, null, _target) 26 | } 27 | } 28 | } 29 | target.addEvent(event, handler) 30 | } 31 | 32 | function remove ( 33 | event: string, 34 | handler: any, 35 | capture: any, 36 | _target?: any 37 | ) { 38 | (_target || target).removeEvent(event) 39 | } 40 | 41 | function updateDOMListeners (oldVnode: VNodeWithData, vnode: VNodeWithData) { 42 | if (!oldVnode.data.on && !vnode.data.on) { 43 | return 44 | } 45 | const on = vnode.data.on || {} 46 | const oldOn = oldVnode.data.on || {} 47 | target = vnode.elm 48 | updateListeners(on, oldOn, add, remove, vnode.context) 49 | } 50 | 51 | export default { 52 | create: updateDOMListeners, 53 | update: updateDOMListeners 54 | } 55 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/runtime/modules/index.js: -------------------------------------------------------------------------------- 1 | import attrs from './attrs' 2 | import klass from './class' 3 | import events from './events' 4 | import style from './style' 5 | import transition from './transition' 6 | 7 | export default [ 8 | attrs, 9 | klass, 10 | events, 11 | style, 12 | transition 13 | ] 14 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/runtime/patch.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import * as nodeOps from 'weex/runtime/node-ops' 4 | import { createPatchFunction } from 'core/vdom/patch' 5 | import baseModules from 'core/vdom/modules/index' 6 | import platformModules from 'weex/runtime/modules/index' 7 | 8 | // the directive module should be applied last, after all 9 | // built-in modules have been applied. 10 | const modules = platformModules.concat(baseModules) 11 | 12 | export const patch: Function = createPatchFunction({ 13 | nodeOps, 14 | modules, 15 | LONG_LIST_THRESHOLD: 10 16 | }) 17 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/platforms/weex/runtime/text-node.js: -------------------------------------------------------------------------------- 1 | let latestNodeId = 1 2 | 3 | export default function TextNode (text) { 4 | this.instanceId = '' 5 | this.nodeId = latestNodeId++ 6 | this.parentNode = null 7 | this.nodeType = 3 8 | this.text = text 9 | } 10 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/server/bundle-renderer/source-map-support.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | const SourceMapConsumer = require('source-map').SourceMapConsumer 4 | 5 | const filenameRE = /\(([^)]+\.js):(\d+):(\d+)\)$/ 6 | 7 | export function createSourceMapConsumers (rawMaps: Object) { 8 | const maps = {} 9 | Object.keys(rawMaps).forEach(file => { 10 | maps[file] = new SourceMapConsumer(rawMaps[file]) 11 | }) 12 | return maps 13 | } 14 | 15 | export function rewriteErrorTrace (e: any, mapConsumers: { 16 | [key: string]: SourceMapConsumer 17 | }) { 18 | if (e && typeof e.stack === 'string') { 19 | e.stack = e.stack.split('\n').map(line => { 20 | return rewriteTraceLine(line, mapConsumers) 21 | }).join('\n') 22 | } 23 | } 24 | 25 | function rewriteTraceLine (trace: string, mapConsumers: { 26 | [key: string]: SourceMapConsumer 27 | }) { 28 | const m = trace.match(filenameRE) 29 | const map = m && mapConsumers[m[1]] 30 | if (m != null && map) { 31 | const originalPosition = map.originalPositionFor({ 32 | line: Number(m[2]), 33 | column: Number(m[3]) 34 | }) 35 | if (originalPosition.source != null) { 36 | const { source, line, column } = originalPosition 37 | const mappedPosition = `(${source.replace(/^webpack:\/\/\//, '')}:${String(line)}:${String(column)})` 38 | return trace.replace(filenameRE, mappedPosition) 39 | } else { 40 | return trace 41 | } 42 | } else { 43 | return trace 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/server/template-renderer/parse-template.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | const compile = require('lodash.template') 4 | const compileOptions = { 5 | escape: /{{[^{]([\s\S]+?)[^}]}}/g, 6 | interpolate: /{{{([\s\S]+?)}}}/g 7 | } 8 | 9 | export type ParsedTemplate = { 10 | head: (data: any) => string; 11 | neck: (data: any) => string; 12 | tail: (data: any) => string; 13 | }; 14 | 15 | export function parseTemplate ( 16 | template: string, 17 | contentPlaceholder?: string = '' 18 | ): ParsedTemplate { 19 | if (typeof template === 'object') { 20 | return template 21 | } 22 | 23 | let i = template.indexOf('') 24 | const j = template.indexOf(contentPlaceholder) 25 | 26 | if (j < 0) { 27 | throw new Error(`Content placeholder not found in template.`) 28 | } 29 | 30 | if (i < 0) { 31 | i = template.indexOf('') 32 | if (i < 0) { 33 | i = j 34 | } 35 | } 36 | 37 | return { 38 | head: compile(template.slice(0, i), compileOptions), 39 | neck: compile(template.slice(i, j), compileOptions), 40 | tail: compile(template.slice(j + contentPlaceholder.length), compileOptions) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/server/util.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | export const isJS = (file: string): boolean => /\.js(\?[^.]+)?$/.test(file) 4 | 5 | export const isCSS = (file: string): boolean => /\.css(\?[^.]+)?$/.test(file) 6 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/server/webpack-plugin/util.js: -------------------------------------------------------------------------------- 1 | const { red, yellow } = require('chalk') 2 | 3 | const prefix = `[vue-server-renderer-webpack-plugin]` 4 | const warn = exports.warn = msg => console.error(red(`${prefix} ${msg}\n`)) 5 | const tip = exports.tip = msg => console.log(yellow(`${prefix} ${msg}\n`)) 6 | 7 | export const validate = compiler => { 8 | if (compiler.options.target !== 'node') { 9 | warn('webpack config `target` should be "node".') 10 | } 11 | 12 | if (compiler.options.output && compiler.options.output.libraryTarget !== 'commonjs2') { 13 | warn('webpack config `output.libraryTarget` should be "commonjs2".') 14 | } 15 | 16 | if (!compiler.options.externals) { 17 | tip( 18 | 'It is recommended to externalize dependencies in the server build for ' + 19 | 'better build performance.' 20 | ) 21 | } 22 | } 23 | 24 | export { isJS, isCSS } from '../util' 25 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/server/write.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | const MAX_STACK_DEPTH = 1000 4 | 5 | export function createWriteFunction ( 6 | write: (text: string, next: Function) => boolean, 7 | onError: Function 8 | ): Function { 9 | let stackDepth = 0 10 | const cachedWrite = (text, next) => { 11 | if (text && cachedWrite.caching) { 12 | cachedWrite.cacheBuffer[cachedWrite.cacheBuffer.length - 1] += text 13 | } 14 | const waitForNext = write(text, next) 15 | if (waitForNext !== true) { 16 | if (stackDepth >= MAX_STACK_DEPTH) { 17 | process.nextTick(() => { 18 | try { next() } catch (e) { 19 | onError(e) 20 | } 21 | }) 22 | } else { 23 | stackDepth++ 24 | next() 25 | stackDepth-- 26 | } 27 | } 28 | } 29 | cachedWrite.caching = false 30 | cachedWrite.cacheBuffer = [] 31 | cachedWrite.componentBuffer = [] 32 | return cachedWrite 33 | } 34 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vue-src/shared/constants.js: -------------------------------------------------------------------------------- 1 | /*用来标记是否是服务端渲染*/ 2 | export const SSR_ATTR = 'data-server-rendered' 3 | 4 | /*选项/资源集合*/ 5 | export const ASSET_TYPES = [ 6 | 'component', 7 | 'directive', 8 | 'filter' 9 | ] 10 | 11 | /*钩子函数集合*/ 12 | export const LIFECYCLE_HOOKS = [ 13 | 'beforeCreate', 14 | 'created', 15 | 'beforeMount', 16 | 'mounted', 17 | 'beforeUpdate', 18 | 'updated', 19 | 'beforeDestroy', 20 | 'destroyed', 21 | 'activated', 22 | 'deactivated' 23 | ] 24 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vuex-src/index.esm.js: -------------------------------------------------------------------------------- 1 | import { Store, install } from './store' 2 | import { mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from './helpers' 3 | 4 | export default { 5 | Store, 6 | install, 7 | version: '__VERSION__', 8 | mapState, 9 | mapMutations, 10 | mapGetters, 11 | mapActions, 12 | createNamespacedHelpers 13 | } 14 | 15 | export { 16 | Store, 17 | install, 18 | mapState, 19 | mapMutations, 20 | mapGetters, 21 | mapActions, 22 | createNamespacedHelpers 23 | } 24 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vuex-src/index.js: -------------------------------------------------------------------------------- 1 | import { Store, install } from './store' 2 | import { mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from './helpers' 3 | 4 | export default { 5 | Store, 6 | install, 7 | version: '__VERSION__', 8 | mapState, 9 | mapMutations, 10 | mapGetters, 11 | mapActions, 12 | createNamespacedHelpers 13 | } 14 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vuex-src/mixin.js: -------------------------------------------------------------------------------- 1 | export default function (Vue) { 2 | /*获取Vue版本,鉴别Vue1.0还是Vue2.0*/ 3 | const version = Number(Vue.version.split('.')[0]) 4 | 5 | if (version >= 2) { 6 | /*通过mixin将vuexInit混淆到Vue实例的beforeCreate钩子中*/ 7 | Vue.mixin({ beforeCreate: vuexInit }) 8 | } else { 9 | // override init and inject vuex init procedure 10 | // for 1.x backwards compatibility. 11 | /*将vuexInit放入_init中调用*/ 12 | const _init = Vue.prototype._init 13 | Vue.prototype._init = function (options = {}) { 14 | options.init = options.init 15 | ? [vuexInit].concat(options.init) 16 | : vuexInit 17 | _init.call(this, options) 18 | } 19 | } 20 | 21 | /** 22 | * Vuex init hook, injected into each instances init hooks list. 23 | */ 24 | /*Vuex的init钩子,会存入每一个Vue实例等钩子列表*/ 25 | function vuexInit () { 26 | const options = this.$options 27 | // store injection 28 | if (options.store) { 29 | /*存在store其实代表的就是Root节点,直接执行store(function时)或者使用store(非function)*/ 30 | this.$store = typeof options.store === 'function' 31 | ? options.store() 32 | : options.store 33 | } else if (options.parent && options.parent.$store) { 34 | /*子组件直接从父组件中获取$store,这样就保证了所有组件都公用了全局的同一份store*/ 35 | this.$store = options.parent.$store 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /source-learn/vue源码分析/source/vuex-src/plugins/devtool.js: -------------------------------------------------------------------------------- 1 | /* 从window对象的__VUE_DEVTOOLS_GLOBAL_HOOK__中获取devtool插件 */ 2 | const devtoolHook = 3 | typeof window !== 'undefined' && 4 | window.__VUE_DEVTOOLS_GLOBAL_HOOK__ 5 | 6 | export default function devtoolPlugin (store) { 7 | if (!devtoolHook) return 8 | 9 | /* devtoll插件实例存储在store的_devtoolHook上 */ 10 | store._devtoolHook = devtoolHook 11 | 12 | /* 出发vuex的初始化事件,并将store的引用地址传给deltool插件,使插件获取store的实例 */ 13 | devtoolHook.emit('vuex:init', store) 14 | 15 | /* 监听travel-to-state事件 */ 16 | devtoolHook.on('vuex:travel-to-state', targetState => { 17 | /* 重制state */ 18 | store.replaceState(targetState) 19 | }) 20 | 21 | /* 订阅store的变化 */ 22 | store.subscribe((mutation, state) => { 23 | devtoolHook.emit('vuex:mutation', mutation, state) 24 | }) 25 | } 26 | --------------------------------------------------------------------------------