├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── deploy.sh ├── docs ├── .vuepress │ ├── components │ │ └── GhongZhongHao.vue │ ├── config.js │ ├── enhanceApp.js │ ├── styles │ │ ├── index.styl │ │ └── palette.styl │ └── theme │ │ ├── LICENSE │ │ ├── README.md │ │ ├── components │ │ ├── AlgoliaSearchBox.vue │ │ ├── DropdownLink.vue │ │ ├── DropdownTransition.vue │ │ ├── Footer.vue │ │ ├── Home.vue │ │ ├── MainCard.vue │ │ ├── NavLink.vue │ │ ├── NavLinks.vue │ │ ├── Navbar.vue │ │ ├── Page.vue │ │ ├── PageEdit.vue │ │ ├── PageNav.vue │ │ ├── Sidebar.vue │ │ ├── SidebarButton.vue │ │ ├── SidebarGroup.vue │ │ ├── SidebarLink.vue │ │ ├── SidebarLinks.vue │ │ ├── SubMainCard.vue │ │ ├── ThirdCard.vue │ │ └── TopBanner.vue │ │ ├── global-components │ │ └── Badge.vue │ │ ├── index.js │ │ ├── layouts │ │ ├── 404.vue │ │ └── Layout.vue │ │ ├── noopModule.js │ │ ├── package.json │ │ ├── styles │ │ ├── arrow.styl │ │ ├── code.styl │ │ ├── config.styl │ │ ├── custom-blocks.styl │ │ ├── index.styl │ │ ├── mobile.styl │ │ ├── toc.styl │ │ └── wrapper.styl │ │ └── util │ │ └── index.js ├── about.md ├── borswer │ └── index.md ├── compiler │ └── index.md ├── css │ └── index.md ├── design │ └── index.md ├── dsa │ └── index.md ├── index.md ├── js │ ├── 1.md │ ├── 2.md │ ├── 3.md │ ├── 4.md │ ├── 5.md │ ├── 6.md │ ├── 7.md │ └── index.md ├── network │ ├── 1.md │ ├── 2.md │ ├── 3.md │ ├── 4.md │ ├── 5.md │ ├── 6.md │ ├── 7.md │ ├── 8.md │ ├── 9.md │ └── index.md ├── node │ └── index.md ├── noop │ └── index.md ├── per │ └── index.md ├── safe │ └── index.md ├── unknow.md ├── vue │ ├── 1.md │ ├── index.md │ ├── vue-2.6.0 │ │ ├── LICENSE │ │ ├── README.md │ │ ├── package.json │ │ ├── src │ │ │ ├── compiler │ │ │ │ ├── codeframe.js │ │ │ │ ├── codegen │ │ │ │ │ ├── events.js │ │ │ │ │ └── index.js │ │ │ │ ├── create-compiler.js │ │ │ │ ├── directives │ │ │ │ │ ├── bind.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── model.js │ │ │ │ │ └── on.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 │ │ │ │ └── to-function.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-dynamic-keys.js │ │ │ │ │ │ ├── bind-object-listeners.js │ │ │ │ │ │ ├── bind-object-props.js │ │ │ │ │ │ ├── check-keycodes.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── render-list.js │ │ │ │ │ │ ├── render-slot.js │ │ │ │ │ │ ├── render-static.js │ │ │ │ │ │ ├── resolve-filter.js │ │ │ │ │ │ ├── resolve-scoped-slots.js │ │ │ │ │ │ └── resolve-slots.js │ │ │ │ │ ├── render.js │ │ │ │ │ └── state.js │ │ │ │ ├── observer │ │ │ │ │ ├── array.js │ │ │ │ │ ├── dep.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── scheduler.js │ │ │ │ │ ├── traverse.js │ │ │ │ │ └── watcher.js │ │ │ │ ├── util │ │ │ │ │ ├── debug.js │ │ │ │ │ ├── env.js │ │ │ │ │ ├── error.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── lang.js │ │ │ │ │ ├── next-tick.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 │ │ │ │ │ ├── is-async-placeholder.js │ │ │ │ │ ├── merge-hook.js │ │ │ │ │ ├── normalize-children.js │ │ │ │ │ ├── normalize-scoped-slots.js │ │ │ │ │ ├── resolve-async-component.js │ │ │ │ │ └── update-listeners.js │ │ │ │ │ ├── modules │ │ │ │ │ ├── directives.js │ │ │ │ │ ├── index.js │ │ │ │ │ └── ref.js │ │ │ │ │ ├── patch.js │ │ │ │ │ └── vnode.js │ │ │ ├── platforms │ │ │ │ ├── web │ │ │ │ │ ├── compiler │ │ │ │ │ │ ├── directives │ │ │ │ │ │ │ ├── html.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── model.js │ │ │ │ │ │ │ └── text.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── modules │ │ │ │ │ │ │ ├── class.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── model.js │ │ │ │ │ │ │ └── style.js │ │ │ │ │ │ ├── options.js │ │ │ │ │ │ └── util.js │ │ │ │ │ ├── entry-compiler.js │ │ │ │ │ ├── entry-runtime-with-compiler.js │ │ │ │ │ ├── entry-runtime.js │ │ │ │ │ ├── entry-server-basic-renderer.js │ │ │ │ │ ├── entry-server-renderer.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 │ │ │ │ │ │ ├── compiler.js │ │ │ │ │ │ ├── directives │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── model.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 │ │ │ │ │ ├── directives │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ └── model.js │ │ │ │ │ ├── index.js │ │ │ │ │ └── modules │ │ │ │ │ │ ├── append.js │ │ │ │ │ │ ├── class.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── props.js │ │ │ │ │ │ ├── recycle-list │ │ │ │ │ │ ├── component-root.js │ │ │ │ │ │ ├── component.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── recycle-list.js │ │ │ │ │ │ ├── text.js │ │ │ │ │ │ ├── v-bind.js │ │ │ │ │ │ ├── v-for.js │ │ │ │ │ │ ├── v-if.js │ │ │ │ │ │ ├── v-on.js │ │ │ │ │ │ └── v-once.js │ │ │ │ │ │ └── style.js │ │ │ │ │ ├── entry-compiler.js │ │ │ │ │ ├── entry-framework.js │ │ │ │ │ ├── entry-runtime-factory.js │ │ │ │ │ ├── runtime │ │ │ │ │ ├── components │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── richtext.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 │ │ │ │ │ ├── recycle-list │ │ │ │ │ │ ├── render-component-template.js │ │ │ │ │ │ └── virtual-component.js │ │ │ │ │ └── text-node.js │ │ │ │ │ └── util │ │ │ │ │ ├── element.js │ │ │ │ │ ├── index.js │ │ │ │ │ └── parser.js │ │ │ ├── server │ │ │ │ ├── bundle-renderer │ │ │ │ │ ├── create-bundle-renderer.js │ │ │ │ │ ├── create-bundle-runner.js │ │ │ │ │ └── source-map-support.js │ │ │ │ ├── create-basic-renderer.js │ │ │ │ ├── create-renderer.js │ │ │ │ ├── optimizing-compiler │ │ │ │ │ ├── codegen.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── modules.js │ │ │ │ │ ├── optimizer.js │ │ │ │ │ └── runtime-helpers.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 │ │ └── types │ │ │ ├── index.d.ts │ │ │ ├── options.d.ts │ │ │ ├── plugin.d.ts │ │ │ ├── umd.d.ts │ │ │ ├── vnode.d.ts │ │ │ └── vue.d.ts │ └── vue3.0.js ├── webpack │ └── index.md └── work │ └── index.md ├── main ├── .gitignore ├── .vscode │ └── extensions.json ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── public │ └── vite.svg ├── src │ ├── App.vue │ ├── assets │ │ └── vue.svg │ ├── components │ │ └── HelloWorld.vue │ ├── main.ts │ ├── style.css │ ├── topic │ │ ├── async_await.ts │ │ ├── eventLoop.ts │ │ ├── iterator.ts │ │ ├── microtasks.ts │ │ ├── promise.ts │ │ └── webworker.ts │ └── vite-env.d.ts ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ├── package-lock.json ├── package.json ├── question.md ├── scripts └── build.sh └── src ├── js ├── 1-1.js ├── 1-2.js ├── 1-3.js ├── 1-4.js ├── 1-5.js ├── 1.js ├── 3.js ├── eventloop.html ├── promise.js └── this.js └── network └── 1.ts /.gitattributes: -------------------------------------------------------------------------------- 1 | *.css linguist-language=javascript 2 | *.less linguist-language=javascript 3 | *.js linguist-language=javascript 4 | *.html linguist-language=javascript 5 | *.sh linguist-language=javascript -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 suyan 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 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 确保脚本抛出遇到的错误 4 | set -e 5 | 6 | # 生成静态文件 7 | npm run build 8 | 9 | # 进入生成的文件夹 10 | cd docs/.vuepress/dist 11 | 12 | # 如果是发布到自定义域名 13 | # echo 'www.example.com' > CNAME 14 | 15 | git init 16 | git add -A 17 | git commit -m 'deploy' 18 | 19 | # 如果发布到 https://.github.io 20 | # git push -f git@github.com:/.github.io.git master 21 | 22 | # 如果发布到 https://.github.io/ 23 | # 发布到 lefex.github.io/fe-mini-course 下 24 | # git push -f git@github.com:lefex/fe-mini-course.git master:gh-pages 25 | # 发布到 lefex.github.io 下 26 | git push -f git@github.com:lefex/bat.git master:gh-pages 27 | 28 | cd - -------------------------------------------------------------------------------- /docs/.vuepress/components/GhongZhongHao.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 22 | 23 | -------------------------------------------------------------------------------- /docs/.vuepress/enhanceApp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Client app enhancement file. 3 | * 4 | * https://v1.vuepress.vuejs.org/guide/basic-config.html#app-level-enhancements 5 | */ 6 | 7 | import ElementUI from 'element-ui'; 8 | import 'element-ui/lib/theme-chalk/index.css' 9 | 10 | export default ({ 11 | Vue, // the version of Vue being used in the VuePress app 12 | options, // the options for the root Vue instance 13 | router, // the router instance for the app 14 | siteData // site metadata 15 | }) => { 16 | // ...apply enhancements for the site. 17 | Vue.use(ElementUI); 18 | }; 19 | -------------------------------------------------------------------------------- /docs/.vuepress/styles/index.styl: -------------------------------------------------------------------------------- 1 | /** 2 | * Custom Styles here. 3 | * 4 | * ref:https://v1.vuepress.vuejs.org/config/#index-styl 5 | */ 6 | 7 | .home .hero img 8 | max-width 450px!important 9 | -------------------------------------------------------------------------------- /docs/.vuepress/styles/palette.styl: -------------------------------------------------------------------------------- 1 | /** 2 | * Custom palette here. 3 | * 4 | * ref:https://v1.vuepress.vuejs.org/zh/config/#palette-styl 5 | */ 6 | 7 | $accentColor = #409EFF 8 | $textColor = #222 9 | $borderColor = #f5f5f5 10 | $codeBgColor = #282c34 11 | 12 | $homePageWidth = 1280px 13 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018-present, Yuxi (Evan) You 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/README.md: -------------------------------------------------------------------------------- 1 | # @vuepress/theme-default 2 | 3 | > theme-default for VuePress 4 | 5 | ## Plugins 6 | 7 | The default theme has the following plugin built in: 8 | 9 | - [@vuepress/plugin-active-header-links](https://github.com/vuejs/vuepress/tree/master/packages/@vuepress/plugin-active-header-links) 10 | - [@vuepress/plugin-google-analytics](https://github.com/vuejs/vuepress/tree/master/packages/%40vuepress/plugin-google-analytics) 11 | - [@vuepress/plugin-search](https://github.com/vuejs/vuepress/tree/master/packages/%40vuepress/plugin-search) 12 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/components/DropdownTransition.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 28 | 29 | 34 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/components/Footer.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 22 | 23 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/components/MainCard.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 42 | 43 | 92 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/components/NavLink.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 91 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/components/Page.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 23 | 24 | 32 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/components/Sidebar.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 27 | 28 | 65 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/components/SidebarButton.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 41 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/components/SubMainCard.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 28 | 29 | 53 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/components/ThirdCard.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 31 | 32 | 59 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/components/TopBanner.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 31 | 32 | 52 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/global-components/Badge.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 45 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | // Theme API. 4 | module.exports = (options, ctx) => { 5 | const { themeConfig, siteConfig } = ctx 6 | 7 | // resolve algolia 8 | const isAlgoliaSearch = ( 9 | themeConfig.algolia 10 | || Object 11 | .keys(siteConfig.locales && themeConfig.locales || {}) 12 | .some(base => themeConfig.locales[base].algolia) 13 | ) 14 | 15 | const enableSmoothScroll = themeConfig.smoothScroll === true 16 | 17 | return { 18 | alias () { 19 | return { 20 | '@AlgoliaSearchBox': isAlgoliaSearch 21 | ? path.resolve(__dirname, 'components/AlgoliaSearchBox.vue') 22 | : path.resolve(__dirname, 'noopModule.js') 23 | } 24 | }, 25 | 26 | plugins: [ 27 | ['@vuepress/active-header-links', options.activeHeaderLinks], 28 | '@vuepress/search', 29 | '@vuepress/plugin-nprogress', 30 | ['container', { 31 | type: 'tip', 32 | defaultTitle: { 33 | '/': 'TIP', 34 | '/zh/': '提示' 35 | } 36 | }], 37 | ['container', { 38 | type: 'warning', 39 | defaultTitle: { 40 | '/': 'WARNING', 41 | '/zh/': '注意' 42 | } 43 | }], 44 | ['container', { 45 | type: 'danger', 46 | defaultTitle: { 47 | '/': 'WARNING', 48 | '/zh/': '警告' 49 | } 50 | }], 51 | ['container', { 52 | type: 'details', 53 | before: info => `
${info ? `${info}` : ''}\n`, 54 | after: () => '
\n' 55 | }], 56 | ['smooth-scroll', enableSmoothScroll] 57 | ] 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/layouts/404.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 31 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/noopModule.js: -------------------------------------------------------------------------------- 1 | export default {} 2 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_args": [ 3 | [ 4 | "@vuepress/theme-default@1.5.4", 5 | "/Users/suyanwang/Desktop/project/SYJSBridge" 6 | ] 7 | ], 8 | "_development": true, 9 | "_from": "@vuepress/theme-default@1.5.4", 10 | "_id": "@vuepress/theme-default@1.5.4", 11 | "_inBundle": false, 12 | "_integrity": "sha512-kHst1yXzqTiocVU7w9x4cfJ08vR9ZbREC6kTRtH1ytQSEUL5tM0b9HFicfg1kDp7YNq2qntRro+WmfjU9Ps/eg==", 13 | "_location": "/@vuepress/theme-default", 14 | "_phantomChildren": {}, 15 | "_requested": { 16 | "type": "version", 17 | "registry": true, 18 | "raw": "@vuepress/theme-default@1.5.4", 19 | "name": "@vuepress/theme-default", 20 | "escapedName": "@vuepress%2ftheme-default", 21 | "scope": "@vuepress", 22 | "rawSpec": "1.5.4", 23 | "saveSpec": null, 24 | "fetchSpec": "1.5.4" 25 | }, 26 | "_requiredBy": [ 27 | "/vuepress" 28 | ], 29 | "_resolved": "https://registry.npmjs.org/@vuepress/theme-default/-/theme-default-1.5.4.tgz", 30 | "_spec": "1.5.4", 31 | "_where": "/Users/suyanwang/Desktop/project/SYJSBridge", 32 | "author": { 33 | "name": "Evan You" 34 | }, 35 | "bugs": { 36 | "url": "https://github.com/vuejs/vuepress/issues" 37 | }, 38 | "dependencies": { 39 | "@vuepress/plugin-active-header-links": "1.5.4", 40 | "@vuepress/plugin-nprogress": "1.5.4", 41 | "@vuepress/plugin-search": "1.5.4", 42 | "docsearch.js": "^2.5.2", 43 | "lodash": "^4.17.15", 44 | "stylus": "^0.54.5", 45 | "stylus-loader": "^3.0.2", 46 | "vuepress-plugin-container": "^2.0.2", 47 | "vuepress-plugin-smooth-scroll": "^0.0.3" 48 | }, 49 | "description": "Default theme for VuePress", 50 | "gitHead": "98086ad620d4ba51f08497acddad8ffc1fc1273c", 51 | "homepage": "https://github.com/vuejs/vuepress/blob/master/packages/@vuepress/theme-default#readme", 52 | "keywords": [ 53 | "documentation", 54 | "generator", 55 | "vue", 56 | "vuepress" 57 | ], 58 | "license": "MIT", 59 | "main": "index.js", 60 | "maintainers": [ 61 | { 62 | "name": "ULIVZ", 63 | "email": "chl814@foxmail.com" 64 | } 65 | ], 66 | "name": "@vuepress/theme-default", 67 | "publishConfig": { 68 | "access": "public" 69 | }, 70 | "repository": { 71 | "type": "git", 72 | "url": "git+https://github.com/vuejs/vuepress.git", 73 | "directory": "packages/@vuepress/theme-default" 74 | }, 75 | "version": "1.5.4" 76 | } 77 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/styles/arrow.styl: -------------------------------------------------------------------------------- 1 | @require './config' 2 | 3 | .arrow 4 | display inline-block 5 | width 0 6 | height 0 7 | &.up 8 | border-left 4px solid transparent 9 | border-right 4px solid transparent 10 | border-bottom 6px solid $arrowBgColor 11 | &.down 12 | border-left 4px solid transparent 13 | border-right 4px solid transparent 14 | border-top 6px solid $arrowBgColor 15 | &.right 16 | border-top 4px solid transparent 17 | border-bottom 4px solid transparent 18 | border-left 6px solid $arrowBgColor 19 | &.left 20 | border-top 4px solid transparent 21 | border-bottom 4px solid transparent 22 | border-right 6px solid $arrowBgColor 23 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/styles/config.styl: -------------------------------------------------------------------------------- 1 | $contentClass = '.theme-default-content' 2 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/styles/custom-blocks.styl: -------------------------------------------------------------------------------- 1 | .custom-block 2 | .custom-block-title 3 | font-weight 600 4 | margin-bottom -0.4rem 5 | &.tip, &.warning, &.danger 6 | padding .1rem 1.5rem 7 | border-left-width .5rem 8 | border-left-style solid 9 | margin 1rem 0 10 | &.tip 11 | background-color #f3f5f7 12 | border-color #42b983 13 | &.warning 14 | background-color rgba(255,229,100,.3) 15 | border-color darken(#ffe564, 35%) 16 | color darken(#ffe564, 70%) 17 | .custom-block-title 18 | color darken(#ffe564, 50%) 19 | a 20 | color $textColor 21 | &.danger 22 | background-color #ffe6e6 23 | border-color darken(red, 20%) 24 | color darken(red, 70%) 25 | .custom-block-title 26 | color darken(red, 40%) 27 | a 28 | color $textColor 29 | &.details 30 | display block 31 | position relative 32 | border-radius 2px 33 | margin 1.6em 0 34 | padding 1.6em 35 | background-color #eee 36 | h4 37 | margin-top 0 38 | figure, p 39 | &:last-child 40 | margin-bottom 0 41 | padding-bottom 0 42 | summary 43 | outline none 44 | cursor pointer 45 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/styles/mobile.styl: -------------------------------------------------------------------------------- 1 | @require './config' 2 | 3 | $mobileSidebarWidth = $sidebarWidth * 0.82 4 | 5 | // narrow desktop / iPad 6 | @media (max-width: $MQNarrow) 7 | .sidebar 8 | font-size 15px 9 | width $mobileSidebarWidth 10 | .page 11 | padding-left $mobileSidebarWidth 12 | 13 | // wide mobile 14 | @media (max-width: $MQMobile) 15 | .sidebar 16 | top 0 17 | padding-top $navbarHeight 18 | transform translateX(-100%) 19 | transition transform .2s ease 20 | .page 21 | padding-left 0 22 | .theme-container 23 | &.sidebar-open 24 | .sidebar 25 | transform translateX(0) 26 | &.no-navbar 27 | .sidebar 28 | padding-top: 0 29 | 30 | // narrow mobile 31 | @media (max-width: $MQMobileNarrow) 32 | h1 33 | font-size 1.9rem 34 | {$contentClass} 35 | div[class*="language-"] 36 | margin 0.85rem -1.5rem 37 | border-radius 0 38 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/styles/toc.styl: -------------------------------------------------------------------------------- 1 | .table-of-contents 2 | .badge 3 | vertical-align middle 4 | -------------------------------------------------------------------------------- /docs/.vuepress/theme/styles/wrapper.styl: -------------------------------------------------------------------------------- 1 | $wrapper 2 | max-width $contentWidth 3 | margin 0 auto 4 | padding 2rem 2.5rem 5 | @media (max-width: $MQNarrow) 6 | padding 2rem 7 | @media (max-width: $MQMobileNarrow) 8 | padding 1.5rem 9 | 10 | -------------------------------------------------------------------------------- /docs/about.md: -------------------------------------------------------------------------------- 1 | ## 关于本站 2 | 3 | BAT代表着国内顶尖的互联网公司,包括百度、阿里、腾讯。随着这几年互联网公司不断崛起,涌现出了更多类似BAT这样的公司,成为这些公司的员工是每个前端程序员的奋斗目标。各大公司面试题层出不穷,即使你能力比较强,也可能在面试过程中失利。本站通过收集各大厂前端面试题,并对其进行深入剖析,拆解知识点,以了解顶尖互联网公司对顶尖人才的要求,最终希望你能够顺利拿到满意的 offer。 4 | 5 | 作者目前就职于百度,毒舌程序员,擅长 iOS 与前端,正在写 [前端小课](https://lefex.gitee.io/),帮助10W人入门并进阶前端,并运营公众号素燕。 6 | 7 | -------------------------------------------------------------------------------- /docs/borswer/index.md: -------------------------------------------------------------------------------- 1 | # 浏览器相关的知识点 2 | 3 | - 对浏览器渲染机制的理解(具体到细节,从渲染树到paint之间究竟发生了什么) 4 | - 浏览器的架构,bom,dom 5 | - cookie,session,localstorage 区别 6 | - 浏览器内核有哪些 7 | - 什么是CDN,页面怎么优化 -------------------------------------------------------------------------------- /docs/compiler/index.md: -------------------------------------------------------------------------------- 1 | # 编译器 2 | 3 | - ES6 代码转成 ES5 代码的实现思路是什么 -------------------------------------------------------------------------------- /docs/css/index.md: -------------------------------------------------------------------------------- 1 | # css 2 | 3 | - 介绍下 BFC、IFC、GFC 和 FFC 4 | - 如何解决移动端 Retina 屏 1px 像素问题 5 | - 已知如下代码,如何修改才能让图片宽度为 300px ?注意下面代码不可修改。 6 | ```html 7 | setTimeout(() => { throw e; })); // report exceptions 28 | }; 29 | } 30 | ``` 31 | 32 | 啥时候使用微任务,比如保证调用顺序一致: 33 | 34 | ```js 35 | customElement.prototype.getData = url => { 36 | if (this.cache[url]) { 37 | queueMicrotask(() => { 38 | this.data = this.cache[url]; 39 | this.dispatchEvent(new Event("load")); 40 | }); 41 | } else { 42 | fetch(url).then(result => result.arrayBuffer()).then(data => { 43 | this.cache[url] = data; 44 | this.data = data; 45 | this.dispatchEvent(new Event("load")); 46 | }); 47 | } 48 | }; 49 | ``` 50 | 51 | 52 | ### 参考 53 | 54 | - [Event Loop Spec](https://html.spec.whatwg.org/multipage/webappapis.html#event-loops) 55 | - [event loop](https://javascript.info/event-loop) 56 | - [queueMicrotask](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/queueMicrotask) 57 | - [event-loop](https://javascript.info/event-loop) 58 | - [Microtask guide](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide) 59 | - [自实现微任务](https://github.com/feross/queue-microtask) 60 | - [microtask guide in depth](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide/In_depth) 61 | - [JavaScript 运行机制详解:再谈Event Loop](http://www.ruanyifeng.com/blog/2014/10/event-loop.html) 62 | - [Tasks, microtasks, queues 和 schedules](https://hongfanqie.github.io/tasks-microtasks-queues-and-schedules/) 63 | - [更快的异步函数和 Promise](https://v8.js.cn/blog/fast-async/) -------------------------------------------------------------------------------- /docs/js/7.md: -------------------------------------------------------------------------------- 1 | # 如何理解 JavaScript 异步执行机制 2 | 3 | 下面这段代码的执行顺序是什么? 4 | 5 | ```js 6 | async function async1() { 7 | console.log('async1 start'); 8 | await async2(); 9 | console.log('async1 end'); 10 | } 11 | 12 | function async2() { 13 | console.log('async2 start'); 14 | } 15 | 16 | console.log('start'); 17 | 18 | setTimeout(function() { 19 | console.log('setTimeout excuted'); 20 | }, 0) 21 | async1(); 22 | 23 | new Promise(function(resolve) { 24 | console.log('promise resolve'); 25 | resolve(); 26 | }).then(function() { 27 | console.log('promise then'); 28 | }); 29 | 30 | console.log('end'); 31 | ``` 32 | 33 | 代码执行结果: 34 | 35 | ```js 36 | start 37 | async1 start 38 | async2 start 39 | promise resolve 40 | end 41 | async1 end 42 | promise then 43 | setTimeout excuted 44 | ``` -------------------------------------------------------------------------------- /docs/network/2.md: -------------------------------------------------------------------------------- 1 | # 2.工作中是否遇到过跨域?什么是跨域?如何解决? 2 | 3 | 4 | 5 | 相似问题: 6 | - 跨域请求可以携带cookie吗 7 | - 跨域的解决办法,jsonp的实现原理 8 | - cookie 跨域的处理方案 9 | - cookie 种在子域下能否携带发送到服务端(SSO登录) 10 | - cookie跨域服务端需要如何适配(CORS头) 11 | - 跨域的解决办法 12 | - cookie 和 token 都存放在 header 中,为什么不会劫持 token? 13 | - 一个请求跨域是否会抵达服务端 -------------------------------------------------------------------------------- /docs/network/3.md: -------------------------------------------------------------------------------- 1 | # 3.为什么通常在发送数据埋点请求的时候使用的是 1x1 像素的透明 gif 图片? -------------------------------------------------------------------------------- /docs/network/4.md: -------------------------------------------------------------------------------- 1 | # 4.谈谈你对TCP的理解 2 | 3 | 相关题目: 4 | - 三次握手和四次挥手的理解 5 | - A、B 机器正常连接后,B 机器突然重启,问 A 此时处于 TCP 什么状态 -------------------------------------------------------------------------------- /docs/network/5.md: -------------------------------------------------------------------------------- 1 | # 5.从输入一个url到呈现网页,都有哪些步骤 -------------------------------------------------------------------------------- /docs/network/6.md: -------------------------------------------------------------------------------- 1 | # 6.谈谈你对 HTTP 的理解,状态码的含义,header 定义 2 | 3 | 相关面试题 4 | - http的头部有什么字段,简要描述(缓存,content-type,cookie等等) 5 | - http keep—alive都解决了哪些问题 keep-alive是从c - nginx建立的还是直接到服务建立的长连接,与websocket有什么区别与联系 -------------------------------------------------------------------------------- /docs/network/7.md: -------------------------------------------------------------------------------- 1 | # 7.谈谈你对 https 的理解 2 | 3 | ## 相关面试题 4 | - 介绍下 HTTPS 中间人攻击 5 | - HTTPS 握手过程中,客户端如何验证证书的合法性 6 | - 介绍 HTTPS 握手过程 7 | - https 建立连接的过程及通信 如何劫持,鉴别是否被劫持 8 | - 对https的理解,对称、非对称加密在哪部使用 9 | -------------------------------------------------------------------------------- /docs/network/8.md: -------------------------------------------------------------------------------- 1 | # 8.谈谈你对 HTTP2 的理解 2 | 3 | 相关面试题: 4 | 5 | - 简单讲解一下http2的多路复用 6 | - 对http2有哪些了解 7 | -------------------------------------------------------------------------------- /docs/network/9.md: -------------------------------------------------------------------------------- 1 | # axios 是如何实现的 2 | 3 | -------------------------------------------------------------------------------- /docs/network/index.md: -------------------------------------------------------------------------------- 1 | # 前端网络相关的面试题 2 | 3 | 网格相关内容主要围绕下面这些面试题进行展开,每道面试题都是从一个点展开,由浅入深,在做面试题的同时掌握知识。 4 | 5 | - [第 1 题:前端网络请求都有哪些方式?webSocket 是什么?](https://lefex.github.io/bat/network/1) 6 | - [第 2 题:工作中是否遇到过跨域?什么是跨域?如何解决?](https://lefex.github.io/bat/network/2) 7 | - [第 3 题:为什么通常在发送数据埋点请求的时候使用的是 1x1 像素的透明 gif 图片?](https://lefex.github.io/bat/network/3) 8 | - [第 4 题:谈谈你对TCP的理解](https://lefex.github.io/bat/network/4) 9 | - [第 5 题:从输入一个url到呈现网页,都有哪些步骤](https://lefex.github.io/bat/network/5) 10 | - [第 6 题:谈谈你对 HTTP 的理解,状态码的含义,header 定义](https://lefex.github.io/bat/network/6) 11 | - [第 7 题:谈谈你对 https 的理解](https://lefex.github.io/bat/network/7) 12 | - [第 8 题:谈谈你对 HTTP2 的理解](https://lefex.github.io/bat/network/8) 13 | - [第 9 题:axios 是如何实现的](https://lefex.github.io/bat/network/9) 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/node/index.md: -------------------------------------------------------------------------------- 1 | # node 常考题 2 | 3 | - 说说浏览器和 Node 事件循环的区别 4 | - EventLoop的理解 5 | - 浏览器渲染触发在EventLoop的哪个阶段,触发机制是怎么样的 6 | - node中的垃圾收集机制 -------------------------------------------------------------------------------- /docs/noop/index.md: -------------------------------------------------------------------------------- 1 | # 杂七杂八的面试题 2 | 3 | - 实现模糊搜索结果的关键词高亮显示 4 | - 在输入框中如何判断输入的是一个正确的网址。 5 | - input 搜索如何防抖,如何处理中文输入 6 | - 如何设计实现无缝轮播 7 | - 介绍下如何实现 token 加密 8 | - 浏览器缓存读取规则 9 | - 介绍下 npm 模块安装机制,为什么输入 npm install 就可以自动安装对应的模块? 10 | - 对代码构建上线流程是否了解,说一下如果让你实现的思路 11 | - JSONpatth 了解吗 12 | - 单点登录成熟的方案 13 | - jQuery 的特点,和现代框架的区别 14 | - script标签为什么要放在页面的底部 15 | - 如果script标签放在head标签中,如何让js脚本等待DOM加载完成执行 16 | - 异步加载一段JavaScript代码,如何监听这段代码是否加载完毕 17 | - 不同子域之间如何共享一段js脚本 18 | - 如何在页面上按需加载一个模块,比如点击按钮加载 -------------------------------------------------------------------------------- /docs/per/index.md: -------------------------------------------------------------------------------- 1 | # 性能优化相关面试题 2 | -------------------------------------------------------------------------------- /docs/safe/index.md: -------------------------------------------------------------------------------- 1 | # 前端开发中的安全问题 2 | -------------------------------------------------------------------------------- /docs/unknow.md: -------------------------------------------------------------------------------- 1 | [BFF层](https://www.jianshu.com/p/eb1875c62ad3) -------------------------------------------------------------------------------- /docs/vue/1.md: -------------------------------------------------------------------------------- 1 | # nextTick 2 | 3 | 源码,其实就是一个微任务,下一个周期: 4 | 5 | ```js 6 | function nextTick(fn) { 7 | const p = currentFlushPromise || resolvedPromise; 8 | return fn ? p.then(this ? fn.bind(this) : fn) : p; 9 | } 10 | ``` -------------------------------------------------------------------------------- /docs/vue/index.md: -------------------------------------------------------------------------------- 1 | vue 相关的面试题 2 | 3 | - 聊聊 Vue 的双向数据绑定,Model 如何改变 View,View 又是如何改变 Model 的 4 | - 聊聊 Redux 和 Vuex 的设计思想 5 | - React 和 Vue 的 diff 时间复杂度从 O(n^3) 优化到 O(n) ,那么 O(n^3) 和 O(n) 是如何计算出来的? 6 | - vue 在 v-for 时给每项元素绑定事件需要用事件代理吗?为什么? 7 | - react-router 里的 Link 标签和 a 标签有什么区别 8 | - Vue 的父组件和子组件生命周期钩子执行顺序是什么 9 | - 为什么普通 for 循环的性能远远高于 forEach 的性能,请解释其中的原因。 10 | - redux 为什么要把 reducer 设计成纯函数 11 | - Vue 的响应式原理中 Object.defineProperty 有什么缺陷?为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty? 12 | - 双向绑定和 vuex 是否冲突 13 | - 在 Vue 中,子组件为何不可以修改父组件传递的 Prop。如果修改了,Vue 是如何监控到属性的修改并给出警告的。 14 | - 为什么 Vuex 的 mutation 和 Redux 的 reducer 中不能做异步操作? 15 | - Virtual DOM 真的比操作原生 DOM 快吗?谈谈你的想法。 16 | - vue数据绑定的实现原理 17 | - vue computed具体在什么阶段进行的依赖收集,具体的过程详细描述 18 | - vue的生命周期 19 | - vue父子组件通信的方式 20 | - vue eventbus的原理 21 | - vue中可以对对象进行数据监听,如果对于数组中的某个元素能否监听,是如何做到的 22 | - 什么事虚拟dom 23 | - 动态给Vue实例增加属性, this.a = 2 a之前未定义,如何监听a的变化 24 | - 在 vue 中根据索引值修改的数据变动的,是否可以检测到,为什么?如果有这样的场景你怎么处理 25 | - Vue中nextTick 的实现原理 与 node 中的 process.nextTick 的区别 26 | 27 | 28 | 为何组件要从直接产出 html 变成产出 Virtual DOM 呢?其原因是 Virtual DOM 带来了 分层设计,它对渲染过程的抽象,使得框架可以渲染到 web(浏览器) 以外的平台,以及能够实现 SSR 等。 29 | 30 | http://hcysun.me/vue-design/zh/essence-of-comp.html#%E7%BB%84%E4%BB%B6%E7%9A%84%E4%BA%A7%E5%87%BA%E6%98%AF%E4%BB%80%E4%B9%88 31 | 32 | VNode 是真实 DOM 的描述,比如我们可以用如下对象描述一个 div 标签: 33 | 34 | vnode:虚拟 DOM 35 | container:真实 DOM 节点 -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-present, Yuxi (Evan) You 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/compiler/codeframe.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | const range = 2 4 | 5 | export function generateCodeFrame ( 6 | source: string, 7 | start: number = 0, 8 | end: number = source.length 9 | ): string { 10 | const lines = source.split(/\r?\n/) 11 | let count = 0 12 | const res = [] 13 | for (let i = 0; i < lines.length; i++) { 14 | count += lines[i].length + 1 15 | if (count >= start) { 16 | for (let j = i - range; j <= i + range || end > count; j++) { 17 | if (j < 0 || j >= lines.length) continue 18 | res.push(`${j + 1}${repeat(` `, 3 - String(j + 1).length)}| ${lines[j]}`) 19 | const lineLength = lines[j].length 20 | if (j === i) { 21 | // push underline 22 | const pad = start - (count - lineLength) + 1 23 | const length = end > count ? lineLength - pad : end - start 24 | res.push(` | ` + repeat(` `, pad) + repeat(`^`, length)) 25 | } else if (j > i) { 26 | if (end > count) { 27 | const length = Math.min(end - count, lineLength) 28 | res.push(` | ` + repeat(`^`, length)) 29 | } 30 | count += lineLength + 1 31 | } 32 | } 33 | break 34 | } 35 | } 36 | return res.join('\n') 37 | } 38 | 39 | function repeat (str, n) { 40 | let result = '' 41 | if (n > 0) { 42 | while (true) { // eslint-disable-line 43 | if (n & 1) result += str 44 | n >>>= 1 45 | if (n <= 0) break 46 | str += str 47 | } 48 | } 49 | return result 50 | } 51 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/compiler/create-compiler.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { extend } from 'shared/util' 4 | import { detectErrors } from './error-detector' 5 | import { createCompileToFunctionFn } from './to-function' 6 | 7 | export function createCompilerCreator (baseCompile: Function): Function { 8 | return function createCompiler (baseOptions: CompilerOptions) { 9 | function compile ( 10 | template: string, 11 | options?: CompilerOptions 12 | ): CompiledResult { 13 | const finalOptions = Object.create(baseOptions) 14 | const errors = [] 15 | const tips = [] 16 | 17 | let warn = (msg, range, tip) => { 18 | (tip ? tips : errors).push(msg) 19 | } 20 | 21 | if (options) { 22 | if (process.env.NODE_ENV !== 'production' && options.outputSourceRange) { 23 | // $flow-disable-line 24 | const leadingSpaceLength = template.match(/^\s*/)[0].length 25 | 26 | warn = (msg, range, tip) => { 27 | const data: WarningMessage = { msg } 28 | if (range) { 29 | if (range.start != null) { 30 | data.start = range.start + leadingSpaceLength 31 | } 32 | if (range.end != null) { 33 | data.end = range.end + leadingSpaceLength 34 | } 35 | } 36 | (tip ? tips : errors).push(data) 37 | } 38 | } 39 | // merge custom modules 40 | if (options.modules) { 41 | finalOptions.modules = 42 | (baseOptions.modules || []).concat(options.modules) 43 | } 44 | // merge custom directives 45 | if (options.directives) { 46 | finalOptions.directives = extend( 47 | Object.create(baseOptions.directives || null), 48 | options.directives 49 | ) 50 | } 51 | // copy other options 52 | for (const key in options) { 53 | if (key !== 'modules' && key !== 'directives') { 54 | finalOptions[key] = options[key] 55 | } 56 | } 57 | } 58 | 59 | finalOptions.warn = warn 60 | 61 | const compiled = baseCompile(template.trim(), finalOptions) 62 | if (process.env.NODE_ENV !== 'production') { 63 | detectErrors(compiled.ast, warn) 64 | } 65 | compiled.errors = errors 66 | compiled.tips = tips 67 | return compiled 68 | } 69 | 70 | return { 71 | compile, 72 | compileToFunctions: createCompileToFunctionFn(compile) 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/compiler/directives/bind.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 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' : 'false' 7 | }${ 8 | dir.modifiers && dir.modifiers.sync ? ',true' : '' 9 | })` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/compiler/directives/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import on from './on' 4 | import bind from './bind' 5 | import { noop } from 'shared/util' 6 | 7 | export default { 8 | on, 9 | bind, 10 | cloak: noop 11 | } 12 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/compiler/directives/on.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { warn } from 'core/util/index' 4 | 5 | export default function on (el: ASTElement, dir: ASTDirective) { 6 | if (process.env.NODE_ENV !== 'production' && dir.modifiers) { 7 | warn(`v-on without argument does not support modifiers.`) 8 | } 9 | el.wrapListeners = (code: string) => `_g(${code},${dir.value})` 10 | } 11 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/compiler/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { parse } from './parser/index' 4 | import { optimize } from './optimizer' 5 | import { generate } from './codegen/index' 6 | import { createCompilerCreator } from './create-compiler' 7 | 8 | // `createCompilerCreator` allows creating compilers that use alternative 9 | // parser/optimizer/codegen, e.g the SSR optimizing compiler. 10 | // Here we just export a default compiler using the default parts. 11 | export const createCompiler = createCompilerCreator(function baseCompile ( 12 | template: string, 13 | options: CompilerOptions 14 | ): CompiledResult { 15 | const ast = parse(template.trim(), options) 16 | if (options.optimize !== false) { 17 | optimize(ast, options) 18 | } 19 | const code = generate(ast, options) 20 | return { 21 | ast, 22 | render: code.render, 23 | staticRenderFns: code.staticRenderFns 24 | } 25 | }) 26 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/compiler/parser/entity-decoder.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | let decoder 4 | 5 | export default { 6 | decode (html: string): string { 7 | decoder = decoder || document.createElement('div') 8 | decoder.innerHTML = html 9 | return decoder.textContent 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/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 = /\{\{((?:.|\r?\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 | 15 | type TextParseResult = { 16 | expression: string, 17 | tokens: Array 18 | } 19 | 20 | export function parseText ( 21 | text: string, 22 | delimiters?: [string, string] 23 | ): TextParseResult | void { 24 | const tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE 25 | if (!tagRE.test(text)) { 26 | return 27 | } 28 | const tokens = [] 29 | const rawTokens = [] 30 | let lastIndex = tagRE.lastIndex = 0 31 | let match, index, tokenValue 32 | while ((match = tagRE.exec(text))) { 33 | index = match.index 34 | // push text token 35 | if (index > lastIndex) { 36 | rawTokens.push(tokenValue = text.slice(lastIndex, index)) 37 | tokens.push(JSON.stringify(tokenValue)) 38 | } 39 | // tag token 40 | const exp = parseFilters(match[1].trim()) 41 | tokens.push(`_s(${exp})`) 42 | rawTokens.push({ '@binding': exp }) 43 | lastIndex = index + match[0].length 44 | } 45 | if (lastIndex < text.length) { 46 | rawTokens.push(tokenValue = text.slice(lastIndex)) 47 | tokens.push(JSON.stringify(tokenValue)) 48 | } 49 | return { 50 | expression: tokens.join('+'), 51 | tokens: rawTokens 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/components/index.js: -------------------------------------------------------------------------------- 1 | import KeepAlive from './keep-alive' 2 | 3 | export default { 4 | KeepAlive 5 | } 6 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/global-api/assets.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { ASSET_TYPES } from 'shared/constants' 4 | import { isPlainObject, validateComponentName } from '../util/index' 5 | 6 | export function initAssetRegisters (Vue: GlobalAPI) { 7 | /** 8 | * Create asset registration methods. 9 | */ 10 | ASSET_TYPES.forEach(type => { 11 | Vue[type] = function ( 12 | id: string, 13 | definition: Function | Object 14 | ): Function | Object | void { 15 | if (!definition) { 16 | return this.options[type + 's'][id] 17 | } else { 18 | /* istanbul ignore if */ 19 | if (process.env.NODE_ENV !== 'production' && type === 'component') { 20 | validateComponentName(id) 21 | } 22 | if (type === 'component' && isPlainObject(definition)) { 23 | definition.name = definition.name || id 24 | definition = this.options._base.extend(definition) 25 | } 26 | if (type === 'directive' && typeof definition === 'function') { 27 | definition = { bind: definition, update: definition } 28 | } 29 | this.options[type + 's'][id] = definition 30 | return definition 31 | } 32 | } 33 | }) 34 | } 35 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/global-api/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import config from '../config' 4 | import { initUse } from './use' 5 | import { initMixin } from './mixin' 6 | import { initExtend } from './extend' 7 | import { initAssetRegisters } from './assets' 8 | import { set, del } from '../observer/index' 9 | import { ASSET_TYPES } from 'shared/constants' 10 | import builtInComponents from '../components/index' 11 | import { observe } from 'core/observer/index' 12 | 13 | import { 14 | warn, 15 | extend, 16 | nextTick, 17 | mergeOptions, 18 | defineReactive 19 | } from '../util/index' 20 | 21 | export function initGlobalAPI (Vue: GlobalAPI) { 22 | // config 23 | const configDef = {} 24 | configDef.get = () => config 25 | if (process.env.NODE_ENV !== 'production') { 26 | configDef.set = () => { 27 | warn( 28 | 'Do not replace the Vue.config object, set individual fields instead.' 29 | ) 30 | } 31 | } 32 | Object.defineProperty(Vue, 'config', configDef) 33 | 34 | // exposed util methods. 35 | // NOTE: these are not considered part of the public API - avoid relying on 36 | // them unless you are aware of the risk. 37 | Vue.util = { 38 | warn, 39 | extend, 40 | mergeOptions, 41 | defineReactive 42 | } 43 | 44 | Vue.set = set 45 | Vue.delete = del 46 | Vue.nextTick = nextTick 47 | 48 | // 2.6 explicit observable API 49 | Vue.observable = (obj: T): T => { 50 | observe(obj) 51 | return obj 52 | } 53 | 54 | Vue.options = Object.create(null) 55 | ASSET_TYPES.forEach(type => { 56 | Vue.options[type + 's'] = Object.create(null) 57 | }) 58 | 59 | // this is used to identify the "base" constructor to extend all plain-object 60 | // components with in Weex's multi-instance scenarios. 61 | Vue.options._base = Vue 62 | 63 | extend(Vue.options.components, builtInComponents) 64 | 65 | initUse(Vue) 66 | initMixin(Vue) 67 | initExtend(Vue) 68 | initAssetRegisters(Vue) 69 | } 70 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/global-api/mixin.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { mergeOptions } from '../util/index' 4 | 5 | export function initMixin (Vue: GlobalAPI) { 6 | Vue.mixin = function (mixin: Object) { 7 | this.options = mergeOptions(this.options, mixin) 8 | return this 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/global-api/use.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { toArray } from '../util/index' 4 | 5 | export function initUse (Vue: GlobalAPI) { 6 | Vue.use = function (plugin: Function | Object) { 7 | const installedPlugins = (this._installedPlugins || (this._installedPlugins = [])) 8 | if (installedPlugins.indexOf(plugin) > -1) { 9 | return this 10 | } 11 | 12 | // additional parameters 13 | const args = toArray(arguments, 1) 14 | args.unshift(this) 15 | if (typeof plugin.install === 'function') { 16 | plugin.install.apply(plugin, args) 17 | } else if (typeof plugin === 'function') { 18 | plugin.apply(null, args) 19 | } 20 | installedPlugins.push(plugin) 21 | return this 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/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 | import { FunctionalRenderContext } from 'core/vdom/create-functional-component' 5 | 6 | initGlobalAPI(Vue) 7 | 8 | Object.defineProperty(Vue.prototype, '$isServer', { 9 | get: isServerRendering 10 | }) 11 | 12 | Object.defineProperty(Vue.prototype, '$ssrContext', { 13 | get () { 14 | /* istanbul ignore next */ 15 | return this.$vnode && this.$vnode.ssrContext 16 | } 17 | }) 18 | 19 | // expose FunctionalRenderContext for ssr runtime helper installation 20 | Object.defineProperty(Vue, 'FunctionalRenderContext', { 21 | value: FunctionalRenderContext 22 | }) 23 | 24 | Vue.version = '__VERSION__' 25 | 26 | export default Vue 27 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/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 | 8 | function Vue (options) { 9 | if (process.env.NODE_ENV !== 'production' && 10 | !(this instanceof Vue) 11 | ) { 12 | warn('Vue is a constructor and should be called with the `new` keyword') 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 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/instance/inject.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { hasOwn } from 'shared/util' 4 | import { warn, hasSymbol } from '../util/index' 5 | import { defineReactive, toggleObserving } from '../observer/index' 6 | 7 | export function initProvide (vm: Component) { 8 | const provide = vm.$options.provide 9 | if (provide) { 10 | vm._provided = typeof provide === 'function' 11 | ? provide.call(vm) 12 | : provide 13 | } 14 | } 15 | 16 | export function initInjections (vm: Component) { 17 | const result = resolveInject(vm.$options.inject, vm) 18 | if (result) { 19 | toggleObserving(false) 20 | Object.keys(result).forEach(key => { 21 | /* istanbul ignore else */ 22 | if (process.env.NODE_ENV !== 'production') { 23 | defineReactive(vm, key, result[key], () => { 24 | warn( 25 | `Avoid mutating an injected value directly since the changes will be ` + 26 | `overwritten whenever the provided component re-renders. ` + 27 | `injection being mutated: "${key}"`, 28 | vm 29 | ) 30 | }) 31 | } else { 32 | defineReactive(vm, key, result[key]) 33 | } 34 | }) 35 | toggleObserving(true) 36 | } 37 | } 38 | 39 | export function resolveInject (inject: any, vm: Component): ?Object { 40 | if (inject) { 41 | // inject is :any because flow is not smart enough to figure out cached 42 | const result = Object.create(null) 43 | const keys = hasSymbol 44 | ? Reflect.ownKeys(inject) 45 | : Object.keys(inject) 46 | 47 | for (let i = 0; i < keys.length; i++) { 48 | const key = keys[i] 49 | // #6574 in case the inject object is observed... 50 | if (key === '__ob__') continue 51 | const provideKey = inject[key].from 52 | let source = vm 53 | while (source) { 54 | if (source._provided && hasOwn(source._provided, provideKey)) { 55 | result[key] = source._provided[provideKey] 56 | break 57 | } 58 | source = source.$parent 59 | } 60 | if (!source) { 61 | if ('default' in inject[key]) { 62 | const provideDefault = inject[key].default 63 | result[key] = typeof provideDefault === 'function' 64 | ? provideDefault.call(vm) 65 | : provideDefault 66 | } else if (process.env.NODE_ENV !== 'production') { 67 | warn(`Injection "${key}" not found`, vm) 68 | } 69 | } 70 | } 71 | return result 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/instance/render-helpers/bind-dynamic-keys.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | // helper to process dynamic keys for dynamic arguments in v-bind and v-on. 4 | // For example, the following template: 5 | // 6 | //
7 | // 8 | // compiles to the following: 9 | // 10 | // _c('div', { attrs: bindDynamicKeys({ "id": "app" }, [key, value]) }) 11 | 12 | import { warn } from 'core/util/debug' 13 | 14 | export function bindDynamicKeys (baseObj: Object, values: Array): Object { 15 | for (let i = 0; i < values.length; i += 2) { 16 | const key = values[i] 17 | if (typeof key === 'string' && key) { 18 | baseObj[values[i]] = values[i + 1] 19 | } else if (process.env.NODE_ENV !== 'production' && key !== '' && key !== null) { 20 | // null is a special value for explicitly removing a binding 21 | warn( 22 | `Invalid value for dynamic directive argument (expected string or null): ${key}`, 23 | this 24 | ) 25 | } 26 | } 27 | return baseObj 28 | } 29 | 30 | // helper to dynamically append modifier runtime markers to event names. 31 | // ensure only append when value is already string, otherwise it will be cast 32 | // to string and cause the type check to miss. 33 | export function prependModifier (value: any, symbol: string): any { 34 | return typeof value === 'string' ? symbol + value : value 35 | } 36 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/instance/render-helpers/bind-object-listeners.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { warn, extend, isPlainObject } from 'core/util/index' 4 | 5 | export function bindObjectListeners (data: any, value: any): VNodeData { 6 | if (value) { 7 | if (!isPlainObject(value)) { 8 | process.env.NODE_ENV !== 'production' && warn( 9 | 'v-on without argument expects an Object value', 10 | this 11 | ) 12 | } else { 13 | const on = data.on = data.on ? extend({}, data.on) : {} 14 | for (const key in value) { 15 | const existing = on[key] 16 | const ours = value[key] 17 | on[key] = existing ? [].concat(existing, ours) : ours 18 | } 19 | } 20 | } 21 | return data 22 | } 23 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/instance/render-helpers/bind-object-props.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import config from 'core/config' 4 | 5 | import { 6 | warn, 7 | isObject, 8 | toObject, 9 | isReservedAttribute, 10 | camelize, 11 | hyphenate 12 | } from 'core/util/index' 13 | 14 | /** 15 | * Runtime helper for merging v-bind="object" into a VNode's data. 16 | */ 17 | export function bindObjectProps ( 18 | data: any, 19 | tag: string, 20 | value: any, 21 | asProp: boolean, 22 | isSync?: boolean 23 | ): VNodeData { 24 | if (value) { 25 | if (!isObject(value)) { 26 | process.env.NODE_ENV !== 'production' && warn( 27 | 'v-bind without argument expects an Object or Array value', 28 | this 29 | ) 30 | } else { 31 | if (Array.isArray(value)) { 32 | value = toObject(value) 33 | } 34 | let hash 35 | for (const key in value) { 36 | if ( 37 | key === 'class' || 38 | key === 'style' || 39 | isReservedAttribute(key) 40 | ) { 41 | hash = data 42 | } else { 43 | const type = data.attrs && data.attrs.type 44 | hash = asProp || config.mustUseProp(tag, type, key) 45 | ? data.domProps || (data.domProps = {}) 46 | : data.attrs || (data.attrs = {}) 47 | } 48 | const camelizedKey = camelize(key) 49 | const hyphenatedKey = hyphenate(key) 50 | if (!(camelizedKey in hash) && !(hyphenatedKey in hash)) { 51 | hash[key] = value[key] 52 | 53 | if (isSync) { 54 | const on = data.on || (data.on = {}) 55 | on[`update:${key}`] = function ($event) { 56 | value[key] = $event 57 | } 58 | } 59 | } 60 | } 61 | } 62 | } 63 | return data 64 | } 65 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/instance/render-helpers/check-keycodes.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import config from 'core/config' 4 | import { hyphenate } from 'shared/util' 5 | 6 | function isKeyNotMatch (expect: T | Array, actual: T): boolean { 7 | if (Array.isArray(expect)) { 8 | return expect.indexOf(actual) === -1 9 | } else { 10 | return expect !== actual 11 | } 12 | } 13 | 14 | /** 15 | * Runtime helper for checking keyCodes from config. 16 | * exposed as Vue.prototype._k 17 | * passing in eventKeyName as last argument separately for backwards compat 18 | */ 19 | export function checkKeyCodes ( 20 | eventKeyCode: number, 21 | key: string, 22 | builtInKeyCode?: number | Array, 23 | eventKeyName?: string, 24 | builtInKeyName?: string | Array 25 | ): ?boolean { 26 | const mappedKeyCode = config.keyCodes[key] || builtInKeyCode 27 | if (builtInKeyName && eventKeyName && !config.keyCodes[key]) { 28 | return isKeyNotMatch(builtInKeyName, eventKeyName) 29 | } else if (mappedKeyCode) { 30 | return isKeyNotMatch(mappedKeyCode, eventKeyCode) 31 | } else if (eventKeyName) { 32 | return hyphenate(eventKeyName) !== key 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/instance/render-helpers/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { toNumber, toString, looseEqual, looseIndexOf } from 'shared/util' 4 | import { createTextVNode, createEmptyVNode } from 'core/vdom/vnode' 5 | import { renderList } from './render-list' 6 | import { renderSlot } from './render-slot' 7 | import { resolveFilter } from './resolve-filter' 8 | import { checkKeyCodes } from './check-keycodes' 9 | import { bindObjectProps } from './bind-object-props' 10 | import { renderStatic, markOnce } from './render-static' 11 | import { bindObjectListeners } from './bind-object-listeners' 12 | import { resolveScopedSlots } from './resolve-scoped-slots' 13 | import { bindDynamicKeys, prependModifier } from './bind-dynamic-keys' 14 | 15 | export function installRenderHelpers (target: any) { 16 | target._o = markOnce 17 | target._n = toNumber 18 | target._s = toString 19 | target._l = renderList 20 | target._t = renderSlot 21 | target._q = looseEqual 22 | target._i = looseIndexOf 23 | target._m = renderStatic 24 | target._f = resolveFilter 25 | target._k = checkKeyCodes 26 | target._b = bindObjectProps 27 | target._v = createTextVNode 28 | target._e = createEmptyVNode 29 | target._u = resolveScopedSlots 30 | target._g = bindObjectListeners 31 | target._d = bindDynamicKeys 32 | target._p = prependModifier 33 | } 34 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/instance/render-helpers/render-list.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { isObject, isDef, hasSymbol } from 'core/util/index' 4 | 5 | /** 6 | * Runtime helper for rendering v-for lists. 7 | */ 8 | export function renderList ( 9 | val: any, 10 | render: ( 11 | val: any, 12 | keyOrIndex: string | number, 13 | index?: number 14 | ) => VNode 15 | ): ?Array { 16 | let ret: ?Array, i, l, keys, key 17 | if (Array.isArray(val) || typeof val === 'string') { 18 | ret = new Array(val.length) 19 | for (i = 0, l = val.length; i < l; i++) { 20 | ret[i] = render(val[i], i) 21 | } 22 | } else if (typeof val === 'number') { 23 | ret = new Array(val) 24 | for (i = 0; i < val; i++) { 25 | ret[i] = render(i + 1, i) 26 | } 27 | } else if (isObject(val)) { 28 | if (hasSymbol && val[Symbol.iterator]) { 29 | ret = [] 30 | const iterator: Iterator = val[Symbol.iterator]() 31 | let result = iterator.next() 32 | while (!result.done) { 33 | ret.push(render(result.value, ret.length)) 34 | result = iterator.next() 35 | } 36 | } else { 37 | keys = Object.keys(val) 38 | ret = new Array(keys.length) 39 | for (i = 0, l = keys.length; i < l; i++) { 40 | key = keys[i] 41 | ret[i] = render(val[key], key, i) 42 | } 43 | } 44 | } 45 | if (!isDef(ret)) { 46 | ret = [] 47 | } 48 | (ret: any)._isVList = true 49 | return ret 50 | } 51 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/instance/render-helpers/render-slot.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { extend, warn, isObject } from 'core/util/index' 4 | 5 | /** 6 | * Runtime helper for rendering 7 | */ 8 | export function renderSlot ( 9 | name: string, 10 | fallback: ?Array, 11 | props: ?Object, 12 | bindObject: ?Object 13 | ): ?Array { 14 | const scopedSlotFn = this.$scopedSlots[name] 15 | let nodes 16 | if (scopedSlotFn) { // scoped slot 17 | props = props || {} 18 | if (bindObject) { 19 | if (process.env.NODE_ENV !== 'production' && !isObject(bindObject)) { 20 | warn( 21 | 'slot v-bind without argument expects an Object', 22 | this 23 | ) 24 | } 25 | props = extend(extend({}, bindObject), props) 26 | } 27 | nodes = scopedSlotFn(props) || fallback 28 | } else { 29 | nodes = this.$slots[name] || fallback 30 | } 31 | 32 | const target = props && props.slot 33 | if (target) { 34 | return this.$createElement('template', { slot: target }, nodes) 35 | } else { 36 | return nodes 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/instance/render-helpers/render-static.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | /** 4 | * Runtime helper for rendering static trees. 5 | */ 6 | export function renderStatic ( 7 | index: number, 8 | isInFor: boolean 9 | ): VNode | Array { 10 | const cached = this._staticTrees || (this._staticTrees = []) 11 | let tree = cached[index] 12 | // if has already-rendered static tree and not inside v-for, 13 | // we can reuse the same tree. 14 | if (tree && !isInFor) { 15 | return tree 16 | } 17 | // otherwise, render a fresh tree. 18 | tree = cached[index] = this.$options.staticRenderFns[index].call( 19 | this._renderProxy, 20 | null, 21 | this // for render fns generated for functional component templates 22 | ) 23 | markStatic(tree, `__static__${index}`, false) 24 | return tree 25 | } 26 | 27 | /** 28 | * Runtime helper for v-once. 29 | * Effectively it means marking the node as static with a unique key. 30 | */ 31 | export function markOnce ( 32 | tree: VNode | Array, 33 | index: number, 34 | key: string 35 | ) { 36 | markStatic(tree, `__once__${index}${key ? `_${key}` : ``}`, true) 37 | return tree 38 | } 39 | 40 | function markStatic ( 41 | tree: VNode | Array, 42 | key: string, 43 | isOnce: boolean 44 | ) { 45 | if (Array.isArray(tree)) { 46 | for (let i = 0; i < tree.length; i++) { 47 | if (tree[i] && typeof tree[i] !== 'string') { 48 | markStaticNode(tree[i], `${key}_${i}`, isOnce) 49 | } 50 | } 51 | } else { 52 | markStaticNode(tree, key, isOnce) 53 | } 54 | } 55 | 56 | function markStaticNode (node, key, isOnce) { 57 | node.isStatic = true 58 | node.key = key 59 | node.isOnce = isOnce 60 | } 61 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/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 | export function resolveFilter (id: string): Function { 9 | return resolveAsset(this.$options, 'filters', id, true) || identity 10 | } 11 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/instance/render-helpers/resolve-scoped-slots.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | export function resolveScopedSlots ( 4 | fns: ScopedSlotsData, // see flow/vnode 5 | res?: Object, 6 | // the following are added in 2.6 7 | hasDynamicKeys?: boolean, 8 | contentHashKey?: number 9 | ): { [key: string]: Function, $stable: boolean } { 10 | res = res || { $stable: !hasDynamicKeys } 11 | for (let i = 0; i < fns.length; i++) { 12 | const slot = fns[i] 13 | if (Array.isArray(slot)) { 14 | resolveScopedSlots(slot, res, hasDynamicKeys) 15 | } else if (slot) { 16 | // marker for reverse proxying v-slot without scope on this.$slots 17 | if (slot.proxy) { 18 | slot.fn.proxy = true 19 | } 20 | res[slot.key] = slot.fn 21 | } 22 | } 23 | if (contentHashKey) { 24 | (res: any).$key = contentHashKey 25 | } 26 | return res 27 | } 28 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/instance/render-helpers/resolve-slots.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import type VNode from 'core/vdom/vnode' 4 | 5 | /** 6 | * Runtime helper for resolving raw children VNodes into a slot object. 7 | */ 8 | export function resolveSlots ( 9 | children: ?Array, 10 | context: ?Component 11 | ): { [key: string]: Array } { 12 | if (!children || !children.length) { 13 | return {} 14 | } 15 | const slots = {} 16 | for (let i = 0, l = children.length; i < l; i++) { 17 | const child = children[i] 18 | const data = child.data 19 | // remove slot attribute if the node is resolved as a Vue slot node 20 | if (data && data.attrs && data.attrs.slot) { 21 | delete data.attrs.slot 22 | } 23 | // named slots should only be respected if the vnode was rendered in the 24 | // same context. 25 | if ((child.context === context || child.fnContext === context) && 26 | data && data.slot != null 27 | ) { 28 | const name = data.slot 29 | const slot = (slots[name] || (slots[name] = [])) 30 | if (child.tag === 'template') { 31 | slot.push.apply(slot, child.children || []) 32 | } else { 33 | slot.push(child) 34 | } 35 | } else { 36 | (slots.default || (slots.default = [])).push(child) 37 | } 38 | } 39 | // ignore slots that contains only whitespace 40 | for (const name in slots) { 41 | if (slots[name].every(isWhitespace)) { 42 | delete slots[name] 43 | } 44 | } 45 | return slots 46 | } 47 | 48 | function isWhitespace (node: VNode): boolean { 49 | return (node.isComment && !node.asyncFactory) || node.text === ' ' 50 | } 51 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/observer/array.js: -------------------------------------------------------------------------------- 1 | /* 2 | * not type checking this file because flow doesn't play well with 3 | * dynamically accessing methods on Array prototype 4 | */ 5 | 6 | import { def } from '../util/index' 7 | 8 | const arrayProto = Array.prototype 9 | export const arrayMethods = Object.create(arrayProto) 10 | 11 | const methodsToPatch = [ 12 | 'push', 13 | 'pop', 14 | 'shift', 15 | 'unshift', 16 | 'splice', 17 | 'sort', 18 | 'reverse' 19 | ] 20 | 21 | /** 22 | * Intercept mutating methods and emit events 23 | */ 24 | methodsToPatch.forEach(function (method) { 25 | // cache original method 26 | const original = arrayProto[method] 27 | def(arrayMethods, method, function mutator (...args) { 28 | const result = original.apply(this, args) 29 | const ob = this.__ob__ 30 | let inserted 31 | switch (method) { 32 | case 'push': 33 | case 'unshift': 34 | inserted = args 35 | break 36 | case 'splice': 37 | inserted = args.slice(2) 38 | break 39 | } 40 | if (inserted) ob.observeArray(inserted) 41 | // notify change 42 | ob.dep.notify() 43 | return result 44 | }) 45 | }) 46 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/observer/dep.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import type Watcher from './watcher' 4 | import { remove } from '../util/index' 5 | import config from '../config' 6 | 7 | let uid = 0 8 | 9 | /** 10 | * A dep is an observable that can have multiple 11 | * directives subscribing to it. 12 | */ 13 | export default class Dep { 14 | static target: ?Watcher; 15 | id: number; 16 | subs: Array; 17 | 18 | constructor () { 19 | this.id = uid++ 20 | this.subs = [] 21 | } 22 | 23 | addSub (sub: Watcher) { 24 | this.subs.push(sub) 25 | } 26 | 27 | removeSub (sub: Watcher) { 28 | remove(this.subs, sub) 29 | } 30 | 31 | depend () { 32 | if (Dep.target) { 33 | Dep.target.addDep(this) 34 | } 35 | } 36 | 37 | notify () { 38 | // stabilize the subscriber list first 39 | const subs = this.subs.slice() 40 | if (process.env.NODE_ENV !== 'production' && !config.async) { 41 | // subs aren't sorted in scheduler if not running async 42 | // we need to sort them now to make sure they fire in correct 43 | // order 44 | subs.sort((a, b) => a.id - b.id) 45 | } 46 | for (let i = 0, l = subs.length; i < l; i++) { 47 | subs[i].update() 48 | } 49 | } 50 | } 51 | 52 | // The current target watcher being evaluated. 53 | // This is globally unique because only one watcher 54 | // can be evaluated at a time. 55 | Dep.target = null 56 | const targetStack = [] 57 | 58 | export function pushTarget (target: ?Watcher) { 59 | targetStack.push(target) 60 | Dep.target = target 61 | } 62 | 63 | export function popTarget () { 64 | targetStack.pop() 65 | Dep.target = targetStack[targetStack.length - 1] 66 | } 67 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/observer/traverse.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { _Set as Set, isObject } from '../util/index' 4 | import type { SimpleSet } from '../util/index' 5 | import VNode from '../vdom/vnode' 6 | 7 | const seenObjects = new Set() 8 | 9 | /** 10 | * Recursively traverse an object to evoke all converted 11 | * getters, so that every nested property inside the object 12 | * is collected as a "deep" dependency. 13 | */ 14 | export function traverse (val: any) { 15 | _traverse(val, seenObjects) 16 | seenObjects.clear() 17 | } 18 | 19 | function _traverse (val: any, seen: SimpleSet) { 20 | let i, keys 21 | const isA = Array.isArray(val) 22 | if ((!isA && !isObject(val)) || Object.isFrozen(val) || val instanceof VNode) { 23 | return 24 | } 25 | if (val.__ob__) { 26 | const depId = val.__ob__.dep.id 27 | if (seen.has(depId)) { 28 | return 29 | } 30 | seen.add(depId) 31 | } 32 | if (isA) { 33 | i = val.length 34 | while (i--) _traverse(val[i], seen) 35 | } else { 36 | keys = Object.keys(val) 37 | i = keys.length 38 | while (i--) _traverse(val[keys[i]], seen) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/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 * from './next-tick' 11 | export { defineReactive } from '../observer/index' 12 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/util/lang.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | /** 4 | * unicode letters used for parsing html tags, component names and property paths. 5 | * using https://www.w3.org/TR/html53/semantics-scripting.html#potentialcustomelementname 6 | * skipping \u10000-\uEFFFF due to it freezing up PhantomJS 7 | */ 8 | export const unicodeRegExp = /a-zA-Z\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD/ 9 | 10 | /** 11 | * Check if a string starts with $ or _ 12 | */ 13 | export function isReserved (str: string): boolean { 14 | const c = (str + '').charCodeAt(0) 15 | return c === 0x24 || c === 0x5F 16 | } 17 | 18 | /** 19 | * Define a property. 20 | */ 21 | export function def (obj: Object, key: string, val: any, enumerable?: boolean) { 22 | Object.defineProperty(obj, key, { 23 | value: val, 24 | enumerable: !!enumerable, 25 | writable: true, 26 | configurable: true 27 | }) 28 | } 29 | 30 | /** 31 | * Parse simple path. 32 | */ 33 | const bailRE = new RegExp(`[^${unicodeRegExp.source}.$_\\d]`) 34 | export function parsePath (path: string): any { 35 | if (bailRE.test(path)) { 36 | return 37 | } 38 | const segments = path.split('.') 39 | return function (obj) { 40 | for (let i = 0; i < segments.length; i++) { 41 | if (!obj) return 42 | obj = obj[segments[i]] 43 | } 44 | return obj 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/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 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/vdom/helpers/extract-props.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { 4 | tip, 5 | hasOwn, 6 | isDef, 7 | isUndef, 8 | hyphenate, 9 | formatComponentName 10 | } from 'core/util/index' 11 | 12 | export function extractPropsFromVNodeData ( 13 | data: VNodeData, 14 | Ctor: Class, 15 | tag?: string 16 | ): ?Object { 17 | // we are only extracting raw values here. 18 | // validation and default values are handled in the child 19 | // component itself. 20 | const propOptions = Ctor.options.props 21 | if (isUndef(propOptions)) { 22 | return 23 | } 24 | const res = {} 25 | const { attrs, props } = data 26 | if (isDef(attrs) || isDef(props)) { 27 | for (const key in propOptions) { 28 | const altKey = hyphenate(key) 29 | if (process.env.NODE_ENV !== 'production') { 30 | const keyInLowerCase = key.toLowerCase() 31 | if ( 32 | key !== keyInLowerCase && 33 | attrs && hasOwn(attrs, keyInLowerCase) 34 | ) { 35 | tip( 36 | `Prop "${keyInLowerCase}" is passed to component ` + 37 | `${formatComponentName(tag || Ctor)}, but the declared prop name is` + 38 | ` "${key}". ` + 39 | `Note that HTML attributes are case-insensitive and camelCased ` + 40 | `props need to use their kebab-case equivalents when using in-DOM ` + 41 | `templates. You should probably use "${altKey}" instead of "${key}".` 42 | ) 43 | } 44 | } 45 | checkProp(res, props, key, altKey, true) || 46 | checkProp(res, attrs, key, altKey, false) 47 | } 48 | } 49 | return res 50 | } 51 | 52 | function checkProp ( 53 | res: Object, 54 | hash: ?Object, 55 | key: string, 56 | altKey: string, 57 | preserve: boolean 58 | ): boolean { 59 | if (isDef(hash)) { 60 | if (hasOwn(hash, key)) { 61 | res[key] = hash[key] 62 | if (!preserve) { 63 | delete hash[key] 64 | } 65 | return true 66 | } else if (hasOwn(hash, altKey)) { 67 | res[key] = hash[altKey] 68 | if (!preserve) { 69 | delete hash[altKey] 70 | } 71 | return true 72 | } 73 | } 74 | return false 75 | } 76 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/vdom/helpers/get-first-component-child.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { isDef } from 'shared/util' 4 | import { isAsyncPlaceholder } from './is-async-placeholder' 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) || isAsyncPlaceholder(c))) { 11 | return c 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/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 | export * from './is-async-placeholder' 10 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/vdom/helpers/is-async-placeholder.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | export function isAsyncPlaceholder (node: VNode): boolean { 4 | return node.isComment && node.asyncFactory 5 | } 6 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/vdom/helpers/merge-hook.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import VNode from '../vnode' 4 | import { createFnInvoker } from './update-listeners' 5 | import { remove, isDef, isUndef, isTrue } from 'shared/util' 6 | 7 | export function mergeVNodeHook (def: Object, hookKey: string, hook: Function) { 8 | if (def instanceof VNode) { 9 | def = def.data.hook || (def.data.hook = {}) 10 | } 11 | let invoker 12 | const oldHook = def[hookKey] 13 | 14 | function wrappedHook () { 15 | hook.apply(this, arguments) 16 | // important: remove merged hook to ensure it's called only once 17 | // and prevent memory leak 18 | remove(invoker.fns, wrappedHook) 19 | } 20 | 21 | if (isUndef(oldHook)) { 22 | // no existing hook 23 | invoker = createFnInvoker([wrappedHook]) 24 | } else { 25 | /* istanbul ignore if */ 26 | if (isDef(oldHook.fns) && isTrue(oldHook.merged)) { 27 | // already a merged invoker 28 | invoker = oldHook 29 | invoker.fns.push(wrappedHook) 30 | } else { 31 | // existing plain hook 32 | invoker = createFnInvoker([oldHook, wrappedHook]) 33 | } 34 | } 35 | 36 | invoker.merged = true 37 | def[hookKey] = invoker 38 | } 39 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/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 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/core/vdom/modules/ref.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { remove, isDef } 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 | export function registerRef (vnode: VNodeWithData, isRemoval: ?boolean) { 21 | const key = vnode.data.ref 22 | if (!isDef(key)) return 23 | 24 | const vm = vnode.context 25 | const ref = vnode.componentInstance || vnode.elm 26 | const refs = vm.$refs 27 | if (isRemoval) { 28 | if (Array.isArray(refs[key])) { 29 | remove(refs[key], ref) 30 | } else if (refs[key] === ref) { 31 | refs[key] = undefined 32 | } 33 | } else { 34 | if (vnode.data.refInFor) { 35 | if (!Array.isArray(refs[key])) { 36 | refs[key] = [ref] 37 | } else if (refs[key].indexOf(ref) < 0) { 38 | // $flow-disable-line 39 | refs[key].push(ref) 40 | } 41 | } else { 42 | refs[key] = ref 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/compiler/directives/html.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { addProp } from 'compiler/helpers' 4 | 5 | export default function html (el: ASTElement, dir: ASTDirective) { 6 | if (dir.value) { 7 | addProp(el, 'innerHTML', `_s(${dir.value})`, dir) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/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 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/compiler/directives/text.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { addProp } from 'compiler/helpers' 4 | 5 | export default function text (el: ASTElement, dir: ASTDirective) { 6 | if (dir.value) { 7 | addProp(el, 'textContent', `_s(${dir.value})`, dir) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/compiler/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { baseOptions } from './options' 4 | import { createCompiler } from 'compiler/index' 5 | 6 | const { compile, compileToFunctions } = createCompiler(baseOptions) 7 | 8 | export { compile, compileToFunctions } 9 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/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 res = parseText(staticClass, options.delimiters) 15 | if (res) { 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 | el.rawAttrsMap['class'] 22 | ) 23 | } 24 | } 25 | if (staticClass) { 26 | el.staticClass = JSON.stringify(staticClass) 27 | } 28 | const classBinding = getBindingAttr(el, 'class', false /* getStatic */) 29 | if (classBinding) { 30 | el.classBinding = classBinding 31 | } 32 | } 33 | 34 | function genData (el: ASTElement): string { 35 | let data = '' 36 | if (el.staticClass) { 37 | data += `staticClass:${el.staticClass},` 38 | } 39 | if (el.classBinding) { 40 | data += `class:${el.classBinding},` 41 | } 42 | return data 43 | } 44 | 45 | export default { 46 | staticKeys: ['staticClass'], 47 | transformNode, 48 | genData 49 | } 50 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/compiler/modules/index.js: -------------------------------------------------------------------------------- 1 | import klass from './class' 2 | import style from './style' 3 | import model from './model' 4 | 5 | export default [ 6 | klass, 7 | style, 8 | model 9 | ] 10 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/compiler/modules/style.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { parseText } from 'compiler/parser/text-parser' 4 | import { parseStyleText } from 'web/util/style' 5 | import { 6 | getAndRemoveAttr, 7 | getBindingAttr, 8 | baseWarn 9 | } from 'compiler/helpers' 10 | 11 | function transformNode (el: ASTElement, options: CompilerOptions) { 12 | const warn = options.warn || baseWarn 13 | const staticStyle = getAndRemoveAttr(el, 'style') 14 | if (staticStyle) { 15 | /* istanbul ignore if */ 16 | if (process.env.NODE_ENV !== 'production') { 17 | const res = parseText(staticStyle, options.delimiters) 18 | if (res) { 19 | warn( 20 | `style="${staticStyle}": ` + 21 | 'Interpolation inside attributes has been removed. ' + 22 | 'Use v-bind or the colon shorthand instead. For example, ' + 23 | 'instead of
, use
.', 24 | el.rawAttrsMap['style'] 25 | ) 26 | } 27 | } 28 | el.staticStyle = JSON.stringify(parseStyleText(staticStyle)) 29 | } 30 | 31 | const styleBinding = getBindingAttr(el, 'style', false /* getStatic */) 32 | if (styleBinding) { 33 | el.styleBinding = styleBinding 34 | } 35 | } 36 | 37 | function genData (el: ASTElement): string { 38 | let data = '' 39 | if (el.staticStyle) { 40 | data += `staticStyle:${el.staticStyle},` 41 | } 42 | if (el.styleBinding) { 43 | data += `style:(${el.styleBinding}),` 44 | } 45 | return data 46 | } 47 | 48 | export default { 49 | staticKeys: ['staticStyle'], 50 | transformNode, 51 | genData 52 | } 53 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/compiler/options.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { 4 | isPreTag, 5 | mustUseProp, 6 | isReservedTag, 7 | getTagNamespace 8 | } from '../util/index' 9 | 10 | import modules from './modules/index' 11 | import directives from './directives/index' 12 | import { genStaticKeys } from 'shared/util' 13 | import { isUnaryTag, canBeLeftOpenTag } from './util' 14 | 15 | export const baseOptions: CompilerOptions = { 16 | expectHTML: true, 17 | modules, 18 | directives, 19 | isPreTag, 20 | isUnaryTag, 21 | mustUseProp, 22 | canBeLeftOpenTag, 23 | isReservedTag, 24 | getTagNamespace, 25 | staticKeys: genStaticKeys(modules) 26 | } 27 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/compiler/util.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { makeMap } from 'shared/util' 4 | 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 | 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 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/entry-compiler.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | export { parseComponent } from 'sfc/parser' 4 | export { compile, compileToFunctions } from './compiler/index' 5 | export { ssrCompile, ssrCompileToFunctions } from './server/compiler' 6 | export { generateCodeFrame } from 'compiler/codeframe' 7 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/entry-runtime.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import Vue from './runtime/index' 4 | 5 | export default Vue 6 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/entry-server-basic-renderer.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import modules from './server/modules/index' 4 | import directives from './server/directives/index' 5 | import { isUnaryTag, canBeLeftOpenTag } from './compiler/util' 6 | import { createBasicRenderer } from 'server/create-basic-renderer' 7 | 8 | export default createBasicRenderer({ 9 | modules, 10 | directives, 11 | isUnaryTag, 12 | canBeLeftOpenTag 13 | }) 14 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/entry-server-renderer.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | process.env.VUE_ENV = 'server' 4 | 5 | import { extend } from 'shared/util' 6 | import modules from './server/modules/index' 7 | import baseDirectives from './server/directives/index' 8 | import { isUnaryTag, canBeLeftOpenTag } from './compiler/util' 9 | 10 | import { createRenderer as _createRenderer } from 'server/create-renderer' 11 | import { createBundleRendererCreator } from 'server/bundle-renderer/create-bundle-renderer' 12 | 13 | export function createRenderer (options?: Object = {}): { 14 | renderToString: Function, 15 | renderToStream: Function 16 | } { 17 | return _createRenderer(extend(extend({}, options), { 18 | isUnaryTag, 19 | canBeLeftOpenTag, 20 | modules, 21 | // user can provide server-side implementations for custom directives 22 | // when creating the renderer. 23 | directives: extend(baseDirectives, options.directives) 24 | })) 25 | } 26 | 27 | export const createBundleRenderer = createBundleRendererCreator(createRenderer) 28 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/runtime/class-util.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | const whitespaceRE = /\s+/ 4 | 5 | /** 6 | * Add class with compatibility for SVG since classList is not supported on 7 | * SVG elements in IE 8 | */ 9 | export function addClass (el: HTMLElement, cls: ?string) { 10 | /* istanbul ignore if */ 11 | if (!cls || !(cls = cls.trim())) { 12 | return 13 | } 14 | 15 | /* istanbul ignore else */ 16 | if (el.classList) { 17 | if (cls.indexOf(' ') > -1) { 18 | cls.split(whitespaceRE).forEach(c => el.classList.add(c)) 19 | } else { 20 | el.classList.add(cls) 21 | } 22 | } else { 23 | const cur = ` ${el.getAttribute('class') || ''} ` 24 | if (cur.indexOf(' ' + cls + ' ') < 0) { 25 | el.setAttribute('class', (cur + cls).trim()) 26 | } 27 | } 28 | } 29 | 30 | /** 31 | * Remove class with compatibility for SVG since classList is not supported on 32 | * SVG elements in IE 33 | */ 34 | export function removeClass (el: HTMLElement, cls: ?string) { 35 | /* istanbul ignore if */ 36 | if (!cls || !(cls = cls.trim())) { 37 | return 38 | } 39 | 40 | /* istanbul ignore else */ 41 | if (el.classList) { 42 | if (cls.indexOf(' ') > -1) { 43 | cls.split(whitespaceRE).forEach(c => el.classList.remove(c)) 44 | } else { 45 | el.classList.remove(cls) 46 | } 47 | if (!el.classList.length) { 48 | el.removeAttribute('class') 49 | } 50 | } else { 51 | let cur = ` ${el.getAttribute('class') || ''} ` 52 | const tar = ' ' + cls + ' ' 53 | while (cur.indexOf(tar) >= 0) { 54 | cur = cur.replace(tar, ' ') 55 | } 56 | cur = cur.trim() 57 | if (cur) { 58 | el.setAttribute('class', cur) 59 | } else { 60 | el.removeAttribute('class') 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/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 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/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 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/runtime/directives/show.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { enter, leave } from '../modules/transition' 4 | 5 | // recursively search for possible transition defined inside the component root 6 | function locateNode (vnode: VNode): VNodeWithData { 7 | return vnode.componentInstance && (!vnode.data || !vnode.data.transition) 8 | ? locateNode(vnode.componentInstance._vnode) 9 | : vnode 10 | } 11 | 12 | export default { 13 | bind (el: any, { value }: VNodeDirective, vnode: VNodeWithData) { 14 | vnode = locateNode(vnode) 15 | const transition = vnode.data && vnode.data.transition 16 | const originalDisplay = el.__vOriginalDisplay = 17 | el.style.display === 'none' ? '' : el.style.display 18 | if (value && transition) { 19 | vnode.data.show = true 20 | enter(vnode, () => { 21 | el.style.display = originalDisplay 22 | }) 23 | } else { 24 | el.style.display = value ? originalDisplay : 'none' 25 | } 26 | }, 27 | 28 | update (el: any, { value, oldValue }: VNodeDirective, vnode: VNodeWithData) { 29 | /* istanbul ignore if */ 30 | if (!value === !oldValue) return 31 | vnode = locateNode(vnode) 32 | const transition = vnode.data && vnode.data.transition 33 | if (transition) { 34 | vnode.data.show = true 35 | if (value) { 36 | enter(vnode, () => { 37 | el.style.display = el.__vOriginalDisplay 38 | }) 39 | } else { 40 | leave(vnode, () => { 41 | el.style.display = 'none' 42 | }) 43 | } 44 | } else { 45 | el.style.display = value ? el.__vOriginalDisplay : 'none' 46 | } 47 | }, 48 | 49 | unbind ( 50 | el: any, 51 | binding: VNodeDirective, 52 | vnode: VNodeWithData, 53 | oldVnode: VNodeWithData, 54 | isDestroy: boolean 55 | ) { 56 | if (!isDestroy) { 57 | el.style.display = el.__vOriginalDisplay 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/runtime/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import Vue from 'core/index' 4 | import config from 'core/config' 5 | import { extend, noop } from 'shared/util' 6 | import { mountComponent } from 'core/instance/lifecycle' 7 | import { devtools, inBrowser } from 'core/util/index' 8 | 9 | import { 10 | query, 11 | mustUseProp, 12 | isReservedTag, 13 | isReservedAttr, 14 | getTagNamespace, 15 | isUnknownElement 16 | } from 'web/util/index' 17 | 18 | import { patch } from './patch' 19 | import platformDirectives from './directives/index' 20 | import platformComponents from './components/index' 21 | 22 | // install platform specific utils 23 | Vue.config.mustUseProp = mustUseProp 24 | Vue.config.isReservedTag = isReservedTag 25 | Vue.config.isReservedAttr = isReservedAttr 26 | Vue.config.getTagNamespace = getTagNamespace 27 | Vue.config.isUnknownElement = isUnknownElement 28 | 29 | // install platform runtime directives & components 30 | extend(Vue.options.directives, platformDirectives) 31 | extend(Vue.options.components, platformComponents) 32 | 33 | // install platform patch function 34 | Vue.prototype.__patch__ = inBrowser ? patch : noop 35 | 36 | // public mount method 37 | Vue.prototype.$mount = function ( 38 | el?: string | Element, 39 | hydrating?: boolean 40 | ): Component { 41 | el = el && inBrowser ? query(el) : undefined 42 | return mountComponent(this, el, hydrating) 43 | } 44 | 45 | // devtools global hook 46 | /* istanbul ignore next */ 47 | if (inBrowser) { 48 | setTimeout(() => { 49 | if (config.devtools) { 50 | if (devtools) { 51 | devtools.emit('init', Vue) 52 | } else if ( 53 | process.env.NODE_ENV !== 'production' && 54 | process.env.NODE_ENV !== 'test' 55 | ) { 56 | console[console.info ? 'info' : 'log']( 57 | 'Download the Vue Devtools extension for a better development experience:\n' + 58 | 'https://github.com/vuejs/vue-devtools' 59 | ) 60 | } 61 | } 62 | if (process.env.NODE_ENV !== 'production' && 63 | process.env.NODE_ENV !== 'test' && 64 | config.productionTip !== false && 65 | typeof console !== 'undefined' 66 | ) { 67 | console[console.info ? 'info' : 'log']( 68 | `You are running Vue in development mode.\n` + 69 | `Make sure to turn on production mode when deploying for production.\n` + 70 | `See more tips at https://vuejs.org/guide/deployment.html` 71 | ) 72 | } 73 | }, 0) 74 | } 75 | 76 | export default Vue 77 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/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 | function updateClass (oldVnode: any, vnode: any) { 15 | const el = vnode.elm 16 | const data: VNodeData = vnode.data 17 | const oldData: VNodeData = oldVnode.data 18 | if ( 19 | isUndef(data.staticClass) && 20 | isUndef(data.class) && ( 21 | isUndef(oldData) || ( 22 | isUndef(oldData.staticClass) && 23 | isUndef(oldData.class) 24 | ) 25 | ) 26 | ) { 27 | return 28 | } 29 | 30 | let cls = genClassForVnode(vnode) 31 | 32 | // handle transition classes 33 | const transitionClass = el._transitionClasses 34 | if (isDef(transitionClass)) { 35 | cls = concat(cls, stringifyClass(transitionClass)) 36 | } 37 | 38 | // set the class 39 | if (cls !== el._prevClass) { 40 | el.setAttribute('class', cls) 41 | el._prevClass = cls 42 | } 43 | } 44 | 45 | export default { 46 | create: updateClass, 47 | update: updateClass 48 | } 49 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/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 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/runtime/node-ops.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { namespaceMap } from 'web/util/index' 4 | 5 | export function createElement (tagName: string, vnode: VNode): Element { 6 | const elm = document.createElement(tagName) 7 | if (tagName !== 'select') { 8 | return elm 9 | } 10 | // false or null will remove the attribute but undefined will not 11 | if (vnode.data && vnode.data.attrs && vnode.data.attrs.multiple !== undefined) { 12 | elm.setAttribute('multiple', 'multiple') 13 | } 14 | return elm 15 | } 16 | 17 | export function createElementNS (namespace: string, tagName: string): Element { 18 | return document.createElementNS(namespaceMap[namespace], tagName) 19 | } 20 | 21 | export function createTextNode (text: string): Text { 22 | return document.createTextNode(text) 23 | } 24 | 25 | export function createComment (text: string): Comment { 26 | return document.createComment(text) 27 | } 28 | 29 | export function insertBefore (parentNode: Node, newNode: Node, referenceNode: Node) { 30 | parentNode.insertBefore(newNode, referenceNode) 31 | } 32 | 33 | export function removeChild (node: Node, child: Node) { 34 | node.removeChild(child) 35 | } 36 | 37 | export function appendChild (node: Node, child: Node) { 38 | node.appendChild(child) 39 | } 40 | 41 | export function parentNode (node: Node): ?Node { 42 | return node.parentNode 43 | } 44 | 45 | export function nextSibling (node: Node): ?Node { 46 | return node.nextSibling 47 | } 48 | 49 | export function tagName (node: Element): string { 50 | return node.tagName 51 | } 52 | 53 | export function setTextContent (node: Node, text: string) { 54 | node.textContent = text 55 | } 56 | 57 | export function setStyleScope (node: Element, scopeId: string) { 58 | node.setAttribute(scopeId, '') 59 | } 60 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/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 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/server/compiler.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { baseOptions } from '../compiler/options' 4 | import { createCompiler } from 'server/optimizing-compiler/index' 5 | 6 | const { compile, compileToFunctions } = createCompiler(baseOptions) 7 | 8 | export { 9 | compile as ssrCompile, 10 | compileToFunctions as ssrCompileToFunctions 11 | } 12 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/server/directives/index.js: -------------------------------------------------------------------------------- 1 | import show from './show' 2 | import model from './model' 3 | 4 | export default { 5 | show, 6 | model 7 | } 8 | -------------------------------------------------------------------------------- /docs/vue/vue-2.6.0/src/platforms/web/server/directives/model.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | import { looseEqual, looseIndexOf } from 'shared/util' 4 | 5 | // this is only applied for