§ 参考
337 |-
338 |
- vuejs-templates/webpack for Vue 1.x 339 |
- vuejs-templates/webpack for Vue 2.x 340 |
- eteplus/vue-sui-demo 341 |
- kenberkeley/vue2-scaffold(Vue 2 脚手架) 342 |
├── .babelrc ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .nojekyll ├── LICENSE ├── README.md ├── build ├── config │ ├── ENV.js │ ├── PATHS.js │ ├── PORTS.js │ └── style-rules.js ├── dev.js ├── gulpfile.js ├── prod.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── dist ├── css │ └── app.0ad153.css ├── index.html ├── js │ ├── app.62bef8.js │ ├── manifest.b3d0c9.js │ └── vendor.05926d.js └── static │ ├── README.md │ ├── bootstrap │ ├── css │ │ └── bootstrap.min.css │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ └── js │ │ └── bootstrap.min.js │ ├── bundle │ ├── plugins-00354ef8eb.js │ └── plugins-839bf7d848.css │ ├── favicon.ico │ ├── font-awesome │ ├── css │ │ └── font-awesome.min.css │ └── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ └── jquery.min.js ├── docs ├── LANGS.md ├── _book │ ├── gitbook │ │ ├── fonts │ │ │ └── fontawesome │ │ │ │ ├── FontAwesome.otf │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ ├── fontawesome-webfont.svg │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ └── fontawesome-webfont.woff2 │ │ ├── gitbook-plugin-fontsettings │ │ │ ├── fontsettings.js │ │ │ └── website.css │ │ ├── gitbook-plugin-highlight │ │ │ ├── ebook.css │ │ │ └── website.css │ │ ├── gitbook-plugin-lunr │ │ │ ├── lunr.min.js │ │ │ └── search-lunr.js │ │ ├── gitbook-plugin-search │ │ │ ├── lunr.min.js │ │ │ ├── search-engine.js │ │ │ ├── search.css │ │ │ └── search.js │ │ ├── gitbook-plugin-sharing │ │ │ └── buttons.js │ │ ├── gitbook.js │ │ ├── images │ │ │ ├── apple-touch-icon-precomposed-152.png │ │ │ └── favicon.ico │ │ ├── style.css │ │ └── theme.js │ ├── index.html │ ├── search_index.json │ └── zh-cn │ │ ├── Features.html │ │ ├── Getting-started.html │ │ ├── Reference.html │ │ ├── Structure.html │ │ ├── development │ │ ├── Ajax-interface.html │ │ ├── Best-practice.html │ │ ├── CORS-and-Proxy.html │ │ ├── Configuration.html │ │ ├── Service-layer.html │ │ ├── State-management.html │ │ ├── URL-is-soul-of-SPA.html │ │ └── index.html │ │ ├── index.html │ │ └── search_index.json └── zh-cn │ ├── Features.md │ ├── Getting-started.md │ ├── README.md │ ├── Reference.md │ ├── SUMMARY.md │ ├── Structure.md │ └── development │ ├── Ajax-interface.md │ ├── Best-practice.md │ ├── CORS-and-Proxy.md │ ├── Configuration.md │ ├── README.md │ ├── Service-layer.md │ ├── State-management.md │ └── URL-is-soul-of-SPA.md ├── mock ├── browser-xhr.js ├── controllers │ ├── auth.js │ └── msg.js ├── db │ └── index.js ├── middlewares │ ├── interceptor.js │ ├── notFound.js │ ├── res.ajaxReturn.js │ └── simpleLogger.js ├── node-app.js └── routes │ └── index.js ├── package.json ├── screenshot.png ├── src ├── app.js ├── assets │ ├── README.md │ ├── css │ │ └── common.css │ ├── img │ │ ├── larger.png │ │ └── smaller.png │ ├── less │ │ └── normalize.less │ └── scss │ │ └── normalize.scss ├── components │ ├── App.vue │ ├── Breadcrumb.vue │ ├── Navbar.vue │ ├── Pagination.vue │ ├── Select │ │ ├── LimitSelect.vue │ │ └── Select2.vue │ └── Sidebar │ │ ├── Link.vue │ │ └── index.vue ├── filters │ ├── dateTimeFormatter.js │ └── index.js ├── index.html ├── mixins │ ├── autoSyncWithQuery.js │ └── updateQuery.js ├── routes │ ├── hooks │ │ ├── afterEach │ │ │ ├── docTitleReplacer.js │ │ │ ├── scrollToTop.js │ │ │ └── simpleLogger.js │ │ ├── beforeEach │ │ │ └── authInterceptor.js │ │ └── index.js │ ├── index.js │ └── map │ │ ├── auth.js │ │ ├── index.js │ │ └── msg.js ├── services │ ├── authService.js │ ├── msgService.js │ └── xhr │ │ ├── index.js │ │ └── jquery.js ├── utils │ ├── trimQs.js │ └── updateQuery.js └── views │ ├── auth │ ├── login.vue │ └── logout.vue │ ├── index.vue │ └── msg │ ├── _components │ ├── AuthorSelect.vue │ ├── MsgForm.vue │ └── OptBtnGroup.vue │ ├── _mixins │ └── autoLoadByParams.js │ ├── add.vue │ ├── detail.vue │ ├── index.vue │ ├── list.vue │ └── update.vue └── static ├── README.md ├── bootstrap ├── css │ └── bootstrap.min.css ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 └── js │ └── bootstrap.min.js ├── favicon.ico ├── font-awesome ├── css │ └── font-awesome.min.css └── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ └── fontawesome-webfont.woff2 ├── jquery.min.js └── plugins ├── jquery.ajax.loading.js ├── jquery.scrollTo.min.js ├── jquery.toast ├── README.md ├── jquery.toast.min.css └── jquery.toast.min.js ├── moment.min.js ├── select2 ├── select2.min.css └── select2.min.js └── sweetalert ├── sweetalert.css └── sweetalert.min.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2"], 3 | "plugins": ["transform-runtime"], 4 | "comments": false 5 | } 6 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | src/assets/** 2 | static/** 3 | node_modules/** 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "node": true 5 | }, 6 | "globals": { 7 | "__DEV__": false, 8 | "__PROD__": false, 9 | "$": true 10 | }, 11 | "ecmaFeatures": { 12 | "arrowFunctions": true, 13 | "destructuring": true, 14 | "classes": true, 15 | "defaultParams": true, 16 | "blockBindings": true, 17 | "modules": true, 18 | "objectLiteralComputedProperties": true, 19 | "objectLiteralShorthandMethods": true, 20 | "objectLiteralShorthandProperties": true, 21 | "restParams": true, 22 | "spread": true, 23 | "forOf": true, 24 | "generators": true, 25 | "templateStrings": true, 26 | "superInFunctions": true, 27 | "experimentalObjectRestSpread": true 28 | }, 29 | "rules": { 30 | "accessor-pairs": 2, 31 | "array-bracket-spacing": 2, 32 | "block-scoped-var": 0, 33 | "brace-style": [0, "allman", { "allowSingleLine": true }], 34 | "camelcase": 1, 35 | "comma-dangle": [2, "never"], 36 | "comma-spacing": [2, { "before": false, "after": true }], 37 | "comma-style": [2, "last"], 38 | "complexity": 0, 39 | "computed-property-spacing": 0, 40 | "consistent-return": 0, 41 | "consistent-this": 0, 42 | "constructor-super": 2, 43 | "curly": [0, "multi-line"], 44 | "default-case": 0, 45 | "dot-location": [2, "property"], 46 | "dot-notation": 0, 47 | "eol-last": 2, 48 | "eqeqeq": [2, "allow-null"], 49 | "func-names": 0, 50 | "func-style": 0, 51 | "generator-star-spacing": [2, { "before": true, "after": true }], 52 | "guard-for-in": 0, 53 | "handle-callback-err": [2, "^(err|error)$" ], 54 | "indent": 0, 55 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }], 56 | "linebreak-style": 0, 57 | "lines-around-comment": 0, 58 | "max-nested-callbacks": 0, 59 | "new-cap": [2, { "newIsCap": true, "capIsNew": false }], 60 | "new-parens": 2, 61 | "newline-after-var": 0, 62 | "no-alert": 0, 63 | "no-array-constructor": 2, 64 | "no-caller": 2, 65 | "no-catch-shadow": 0, 66 | "no-cond-assign": 2, 67 | "no-console": 0, 68 | "no-constant-condition": 0, 69 | "no-continue": 0, 70 | "no-control-regex": 2, 71 | "no-debugger": 2, 72 | "no-delete-var": 2, 73 | "no-div-regex": 0, 74 | "no-dupe-args": 2, 75 | "no-dupe-keys": 2, 76 | "no-duplicate-case": 2, 77 | "no-else-return": 0, 78 | "no-empty": 0, 79 | "no-empty-character-class": 2, 80 | "no-empty-label": 2, 81 | "no-eq-null": 0, 82 | "no-eval": 2, 83 | "no-ex-assign": 2, 84 | "no-extend-native": 2, 85 | "no-extra-bind": 2, 86 | "no-extra-boolean-cast": 2, 87 | "no-extra-parens": 0, 88 | "no-extra-semi": 0, 89 | "no-fallthrough": 2, 90 | "no-floating-decimal": 2, 91 | "no-func-assign": 2, 92 | "no-implied-eval": 2, 93 | "no-inline-comments": 0, 94 | "no-inner-declarations": [2, "functions"], 95 | "no-invalid-regexp": 2, 96 | "no-irregular-whitespace": 2, 97 | "no-iterator": 2, 98 | "no-label-var": 2, 99 | "no-labels": 2, 100 | "no-lone-blocks": 2, 101 | "no-lonely-if": 0, 102 | "no-loop-func": 0, 103 | "no-mixed-requires": 0, 104 | "no-mixed-spaces-and-tabs": 2, 105 | "no-multi-spaces": 2, 106 | "no-multi-str": 2, 107 | "no-multiple-empty-lines": [0, { "max": 1 }], 108 | "no-native-reassign": 2, 109 | "no-negated-in-lhs": 2, 110 | "no-nested-ternary": 0, 111 | "no-new": 2, 112 | "no-new-func": 0, 113 | "no-new-object": 2, 114 | "no-new-require": 2, 115 | "no-new-wrappers": 2, 116 | "no-obj-calls": 2, 117 | "no-octal": 2, 118 | "no-octal-escape": 2, 119 | "no-param-reassign": 0, 120 | "no-path-concat": 0, 121 | "no-process-env": 0, 122 | "no-process-exit": 0, 123 | "no-proto": 0, 124 | "no-redeclare": 2, 125 | "no-regex-spaces": 2, 126 | "no-restricted-modules": 0, 127 | "no-return-assign": 0, 128 | "no-script-url": 0, 129 | "no-self-compare": 2, 130 | "no-sequences": 2, 131 | "no-shadow": 0, 132 | "no-shadow-restricted-names": 2, 133 | "no-spaced-func": 2, 134 | "no-sparse-arrays": 2, 135 | "no-sync": 0, 136 | "no-ternary": 0, 137 | "no-this-before-super": 2, 138 | "no-throw-literal": 2, 139 | "no-trailing-spaces": 0, 140 | "no-undef": 2, 141 | "no-undef-init": 2, 142 | "no-undefined": 0, 143 | "no-underscore-dangle": 0, 144 | "no-unexpected-multiline": 2, 145 | "no-unneeded-ternary": 2, 146 | "no-unreachable": 2, 147 | "no-unused-expressions": 0, 148 | "no-unused-vars": [2, { "vars": "all", "args": "none" }], 149 | "no-use-before-define": 0, 150 | "no-var": 0, 151 | "no-void": 0, 152 | "no-warning-comments": 0, 153 | "no-with": 2, 154 | "object-curly-spacing": 0, 155 | "object-shorthand": 0, 156 | "one-var": [2, { "initialized": "never" }], 157 | "operator-assignment": 0, 158 | "operator-linebreak": [2, "after", { "overrides": { "?": "before", ":": "before" } }], 159 | "padded-blocks": 0, 160 | "prefer-const": 0, 161 | "quote-props": 0, 162 | "quotes": [2, "single", "avoid-escape"], 163 | "radix": 2, 164 | "semi": [2, "never"], 165 | "semi-spacing": 0, 166 | "sort-vars": 0, 167 | "space-after-keywords": [2, "always"], 168 | "space-before-blocks": [2, "always"], 169 | "space-before-function-paren": 0, 170 | "space-in-parens": [2, "never"], 171 | "space-infix-ops": 2, 172 | "space-return-throw-case": 2, 173 | "space-unary-ops": [2, { "words": true, "nonwords": false }], 174 | "spaced-comment": [2, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!"] }], 175 | "strict": 0, 176 | "use-isnan": 2, 177 | "valid-jsdoc": 0, 178 | "valid-typeof": 2, 179 | "vars-on-top": 0, 180 | "wrap-iife": [2, "any"], 181 | "wrap-regex": 0, 182 | "yoda": [2, "never"] 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | db.json 2 | .DS_Store 3 | *.log 4 | coverage 5 | node_modules 6 | -------------------------------------------------------------------------------- /.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thisislys/messageBoard-vue/5d0fefc1abc3c5ed2a648d2639bf7a254bfb60ac/.nojekyll -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | Copyright 2016 Ken Berkeley 180 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vue 示例项目 · 简易留言板 2 | 3 |  4 | -------------------------------------------------------------------------------- /build/config/ENV.js: -------------------------------------------------------------------------------- 1 | var env = (process.env.NODE_ENV || 'development').trim(); 2 | console.log('[Current environment]', env); 3 | 4 | module.exports = { 5 | __ENV__: env, 6 | __DEV__: env === 'development', 7 | __PROD__: env === 'production' 8 | }; 9 | -------------------------------------------------------------------------------- /build/config/PATHS.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | /** 4 | * 便捷求取路径原型函数 5 | * @param {String} target 6 | * @return {String} path to target 7 | */ 8 | String.prototype.join = function (target) { 9 | return path.join(this.toString(), target); 10 | }; 11 | 12 | var ROOT = path.resolve(__dirname, '../..'); 13 | 14 | module.exports = { 15 | ROOT: ROOT, // 项目根目录 16 | BUILD: ROOT.join('build'), // 构建工具配置目录 17 | DIST: ROOT.join('dist'), // build 后输出目录 18 | DOCS: ROOT.join('docs/_book'), // build 后的文档 19 | MOCK: ROOT.join('mock'), // Mock Server 目录 20 | SRC: ROOT.join('src'), // 源码目录 21 | STATIC: ROOT.join('static') // 高度静态资源目录 22 | }; 23 | -------------------------------------------------------------------------------- /build/config/PORTS.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | BROWSER_SYNC: 8080, // BrowserSync 调试服务器 3 | DEV_SERVER: 8000, // Express + Webpack 热替换开发服务器,且提供静态资源支持 4 | MOCK_SERVER: 8989 // RESTful API Mock 服务器 5 | }; 6 | -------------------------------------------------------------------------------- /build/config/style-rules.js: -------------------------------------------------------------------------------- 1 | var extract = require('extract-text-webpack-plugin').extract, 2 | ENV = require('./ENV'); 3 | 4 | var basicLoaders = ['css']; 5 | var LOADERS = { 6 | css: basicLoaders, 7 | less: basicLoaders.concat('less'), 8 | sass: basicLoaders.concat('sass?indentedSyntax=true'), 9 | scss: basicLoaders.concat('sass') 10 | }; 11 | 12 | function ruleGen(ext, isForVueLoader) { 13 | var useLoaders = LOADERS[ext]; 14 | if (isForVueLoader) return extract('vue-style', useLoaders.join('!')); 15 | 16 | // 开发环境下直接内嵌 CSS 以支持热替换 17 | if (ENV.__DEV__) return ['style'].concat(useLoaders).join('!'); 18 | // 生产环境下分离出 CSS 文件 19 | return extract('style', useLoaders.join('!')); 20 | } 21 | 22 | function styleRulesGen(isForVueLoader) { 23 | var rules = isForVueLoader ? {} : []; 24 | Object.keys(LOADERS).forEach(function (ext) { 25 | isForVueLoader ? 26 | rules[ext] = ruleGen(ext, true) : 27 | rules.push({ test: new RegExp('\\.' + ext + '$'), loader: ruleGen(ext) }); 28 | }); 29 | return rules; 30 | } 31 | 32 | exports.basic = styleRulesGen(); 33 | exports.vueLoader = styleRulesGen(true); 34 | -------------------------------------------------------------------------------- /build/dev.js: -------------------------------------------------------------------------------- 1 | var express = require('express'), 2 | webpack = require('webpack'), 3 | PATHS = require('./config/PATHS'), 4 | PORTS = require('./config/PORTS'), 5 | config = require('./webpack.dev.conf'), 6 | proxy = require('http-proxy-middleware'), 7 | app = express(); 8 | 9 | var compiler = webpack(config); 10 | 11 | // 提供静态资源服务 12 | app.use('/static', express.static(PATHS.STATIC)); 13 | 14 | // Mock server 15 | require(PATHS.MOCK.join('node-app')).listen(PORTS.MOCK_SERVER); 16 | app.use('/api', proxy({ 17 | target: 'http://127.0.0.1:' + PORTS.MOCK_SERVER, 18 | changeOrigin: true, 19 | pathRewrite: { 20 | // 重写 URL:[Dev Server]/api/xxx <=> [Mock Server]/xxx 21 | '^/api': '/' 22 | } 23 | })); 24 | 25 | // handle fallback for HTML5 history API 26 | app.use(require('connect-history-api-fallback')()); 27 | 28 | // serve webpack bundle output 29 | app.use(require('webpack-dev-middleware')(compiler, { 30 | noInfo: true, 31 | publicPath: config.output.publicPath 32 | })); 33 | 34 | // enable hot-reload and state-preserving 35 | // compilation error display 36 | app.use(require('webpack-hot-middleware')(compiler)); 37 | 38 | app.listen(PORTS.DEV_SERVER); 39 | -------------------------------------------------------------------------------- /build/gulpfile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @export {gulp} 3 | * 1. gulp.start('default') 4 | * 2. 命令行执行 gulp 5 | */ 6 | var gulp = require('gulp'), 7 | fs = require('fs-extra'), 8 | rev = require('gulp-rev'), 9 | csso = require('gulp-csso'), 10 | filter = require('gulp-filter'), 11 | uglify = require('gulp-uglify'), 12 | useref = require('gulp-useref'), 13 | revReplace = require('gulp-rev-replace'), 14 | PATHS = require('./config/PATHS'); 15 | 16 | // 合并压缩打包 index.html 中 build 标签内的资源 17 | gulp.task('bundle', function () { 18 | var jsFilter = filter('**/*.js', { restore: true }), 19 | cssFilter = filter('**/*.css', { restore: true }), 20 | userefAssets = useref.assets(); 21 | 22 | return gulp.src(PATHS.DIST.join('index.html')) 23 | .pipe(userefAssets) 24 | .pipe(jsFilter) 25 | .pipe(uglify()) 26 | .pipe(jsFilter.restore) 27 | .pipe(cssFilter) 28 | .pipe(csso()) 29 | .pipe(cssFilter.restore) 30 | .pipe(rev()) 31 | .pipe(userefAssets.restore()) 32 | .pipe(useref()) 33 | .pipe(revReplace()) 34 | .pipe(gulp.dest(PATHS.DIST)); 35 | }); 36 | 37 | // 由于插件均被合并压缩打包,故可删除以减少生产环境下的文件量 38 | gulp.task('clean', ['bundle'], function () { 39 | fs.remove(PATHS.DIST.join('static/plugins')); 40 | }); 41 | 42 | gulp.task('default', ['bundle', 'clean']); 43 | 44 | if (module.parent) { 45 | module.exports = gulp; 46 | } else { 47 | gulp.start('default'); 48 | } 49 | -------------------------------------------------------------------------------- /build/prod.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs-extra'), 2 | webpack = require('webpack'), 3 | gulp = require('./gulpfile'), 4 | PATHS = require('./config/PATHS'), 5 | config = require('./webpack.prod.conf'); 6 | 7 | fs.emptyDirSync(PATHS.DIST); // 清空 build 目录 8 | fs.copySync(PATHS.STATIC, PATHS.DIST.join('static')); // 复制高度静态资源 9 | 10 | webpack(config, function(err, stats) { 11 | // show build info to console 12 | console.log(stats.toString({ chunks: false, color: true })); 13 | 14 | // save build info to file 15 | // fs.writeFile( 16 | // PATHS.DIST.join('__build_info__'), 17 | // stats.toString({ color: false }) 18 | // ); 19 | 20 | // bundle plugins 21 | gulp.start('default'); 22 | }); 23 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'), 2 | ENV = require('./config/ENV'), 3 | PATHS = require('./config/PATHS'), 4 | styleRules = require('./config/style-rules'), 5 | HtmlWebpackPlugin = require('html-webpack-plugin'), 6 | NyanProgressPlugin = require('nyan-progress-webpack-plugin'); 7 | 8 | module.exports = { 9 | entry: { 10 | app: PATHS.SRC.join('app.js') 11 | }, 12 | // devtool - source map 配置详见 http://webpack.github.io/docs/configuration.html#devtool 13 | devtools: false, 14 | output: { 15 | path: PATHS.DIST, 16 | publicPath: '' 17 | }, 18 | resolve: { 19 | extensions: ['', '.js', '.vue'], 20 | alias: { 21 | // 自定义路径别名 22 | MOCK: PATHS.MOCK, 23 | '@': PATHS.SRC 24 | } 25 | }, 26 | resolveLoader: { 27 | root: PATHS.ROOT.join('node_modules') 28 | }, 29 | module: { 30 | loaders: [{ 31 | test: /\.vue$/, 32 | loader: 'vue' 33 | }, { 34 | test: /\.js$/, 35 | loader: 'babel!eslint', 36 | include: PATHS.SRC, 37 | exclude: /node_modules/ 38 | }, { 39 | test: /\.json$/, 40 | loader: 'json' 41 | }, { 42 | test: /\.html$/, 43 | loader: 'html' 44 | }, { 45 | test: /\.(png|jpe?g|gif|svg)$/, 46 | loader: 'url', 47 | query: { 48 | limit: 10240, // 10KB 以下使用 base64 49 | name: 'img/[name]-[hash:6].[ext]' 50 | } 51 | }, { 52 | test: /\.(woff2?|eot|ttf|otf)$/, 53 | loader: 'url-loader?limit=10240&name=fonts/[name]-[hash:6].[ext]' 54 | }].concat(styleRules.basic) 55 | }, 56 | vue: { 57 | loaders: Object.assign({ 58 | js: 'babel!eslint' 59 | }, styleRules.vueLoader) 60 | }, 61 | eslint: { 62 | formatter: require('eslint-friendly-formatter') 63 | }, 64 | plugins: [ 65 | new NyanProgressPlugin(), // 进度条 66 | new webpack.DefinePlugin(Object.assign({ 67 | 'process.env.NODE_ENV': JSON.stringify(ENV.__ENV__) 68 | }, ENV)), 69 | new webpack.optimize.CommonsChunkPlugin({ 70 | name: 'vendor', 71 | minChunks: function (module) { 72 | return module.context && module.context.indexOf('node_modules') !== -1; 73 | } 74 | }), 75 | new HtmlWebpackPlugin({ 76 | filename: 'index.html', 77 | template: PATHS.SRC.join('index.html') 78 | }) 79 | ] 80 | }; 81 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'), 2 | PATHS = require('./config/PATHS'), 3 | PORTS = require('./config/PORTS'), 4 | config = require('./webpack.base.conf'), 5 | ExtractTextPlugin = require('extract-text-webpack-plugin'), 6 | BrowserSyncPlugin = require('browser-sync-webpack-plugin'); 7 | 8 | config.output.filename = '[name].js'; 9 | config.output.chunkFilename = '[id].js'; 10 | 11 | // add hot-reload related code to entry chunk 12 | config.entry.app = [ 13 | 'eventsource-polyfill', 14 | 'webpack-hot-middleware/client?reload=true', 15 | config.entry.app 16 | ]; 17 | 18 | config.plugins.push( 19 | new webpack.HotModuleReplacementPlugin(), 20 | new webpack.NoErrorsPlugin(), 21 | new ExtractTextPlugin('[name].css'), 22 | new BrowserSyncPlugin({ 23 | host: 'localhost', 24 | port: PORTS.BROWSER_SYNC, 25 | proxy: 'localhost:' + PORTS.DEV_SERVER, 26 | notify: false 27 | }, { 28 | reload: false 29 | }) 30 | ); 31 | 32 | module.exports = config; 33 | -------------------------------------------------------------------------------- /build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'), 2 | PATHS = require('./config/PATHS'), 3 | config = require('./webpack.base.conf'), 4 | ExtractTextPlugin = require('extract-text-webpack-plugin'), 5 | OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); 6 | 7 | config.output.filename = 'js/[name].[chunkhash:6].js'; 8 | config.output.chunkFilename = 'js/[id].[chunkhash:6].js'; 9 | 10 | config.plugins.push( 11 | new webpack.optimize.DedupePlugin(), 12 | new webpack.optimize.OccurenceOrderPlugin(), 13 | new webpack.optimize.UglifyJsPlugin({ 14 | compress: { warnings: false } 15 | }), 16 | new webpack.optimize.CommonsChunkPlugin({ 17 | name: 'manifest', 18 | minChunks: Infinity 19 | }), 20 | new webpack.optimize.AggressiveMergingPlugin(), 21 | new webpack.optimize.MinChunkSizePlugin({ 22 | minChunkSize: 30000 23 | }), 24 | new ExtractTextPlugin('css/[name].[contenthash:6].css', { 25 | allChunks : true // 若要按需加载 CSS 则请注释掉该行 26 | }), 27 | new OptimizeCssAssetsPlugin() // 优化 CSS(去重/压缩) 28 | ); 29 | 30 | module.exports = config; 31 | -------------------------------------------------------------------------------- /dist/css/app.0ad153.css: -------------------------------------------------------------------------------- 1 | .m-0-auto{margin:0 auto}.m-0{margin:0}.m-r-5{margin-right:5px}.m-t-5{margin-top:5px}.p-0{padding:0}.w-100pct{width:100%}.min-h-180{min-height:180px}.line-h-150{line-height:150px}.italic{font-style:italic}.nowrap{white-space:nowrap}.inline-select{display:inline-block;width:45%}.clickable{cursor:pointer}.clickable:hover{background-color:#dadada}.clickable:active:{background-color:blue}.unselectable{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.min-h-160{min-height:160px}.max-h-300{max-height:300px}.overflow-fix{overflow-x:hidden;overflow-y:auto}.p-10{padding:10px}.m-t-100{margin-top:100px!important}.w-60p{width:60%}.terminal{padding:30px;font-size:3em;color:#a6e22e;text-align:center;background-color:#23241f}.p-5{padding:5px}.p-15{padding:15px}.main-content{min-height:300px;background-color:#f7f7f7;border-radius:5px}.fade-transition{transition:opacity .1s ease}.fade-enter,.fade-leave{opacity:0}.w-90p{width:90%}.m-t-0{margin-top:0!important}.vlink:hover{color:orange;background-color:#3071a9}.matched-route{color:#fff!important;background-color:#31b0d5!important} -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |').html(content); 65 | 66 | $link.appendTo($title); 67 | $title.appendTo($li); 68 | $content.appendTo($li); 69 | $li.appendTo($searchList); 70 | }); 71 | } 72 | 73 | function launchSearch(q) { 74 | // Add class for loading 75 | $body.addClass('with-search'); 76 | $body.addClass('search-loading'); 77 | 78 | // Launch search query 79 | throttle(gitbook.search.query(q, 0, MAX_RESULTS) 80 | .then(function(results) { 81 | displayResults(results); 82 | }) 83 | .always(function() { 84 | $body.removeClass('search-loading'); 85 | }), 1000); 86 | } 87 | 88 | function closeSearch() { 89 | $body.removeClass('with-search'); 90 | $bookSearchResults.removeClass('open'); 91 | } 92 | 93 | function launchSearchFromQueryString() { 94 | var q = getParameterByName('q'); 95 | if (q && q.length > 0) { 96 | // Update search input 97 | $searchInput.val(q); 98 | 99 | // Launch search 100 | launchSearch(q); 101 | } 102 | } 103 | 104 | function bindSearch() { 105 | // Bind DOM 106 | $searchInput = $('#book-search-input input'); 107 | $bookSearchResults = $('#book-search-results'); 108 | $searchList = $bookSearchResults.find('.search-results-list'); 109 | $searchTitle = $bookSearchResults.find('.search-results-title'); 110 | $searchResultsCount = $searchTitle.find('.search-results-count'); 111 | $searchQuery = $searchTitle.find('.search-query'); 112 | 113 | // Launch query based on input content 114 | function handleUpdate() { 115 | var q = $searchInput.val(); 116 | 117 | if (q.length == 0) { 118 | closeSearch(); 119 | } 120 | else { 121 | launchSearch(q); 122 | } 123 | } 124 | 125 | // Detect true content change in search input 126 | // Workaround for IE < 9 127 | var propertyChangeUnbound = false; 128 | $searchInput.on('propertychange', function(e) { 129 | if (e.originalEvent.propertyName == 'value') { 130 | handleUpdate(); 131 | } 132 | }); 133 | 134 | // HTML5 (IE9 & others) 135 | $searchInput.on('input', function(e) { 136 | // Unbind propertychange event for IE9+ 137 | if (!propertyChangeUnbound) { 138 | $(this).unbind('propertychange'); 139 | propertyChangeUnbound = true; 140 | } 141 | 142 | handleUpdate(); 143 | }); 144 | 145 | // Push to history on blur 146 | $searchInput.on('blur', function(e) { 147 | // Update history state 148 | if (usePushState) { 149 | var uri = updateQueryString('q', $(this).val()); 150 | history.pushState({ path: uri }, null, uri); 151 | } 152 | }); 153 | } 154 | 155 | gitbook.events.on('page.change', function() { 156 | bindSearch(); 157 | closeSearch(); 158 | 159 | // Launch search based on query parameter 160 | if (gitbook.search.isInitialized()) { 161 | launchSearchFromQueryString(); 162 | } 163 | }); 164 | 165 | gitbook.events.on('search.ready', function() { 166 | bindSearch(); 167 | 168 | // Launch search from query param at start 169 | launchSearchFromQueryString(); 170 | }); 171 | 172 | function getParameterByName(name) { 173 | var url = window.location.href; 174 | name = name.replace(/[\[\]]/g, '\\$&'); 175 | var regex = new RegExp('[?&]' + name + '(=([^]*)|&|#|$)', 'i'), 176 | results = regex.exec(url); 177 | if (!results) return null; 178 | if (!results[2]) return ''; 179 | return decodeURIComponent(results[2].replace(/\+/g, ' ')); 180 | } 181 | 182 | function updateQueryString(key, value) { 183 | value = encodeURIComponent(value); 184 | 185 | var url = window.location.href; 186 | var re = new RegExp('([?&])' + key + '=.*?(&|#|$)(.*)', 'gi'), 187 | hash; 188 | 189 | if (re.test(url)) { 190 | if (typeof value !== 'undefined' && value !== null) 191 | return url.replace(re, '$1' + key + '=' + value + '$2$3'); 192 | else { 193 | hash = url.split('#'); 194 | url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, ''); 195 | if (typeof hash[1] !== 'undefined' && hash[1] !== null) 196 | url += '#' + hash[1]; 197 | return url; 198 | } 199 | } 200 | else { 201 | if (typeof value !== 'undefined' && value !== null) { 202 | var separator = url.indexOf('?') !== -1 ? '&' : '?'; 203 | hash = url.split('#'); 204 | url = hash[0] + separator + key + '=' + value; 205 | if (typeof hash[1] !== 'undefined' && hash[1] !== null) 206 | url += '#' + hash[1]; 207 | return url; 208 | } 209 | else 210 | return url; 211 | } 212 | } 213 | }); 214 | -------------------------------------------------------------------------------- /docs/_book/gitbook/gitbook-plugin-sharing/buttons.js: -------------------------------------------------------------------------------- 1 | require(['gitbook', 'jquery'], function(gitbook, $) { 2 | var SITES = { 3 | 'facebook': { 4 | 'label': 'Facebook', 5 | 'icon': 'fa fa-facebook', 6 | 'onClick': function(e) { 7 | e.preventDefault(); 8 | window.open('http://www.facebook.com/sharer/sharer.php?s=100&p[url]='+encodeURIComponent(location.href)); 9 | } 10 | }, 11 | 'twitter': { 12 | 'label': 'Twitter', 13 | 'icon': 'fa fa-twitter', 14 | 'onClick': function(e) { 15 | e.preventDefault(); 16 | window.open('http://twitter.com/home?status='+encodeURIComponent(document.title+' '+location.href)); 17 | } 18 | }, 19 | 'google': { 20 | 'label': 'Google+', 21 | 'icon': 'fa fa-google-plus', 22 | 'onClick': function(e) { 23 | e.preventDefault(); 24 | window.open('https://plus.google.com/share?url='+encodeURIComponent(location.href)); 25 | } 26 | }, 27 | 'weibo': { 28 | 'label': 'Weibo', 29 | 'icon': 'fa fa-weibo', 30 | 'onClick': function(e) { 31 | e.preventDefault(); 32 | window.open('http://service.weibo.com/share/share.php?content=utf-8&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)); 33 | } 34 | }, 35 | 'instapaper': { 36 | 'label': 'Instapaper', 37 | 'icon': 'fa fa-instapaper', 38 | 'onClick': function(e) { 39 | e.preventDefault(); 40 | window.open('http://www.instapaper.com/text?u='+encodeURIComponent(location.href)); 41 | } 42 | }, 43 | 'vk': { 44 | 'label': 'VK', 45 | 'icon': 'fa fa-vk', 46 | 'onClick': function(e) { 47 | e.preventDefault(); 48 | window.open('http://vkontakte.ru/share.php?url='+encodeURIComponent(location.href)); 49 | } 50 | } 51 | }; 52 | 53 | 54 | 55 | gitbook.events.bind('start', function(e, config) { 56 | var opts = config.sharing; 57 | 58 | // Create dropdown menu 59 | var menu = $.map(opts.all, function(id) { 60 | var site = SITES[id]; 61 | 62 | return { 63 | text: site.label, 64 | onClick: site.onClick 65 | }; 66 | }); 67 | 68 | // Create main button with dropdown 69 | if (menu.length > 0) { 70 | gitbook.toolbar.createButton({ 71 | icon: 'fa fa-share-alt', 72 | label: 'Share', 73 | position: 'right', 74 | dropdown: [menu] 75 | }); 76 | } 77 | 78 | // Direct actions to share 79 | $.each(SITES, function(sideId, site) { 80 | if (!opts[sideId]) return; 81 | 82 | gitbook.toolbar.createButton({ 83 | icon: site.icon, 84 | label: site.text, 85 | position: 'right', 86 | onClick: site.onClick 87 | }); 88 | }); 89 | }); 90 | }); 91 | -------------------------------------------------------------------------------- /docs/_book/gitbook/images/apple-touch-icon-precomposed-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thisislys/messageBoard-vue/5d0fefc1abc3c5ed2a648d2639bf7a254bfb60ac/docs/_book/gitbook/images/apple-touch-icon-precomposed-152.png -------------------------------------------------------------------------------- /docs/_book/gitbook/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thisislys/messageBoard-vue/5d0fefc1abc3c5ed2a648d2639bf7a254bfb60ac/docs/_book/gitbook/images/favicon.ico -------------------------------------------------------------------------------- /docs/_book/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 |Zero
112 |One
113 |Two
114 |{{ text }}
125 |npm start
9 |
10 |
11 |
12 |
13 |
14 | npm run build
17 |
18 |
19 |
20 |
21 | Vue
24 |
25 |
26 |
27 |
28 | {{ msg.content }}
16 |' + opts.tip + '