├── .babelrc ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── LICENSE ├── README.md ├── build ├── build.js ├── dev-client.js ├── dev-server.js ├── utils.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── config ├── dev.env.js ├── index.js ├── prod.env.js └── test.env.js ├── index.html ├── package.json ├── src ├── components │ ├── Assistant.vue │ ├── DataTable.vue │ ├── Nav.vue │ ├── Predictor.vue │ └── SearchBar.vue ├── config │ ├── doc.js │ ├── settings.js │ └── tag.js ├── iconfont │ ├── iconfont.css │ ├── iconfont.eot │ ├── iconfont.svg │ ├── iconfont.ttf │ └── iconfont.woff ├── images │ └── logo.png ├── main.js ├── routers │ └── route.js ├── utils │ └── utils.js └── views │ ├── App.vue │ ├── Detail.vue │ ├── Dev.vue │ ├── Index.vue │ └── Settings.vue └── static ├── .gitkeep ├── highlight.pack.js └── tomorrow-night-eighties.css /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2"], 3 | "plugins": ["transform-runtime"], 4 | "comments": false 5 | } 6 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 4 | extends: 'standard', 5 | // required to lint *.vue files 6 | plugins: [ 7 | 'html' 8 | ], 9 | // add your custom rules here 10 | 'rules': { 11 | // allow paren-less arrow functions 12 | 'arrow-parens': 0, 13 | // allow debugger during development 14 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log 5 | selenium-debug.log 6 | test/unit/coverage 7 | test/e2e/reports 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ##Vue Problems and Solutions 2 | 3 | [Demo](http://qianjiahao.github.io/vue-problems-and-solutions/#!/) 4 | 5 | 更新日志 6 | 2016-6-15 7 | 8 | - 加入scan看图模式 9 | - 修复小bug 10 | 11 | 2016-6-14 12 | 13 | - 加入highlight 优化代码片段的展示 14 | 15 | 2016-6-12 16 | 17 | - 增加分享功能 18 | - 优化了搜索框和数据展示样式 19 | 20 | 21 | 欢迎大家贡献自己的problems和solutions 22 | 23 | ##贡献方法 24 | 25 | ###先fork项目 26 | 27 | git clone your-project-git-url 28 | cd vue-problems-and-solutions 29 | 30 | ###切换到dev分支 31 | 32 | git checkout dev 33 | npm install 34 | 35 | ###通过本地启动项目或在主页上的dev路由下编辑你的问题名称、标签和解决方案 36 | 37 | npm run dev 38 | http://localhost:8080/#!/dev 39 | 40 | 或者 41 | 42 | http://qianjiahao.github.io/vue-problems-and-solutions/#!/dev 43 | 44 | ###复制刚刚编辑的内容到项目的src/config/doc.js文件中 45 | 46 | cd src && cd config && cd doc.js 47 | 48 | 嗯。。。我知道这么做有点low。。。先这么整吧。。。 49 | 50 | PS: 注意空格,因为开启了eslint 51 | 52 | ###先在本地check, 跑通代码后, 回到主页, 看能否查询到刚刚添加的问题和解决方案 53 | 54 | http://localhost:8080/#!/ 55 | 56 | ###提交 & Pull Request 57 | 58 | git add --a 59 | git commit -a -m "你的problems和solutions的简介" 60 | git push origin dev 61 | 62 | 63 | ##在过程中可能会遇到的问题: 64 | 65 | 1 你需要的标签在已有标签中没有,这时需要你手动添加标签 66 | 67 | 添加方法: 68 | 69 | 路径: src/config/tag.js 70 | 规则: 请保持标签的key/value一致,如果是英文统一小写 71 | 72 | 添加完后add到git 73 | 74 | 75 | 2 编辑中需要添加你自己的图片,因为项目是静态的,你可以使用网络图片;或者将本地图片"网络化" 76 | 本地图片网络化的方法是: 找一个社区或者平台,把本地图片丢上去。。。略 77 | 78 | 注意: 不要把图片放到项目的images文件夹中,那样做是无效的 79 | -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | // https://github.com/shelljs/shelljs 2 | require('shelljs/global') 3 | env.NODE_ENV = 'production' 4 | 5 | var path = require('path') 6 | var config = require('../config') 7 | var ora = require('ora') 8 | var webpack = require('webpack') 9 | var webpackConfig = require('./webpack.prod.conf') 10 | 11 | console.log( 12 | ' Tip:\n' + 13 | ' Built files are meant to be served over an HTTP server.\n' + 14 | ' Opening index.html over file:// won\'t work.\n' 15 | ) 16 | 17 | var spinner = ora('building for production...') 18 | spinner.start() 19 | 20 | var assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory) 21 | rm('-rf', assetsPath) 22 | mkdir('-p', assetsPath) 23 | cp('-R', 'static/', assetsPath) 24 | 25 | webpack(webpackConfig, function (err, stats) { 26 | spinner.stop() 27 | if (err) throw err 28 | process.stdout.write(stats.toString({ 29 | colors: true, 30 | modules: false, 31 | children: false, 32 | chunks: false, 33 | chunkModules: false 34 | }) + '\n') 35 | }) 36 | -------------------------------------------------------------------------------- /build/dev-client.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | require('eventsource-polyfill') 3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') 4 | 5 | hotClient.subscribe(function (event) { 6 | if (event.action === 'reload') { 7 | window.location.reload() 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /build/dev-server.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var express = require('express') 3 | var webpack = require('webpack') 4 | var config = require('../config') 5 | var proxyMiddleware = require('http-proxy-middleware') 6 | var webpackConfig = process.env.NODE_ENV === 'testing' 7 | ? require('./webpack.prod.conf') 8 | : require('./webpack.dev.conf') 9 | 10 | // default port where dev server listens for incoming traffic 11 | var port = process.env.PORT || config.dev.port 12 | // Define HTTP proxies to your custom API backend 13 | // https://github.com/chimurai/http-proxy-middleware 14 | var proxyTable = config.dev.proxyTable 15 | 16 | var app = express() 17 | var compiler = webpack(webpackConfig) 18 | 19 | var devMiddleware = require('webpack-dev-middleware')(compiler, { 20 | publicPath: webpackConfig.output.publicPath, 21 | stats: { 22 | colors: true, 23 | chunks: false 24 | } 25 | }) 26 | 27 | var hotMiddleware = require('webpack-hot-middleware')(compiler) 28 | // force page reload when html-webpack-plugin template changes 29 | compiler.plugin('compilation', function (compilation) { 30 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 31 | hotMiddleware.publish({ action: 'reload' }) 32 | cb() 33 | }) 34 | }) 35 | 36 | // proxy api requests 37 | Object.keys(proxyTable).forEach(function (context) { 38 | var options = proxyTable[context] 39 | if (typeof options === 'string') { 40 | options = { target: options } 41 | } 42 | app.use(proxyMiddleware(context, options)) 43 | }) 44 | 45 | // handle fallback for HTML5 history API 46 | app.use(require('connect-history-api-fallback')()) 47 | 48 | // serve webpack bundle output 49 | app.use(devMiddleware) 50 | 51 | // enable hot-reload and state-preserving 52 | // compilation error display 53 | app.use(hotMiddleware) 54 | 55 | // serve pure static assets 56 | var staticPath = path.posix.join(config.build.assetsPublicPath, config.build.assetsSubDirectory) 57 | app.use(staticPath, express.static('./static')) 58 | 59 | module.exports = app.listen(port, function (err) { 60 | if (err) { 61 | console.log(err) 62 | return 63 | } 64 | console.log('Listening at http://localhost:' + port + '\n') 65 | }) 66 | -------------------------------------------------------------------------------- /build/utils.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | 5 | exports.assetsPath = function (_path) { 6 | return path.posix.join(config.build.assetsSubDirectory, _path) 7 | } 8 | 9 | exports.cssLoaders = function (options) { 10 | options = options || {} 11 | // generate loader string to be used with extract text plugin 12 | function generateLoaders (loaders) { 13 | var sourceLoader = loaders.map(function (loader) { 14 | var extraParamChar 15 | if (/\?/.test(loader)) { 16 | loader = loader.replace(/\?/, '-loader?') 17 | extraParamChar = '&' 18 | } else { 19 | loader = loader + '-loader' 20 | extraParamChar = '?' 21 | } 22 | return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '') 23 | }).join('!') 24 | 25 | if (options.extract) { 26 | return ExtractTextPlugin.extract('vue-style-loader', sourceLoader) 27 | } else { 28 | return ['vue-style-loader', sourceLoader].join('!') 29 | } 30 | } 31 | 32 | // http://vuejs.github.io/vue-loader/configurations/extract-css.html 33 | return { 34 | css: generateLoaders(['css']), 35 | postcss: generateLoaders(['css']), 36 | less: generateLoaders(['css', 'less']), 37 | sass: generateLoaders(['css', 'sass?indentedSyntax']), 38 | scss: generateLoaders(['css', 'sass']), 39 | stylus: generateLoaders(['css', 'stylus']), 40 | styl: generateLoaders(['css', 'stylus']) 41 | } 42 | } 43 | 44 | // Generate loaders for standalone style files (outside of .vue) 45 | exports.styleLoaders = function (options) { 46 | var output = [] 47 | var loaders = exports.cssLoaders(options) 48 | for (var extension in loaders) { 49 | var loader = loaders[extension] 50 | output.push({ 51 | test: new RegExp('\\.' + extension + '$'), 52 | loader: loader 53 | }) 54 | } 55 | return output 56 | } 57 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var utils = require('./utils') 4 | var projectRoot = path.resolve(__dirname, '../') 5 | 6 | module.exports = { 7 | entry: { 8 | app: './src/main.js' 9 | }, 10 | output: { 11 | path: config.build.assetsRoot, 12 | publicPath: config.build.assetsPublicPath, 13 | filename: '[name].js' 14 | }, 15 | resolve: { 16 | extensions: ['', '.js', '.vue'], 17 | fallback: [path.join(__dirname, '../node_modules')], 18 | alias: { 19 | 'src': path.resolve(__dirname, '../src'), 20 | 'utils': path.resolve(__dirname, '../src/utils'), 21 | 'routers': path.resolve(__dirname, '../src/routers'), 22 | 'components': path.resolve(__dirname, '../src/components') 23 | } 24 | }, 25 | resolveLoader: { 26 | fallback: [path.join(__dirname, '../node_modules')] 27 | }, 28 | module: { 29 | preLoaders: [ 30 | { 31 | test: /\.vue$/, 32 | loader: 'eslint', 33 | include: projectRoot, 34 | exclude: /node_modules/ 35 | }, 36 | { 37 | test: /\.js$/, 38 | loader: 'eslint', 39 | include: projectRoot, 40 | exclude: /node_modules/ 41 | } 42 | ], 43 | loaders: [ 44 | { 45 | test: /\.vue$/, 46 | loader: 'vue' 47 | }, 48 | { 49 | test: /\.js$/, 50 | loader: 'babel', 51 | include: projectRoot, 52 | exclude: /node_modules/ 53 | }, 54 | { 55 | test: /\.json$/, 56 | loader: 'json' 57 | }, 58 | { 59 | test: /\.html$/, 60 | loader: 'vue-html' 61 | }, 62 | { 63 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 64 | loader: 'url', 65 | query: { 66 | limit: 10000, 67 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 68 | } 69 | }, 70 | { 71 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 72 | loader: 'url', 73 | query: { 74 | limit: 10000, 75 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 76 | } 77 | } 78 | ] 79 | }, 80 | eslint: { 81 | formatter: require('eslint-friendly-formatter') 82 | }, 83 | vue: { 84 | loaders: utils.cssLoaders() 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | var config = require('../config') 2 | var webpack = require('webpack') 3 | var merge = require('webpack-merge') 4 | var utils = require('./utils') 5 | var baseWebpackConfig = require('./webpack.base.conf') 6 | var HtmlWebpackPlugin = require('html-webpack-plugin') 7 | 8 | // add hot-reload related code to entry chunks 9 | Object.keys(baseWebpackConfig.entry).forEach(function (name) { 10 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) 11 | }) 12 | 13 | module.exports = merge(baseWebpackConfig, { 14 | module: { 15 | loaders: utils.styleLoaders() 16 | }, 17 | // eval-source-map is faster for development 18 | devtool: '#eval-source-map', 19 | plugins: [ 20 | new webpack.DefinePlugin({ 21 | 'process.env': config.dev.env 22 | }), 23 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage 24 | new webpack.optimize.OccurenceOrderPlugin(), 25 | new webpack.HotModuleReplacementPlugin(), 26 | new webpack.NoErrorsPlugin(), 27 | // https://github.com/ampedandwired/html-webpack-plugin 28 | new HtmlWebpackPlugin({ 29 | filename: 'index.html', 30 | template: 'index.html', 31 | inject: true 32 | }), 33 | new webpack.ProvidePlugin({ 34 | $: "jquery", 35 | jQuery: "jquery", 36 | "window.jQuery": "jquery" 37 | }) 38 | ] 39 | }) 40 | -------------------------------------------------------------------------------- /build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var utils = require('./utils') 4 | var webpack = require('webpack') 5 | var merge = require('webpack-merge') 6 | var baseWebpackConfig = require('./webpack.base.conf') 7 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 8 | var HtmlWebpackPlugin = require('html-webpack-plugin') 9 | var env = process.env.NODE_ENV === 'testing' 10 | ? require('../config/test.env') 11 | : config.build.env 12 | 13 | var webpackConfig = merge(baseWebpackConfig, { 14 | module: { 15 | loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true }) 16 | }, 17 | devtool: config.build.productionSourceMap ? '#source-map' : false, 18 | output: { 19 | path: config.build.assetsRoot, 20 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 21 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 22 | }, 23 | vue: { 24 | loaders: utils.cssLoaders({ 25 | sourceMap: config.build.productionSourceMap, 26 | extract: true 27 | }) 28 | }, 29 | plugins: [ 30 | // http://vuejs.github.io/vue-loader/workflow/production.html 31 | new webpack.DefinePlugin({ 32 | 'process.env': env 33 | }), 34 | new webpack.optimize.UglifyJsPlugin({ 35 | compress: { 36 | warnings: false 37 | } 38 | }), 39 | new webpack.optimize.OccurenceOrderPlugin(), 40 | // extract css into its own file 41 | new ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')), 42 | // generate dist index.html with correct asset hash for caching. 43 | // you can customize output by editing /index.html 44 | // see https://github.com/ampedandwired/html-webpack-plugin 45 | new HtmlWebpackPlugin({ 46 | filename: process.env.NODE_ENV === 'testing' 47 | ? 'index.html' 48 | : config.build.index, 49 | template: 'index.html', 50 | inject: true, 51 | minify: { 52 | removeComments: true, 53 | collapseWhitespace: true, 54 | removeAttributeQuotes: true 55 | // more options: 56 | // https://github.com/kangax/html-minifier#options-quick-reference 57 | }, 58 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 59 | chunksSortMode: 'dependency' 60 | }), 61 | // split vendor js into its own file 62 | new webpack.optimize.CommonsChunkPlugin({ 63 | name: 'vendor', 64 | minChunks: function (module, count) { 65 | // any required modules inside node_modules are extracted to vendor 66 | return ( 67 | module.resource && 68 | /\.js$/.test(module.resource) && 69 | module.resource.indexOf( 70 | path.join(__dirname, '../node_modules') 71 | ) === 0 72 | ) 73 | } 74 | }), 75 | // extract webpack runtime and module manifest to its own file in order to 76 | // prevent vendor hash from being updated whenever app bundle is updated 77 | new webpack.optimize.CommonsChunkPlugin({ 78 | name: 'manifest', 79 | chunks: ['vendor'] 80 | }), 81 | new webpack.ProvidePlugin({ 82 | $: "jquery", 83 | jQuery: "jquery", 84 | "window.jQuery": "jquery" 85 | }) 86 | ] 87 | }) 88 | 89 | if (config.build.productionGzip) { 90 | var CompressionWebpackPlugin = require('compression-webpack-plugin') 91 | 92 | webpackConfig.plugins.push( 93 | new CompressionWebpackPlugin({ 94 | asset: '[path].gz[query]', 95 | algorithm: 'gzip', 96 | test: new RegExp( 97 | '\\.(' + 98 | config.build.productionGzipExtensions.join('|') + 99 | ')$' 100 | ), 101 | threshold: 10240, 102 | minRatio: 0.8 103 | }) 104 | ) 105 | } 106 | 107 | module.exports = webpackConfig 108 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | module.exports = { 5 | build: { 6 | env: require('./prod.env'), 7 | index: path.resolve(__dirname, '../dist/index.html'), 8 | assetsRoot: path.resolve(__dirname, '../dist'), 9 | assetsSubDirectory: 'static', 10 | assetsPublicPath: '', 11 | productionSourceMap: false, 12 | // gzip off by default as many popular static hosts such as 13 | // surge or netlify already gzip all static assets for you 14 | productionGzip: false, 15 | productionGzipExtensions: ['js', 'css'] 16 | }, 17 | dev: { 18 | env: require('./dev.env'), 19 | port: 8080, 20 | proxyTable: {} 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /config/test.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var devEnv = require('./dev.env') 3 | 4 | module.exports = merge(devEnv, { 5 | NODE_ENV: '"testing"' 6 | }) 7 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | qa for Vue.js 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "qa", 3 | "version": "1.0.0", 4 | "description": "A Vue.js project", 5 | "author": "qianjiahao <1041897388@qq.com>", 6 | "private": true, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "build": "node build/build.js", 10 | "test": "", 11 | "lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs" 12 | }, 13 | "dependencies": { 14 | "babel-runtime": "^6.0.0", 15 | "jquery": "^3.0.0", 16 | "marked": "^0.3.5", 17 | "uuid": "^2.0.2", 18 | "vue": "^1.0.21", 19 | "vue-router": "^0.7.13" 20 | }, 21 | "devDependencies": { 22 | "babel-core": "^6.0.0", 23 | "babel-loader": "^6.0.0", 24 | "babel-plugin-transform-runtime": "^6.0.0", 25 | "babel-preset-es2015": "^6.0.0", 26 | "babel-preset-stage-2": "^6.0.0", 27 | "compression-webpack-plugin": "^0.3.1", 28 | "connect-history-api-fallback": "^1.1.0", 29 | "css-loader": "^0.23.0", 30 | "eslint": "^2.10.2", 31 | "eslint-config-standard": "^5.1.0", 32 | "eslint-friendly-formatter": "^2.0.5", 33 | "eslint-loader": "^1.3.0", 34 | "eslint-plugin-html": "^1.3.0", 35 | "eslint-plugin-promise": "^1.0.8", 36 | "eslint-plugin-standard": "^1.3.2", 37 | "eventsource-polyfill": "^0.9.6", 38 | "express": "^4.13.3", 39 | "extract-text-webpack-plugin": "^1.0.1", 40 | "file-loader": "^0.8.4", 41 | "function-bind": "^1.0.2", 42 | "html-webpack-plugin": "^2.8.1", 43 | "http-proxy-middleware": "^0.12.0", 44 | "json-loader": "^0.5.4", 45 | "node-sass": "^3.7.0", 46 | "ora": "^0.2.0", 47 | "sass-loader": "^3.2.0", 48 | "shelljs": "^0.6.0", 49 | "url-loader": "^0.5.7", 50 | "vue-hot-reload-api": "^1.2.0", 51 | "vue-html-loader": "^1.0.0", 52 | "vue-loader": "^8.3.0", 53 | "vue-style-loader": "^1.0.0", 54 | "webpack": "^1.12.2", 55 | "webpack-dev-middleware": "^1.4.0", 56 | "webpack-hot-middleware": "^2.6.0", 57 | "webpack-merge": "^0.8.3" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/components/Assistant.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 23 | -------------------------------------------------------------------------------- /src/components/DataTable.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | 111 | 112 | 284 | -------------------------------------------------------------------------------- /src/components/Nav.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 45 | 46 | 109 | -------------------------------------------------------------------------------- /src/components/Predictor.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 20 | 21 | 53 | -------------------------------------------------------------------------------- /src/components/SearchBar.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 23 | 24 | 74 | -------------------------------------------------------------------------------- /src/config/doc.js: -------------------------------------------------------------------------------- 1 | import tag from './tag.js' 2 | 3 | export default [ 4 | { 5 | id: 'a013bff1-8912-406f-ae9c-0875a8529d17', 6 | title: 'eslint静态检查', 7 | tags: [tag['eslint']], 8 | content: `在大家用vue-cli创建工程的时候,会有一项,使用使用eslint,如果选择了y,那么工程就会安装并启用eslint。 9 | 10 | 这里列举一下常见的错误: 11 | 12 | 1.多余的分号 13 | ![图片描述][1] 14 | 15 | 2.定义了却未使用的变量 16 | ![图片描述][2] 17 | 18 | 3.结尾多余空格 19 | ![图片描述][3] 20 | 21 | 4.超过一行的空行 22 | ![图片描述][4] 23 | 24 | 5.代码尾行应该有空行 25 | ![图片描述][5] 26 | 27 | 错误肯定是列举不完的,那么提示错误的时候,我们应该先去看提示信息(翻译),如果发现没有错误,可以对照[eslint的官方文档][6] 28 | 29 | 在大家适应了eslint的写法后,效率和正确率会直线上升 30 | 31 | [1]: https://segmentfault.com/img/bVvhFl 32 | [2]: https://segmentfault.com/img/bVvhFs 33 | [3]: https://segmentfault.com/img/bVvhFE 34 | [4]: https://segmentfault.com/img/bVvhFN 35 | [5]: https://segmentfault.com/img/bVvhFR 36 | [6]: http://eslint.org/` 37 | }, 38 | { 39 | id: '77c55630-2fbb-11e6-ac64-b50848dab1ca', 40 | title: 'this指向', 41 | tags: [tag['this'], tag['箭头符号']], 42 | content: `经常会有朋友问一些undifined的错误,比如: 43 | 44 | 71 | 72 | 这是刚创建的工程,我们定义了list,idx和current,在执行iter方法时,我们就给current赋值以idx为下标的值,当我们执行后会发现,浏览器报了一个错误 73 | 74 | ![图片描述][8] 75 | 76 | 这么回事,我们不是定义了idx了吗? 77 | 78 | 其实是因为我们在map里的this是指向当前map的迭代对象,而非我们vue的实例,所以this里没有我们需要的idx。 79 | 80 | 解决方式有两种,其一是通过保存this 81 | 82 | let _this = this 83 | 84 | 其二是使用es6箭头函数 85 | 86 | methods: { 87 | iter () { 88 | this.list.map((v, k) => { 89 | if (k === this.idx) { 90 | this.current = v 91 | 92 | console.log(this.current) 93 | } 94 | }) 95 | } 96 | }, 97 | 98 | 现在再看我们的浏览器 99 | 100 | ![图片描述][9] 101 | 102 | 已经可以达到我们预期的效果了! 103 | 104 | [8]: https://segmentfault.com/img/bVvhHk 105 | [9]: https://segmentfault.com/img/bVvhHG` 106 | }, 107 | { 108 | id: '83ea9ec0-2fbb-11e6-9485-6f1a608fe2fc', 109 | title: '根据$index判断当前值', 110 | tags: [tag['$index']], 111 | content: `比如我们有一个列表,我们希望能显示我们当前选中的那一个,如何实现呢? 112 | 113 | 基本思路是通过$index来判断是否是当前迭代对象,然后去增减class或者style来实现不同的样式 114 | 115 | 123 | 124 | data () { 125 | return { 126 | list: ['a', 'b', 'c'], 127 | activeId: 0 128 | } 129 | },` 130 | }, 131 | { 132 | id: '8f67e780-2fbb-11e6-87d4-93f110a8c904', 133 | title: '传值与传字面量', 134 | tags: [tag['字面量']], 135 | content: `在vue的组件中传递数据,如果是单纯传递字面量,如 136 | 137 | 138 | 139 | 那么在hello中获取的props result的值就是“success”,如果希望进行值传递,需要在指令前加 ':' 冒号,这样,父层的success的值改变,hello的值也会跟着改变。` 140 | }, 141 | { 142 | id: '9649af20-2fbb-11e6-8f62-b3fe7c319399', 143 | title: '转场动画transition', 144 | tags: [tag['transition']], 145 | content: `在vue中有个很好用的指令,transition,通过它我们可以实现自定义的router切换中的动画 146 | 147 | 方法就是在 148 | 149 | 150 | 151 | 加入自定义的class fade-transition , fade-leave , fade-enter即可。` 152 | }, 153 | { 154 | id: 'b4bf6b31-4f86-4411-83c8-a72d590a5c71', 155 | title: 'v-cloak', 156 | tags: [tag['v-cloak']], 157 | content: `如果出现{{}}的短暂出现的情况,可以通过添加v-cloak来处理。 158 | 159 | 这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。` 160 | }, 161 | { 162 | id: 'fbb9fe7a-0748-45c1-b9fe-fc8d05beaf72', 163 | title: '使用sass', 164 | tags: [tag['sass']], 165 | content: `首先安装依赖 166 | 167 | npm i node-sass sass-loader -D 168 | 169 | 然后在vue的style里添加 170 | 171 | 285 | 286 | 也可以使用其他css预编译,如sass 287 | 288 | 291 | 292 | 需要自行安装node-sass和sass-loader 293 | 294 | npm i node-sass sass-loader -S 295 | 296 | ` 297 | }, 298 | { 299 | id: 'a616390c-778a-4a23-80f7-cd05371fab76', 300 | title: '模块化 import & export , module.exports & exports', 301 | tags: [tag['模块化']], 302 | content: `在经历过遵循AMD的RequireJS和遵循CMD的SeaJS后,2015、2016因webpack的大火,遵循commonjs的方式得到了普遍。 303 | 304 | ### es5 多模块 305 | 306 | 从同级的test.js文件中默认导出main函数,附带导出a1,a2函数 307 | 308 | function a1 () {} 309 | function a2 () {} 310 | function main () {} 311 | 312 | module.exports = main 313 | module.exports.a1 = a1 314 | module.exports.a2 = a2 315 | 316 | 或者 317 | 318 | module.exports = main 319 | exports.a1 = a1 320 | exports.a2 = a2 321 | 322 | 引入的时候 323 | 324 | var main = require('./test') 325 | 326 | main() 327 | main.a1() 328 | main.a2() 329 | 330 | ### es6 多模块 331 | 332 | 从同级的test.js文件中默认导出main函数,附带导出a1,a2函数 333 | 334 | export function a1 () {} 335 | export function a2 () {} 336 | 337 | export default function main () {} 338 | 339 | 引入的时候 340 | 341 | import main, { a1, a2 } from './test' 342 | 343 | main() 344 | a1() 345 | a2() 346 | 347 | 或者 348 | 349 | import * as main from './test' 350 | 351 | main() 352 | main.a1() 353 | main.a2()` 354 | } 355 | ] 356 | -------------------------------------------------------------------------------- /src/config/settings.js: -------------------------------------------------------------------------------- 1 | // 权值 2 | export const WEIGHT = { 3 | init: 1, 4 | tag: 1, 5 | title: 2, 6 | content: 1 7 | } 8 | -------------------------------------------------------------------------------- /src/config/tag.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 'eslint': 'eslint', 3 | 'this': 'this', 4 | 'img': 'img', 5 | '$index': '$index', 6 | 'class': 'class', 7 | 'style': 'style', 8 | 'computed': 'computed', 9 | 'transition': 'transition', 10 | 'v-on': 'v-on', 11 | '@': '@', 12 | 'props': 'props', 13 | 'component': 'component', 14 | 'template': 'template', 15 | 'sync': 'sync', 16 | 'slot': 'slot', 17 | 'v-for': 'v-for', 18 | 'fragment': 'fragment', 19 | 'v-show': 'v-show', 20 | 'v-if': 'v-if', 21 | 'track-by': 'track-by', 22 | 'filter': 'filter', 23 | 'vuex': 'vuex', 24 | 'vue-router': 'vue-router', 25 | 'vue-resource': 'vue-resource', 26 | '组件通信': '组件通信', 27 | '组件实例': '组件实例', 28 | '热替换': '热替换', 29 | 'hot reload': 'hot reload', 30 | 'webpack': 'webpack', 31 | '箭头符号': '箭头符号', 32 | '字面量': '字面量', 33 | '对象解构': '对象解构', 34 | '模块化': '模块化', 35 | 'v-cloak': 'v-cloak', 36 | 'sass': 'sass', 37 | 'less': 'less', 38 | '模式': '模式', 39 | '实践': '实践' 40 | } 41 | -------------------------------------------------------------------------------- /src/iconfont/iconfont.css: -------------------------------------------------------------------------------- 1 | 2 | @font-face {font-family: "iconfont"; 3 | src: url('iconfont.eot?t=1465966982'); /* IE9*/ 4 | src: url('iconfont.eot?t=1465966982#iefix') format('embedded-opentype'), /* IE6-IE8 */ 5 | url('iconfont.woff?t=1465966982') format('woff'), /* chrome, firefox */ 6 | url('iconfont.ttf?t=1465966982') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ 7 | url('iconfont.svg?t=1465966982#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .iconfont { 11 | font-family:"iconfont" !important; 12 | font-style:normal; 13 | -webkit-font-smoothing: antialiased; 14 | -webkit-text-stroke-width: 0.2px; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | .icon-link:before { content: "\e617"; } 18 | .icon-small:before { content: "\e608"; } 19 | .icon-xiugai:before { content: "\e609"; } 20 | .icon-github:before { content: "\e606"; } 21 | .icon-unfold:before { content: "\e61a"; } 22 | .icon-big:before { content: "\e60e"; } 23 | .icon-copy-done:before { content: "\e60b"; } 24 | .icon-plane-top:before { content: "\e602"; } 25 | .icon-top:before { content: "\e60d"; } 26 | .icon-search:before { content: "\e613"; } 27 | .icon-more:before { content: "\e600"; } 28 | .icon-code:before { content: "\e611"; } 29 | .icon-marked:before { content: "\e605"; } 30 | .icon-404:before { content: "\e616"; } 31 | .icon-share:before { content: "\e615"; } 32 | .icon-copy-start:before { content: "\e60c"; } 33 | .icon-settings:before { content: "\e612"; } 34 | .icon-unmarked:before { content: "\e607"; } 35 | .icon-clear:before { content: "\e604"; } 36 | .icon-flag:before { content: "\e60a"; } 37 | .icon-next:before { content: "\e61c"; } 38 | .icon-fold:before { content: "\e61d"; } 39 | .icon-pre:before { content: "\e61e"; } 40 | -------------------------------------------------------------------------------- /src/iconfont/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianjiahao/vue-problems-and-solutions/cb1fe8fd8d973121ea883d4a6e64797015d06ea9/src/iconfont/iconfont.eot -------------------------------------------------------------------------------- /src/iconfont/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Created by FontForge 20120731 at Wed Jun 15 13:03:02 2016 6 | By admin 7 | 8 | 9 | 10 | 24 | 26 | 28 | 30 | 32 | 36 | 38 | 42 | 44 | 47 | 51 | 55 | 57 | 59 | 61 | 63 | 67 | 71 | 73 | 78 | 85 | 90 | 95 | 101 | 105 | 107 | 109 | 111 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /src/iconfont/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianjiahao/vue-problems-and-solutions/cb1fe8fd8d973121ea883d4a6e64797015d06ea9/src/iconfont/iconfont.ttf -------------------------------------------------------------------------------- /src/iconfont/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianjiahao/vue-problems-and-solutions/cb1fe8fd8d973121ea883d4a6e64797015d06ea9/src/iconfont/iconfont.woff -------------------------------------------------------------------------------- /src/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianjiahao/vue-problems-and-solutions/cb1fe8fd8d973121ea883d4a6e64797015d06ea9/src/images/logo.png -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import router from './routers/route.js' 2 | import App from './views/App.vue' 3 | import Vue from 'vue' 4 | import './iconfont/iconfont.css' 5 | 6 | router.start(App, '#root') 7 | 8 | Vue.filter('marked-img', (value) => { 9 | return value.replace(new RegExp(' { 11 | require(['../views/Index.vue'], resolve) 12 | } 13 | }, 14 | '/index': { 15 | component: (resolve) => { 16 | require(['../views/Index.vue'], resolve) 17 | } 18 | }, 19 | '/dev': { 20 | component: (resolve) => { 21 | require(['../views/Dev.vue'], resolve) 22 | } 23 | }, 24 | '/detail/:id': { 25 | component: (resolve) => { 26 | require(['../views/Detail.vue'], resolve) 27 | } 28 | } 29 | }) 30 | 31 | export default router 32 | -------------------------------------------------------------------------------- /src/utils/utils.js: -------------------------------------------------------------------------------- 1 | import doc from '../config/doc.js' 2 | import { WEIGHT } from '../config/settings.js' 3 | 4 | // 分词 5 | export function participle (value) { 6 | const parts = value.split(' ').filter(v => v) 7 | 8 | return unique(parts) 9 | } 10 | 11 | // 去重 12 | export function unique (array) { 13 | return [...new Set(array)] 14 | } 15 | 16 | // 计算权值 17 | export function countWeight (parts) { 18 | const result = [] 19 | 20 | doc.map((doc, index) => { 21 | // 基础权值 22 | result[index] = WEIGHT.init 23 | 24 | parts.map((p, k) => { 25 | try { 26 | let item = typeof p === 'string' ? p.toLowerCase() : p.toString().toLowerCase() 27 | 28 | // 计算优先级权值 29 | let priority = parts.length - k 30 | result[index] += priority 31 | 32 | // 计算标签权值 33 | if (doc.tags.indexOf(item) > -1) { 34 | result[index] += WEIGHT.tag 35 | } 36 | 37 | let title = doc.title 38 | let content = doc.content 39 | let len = p.length 40 | 41 | // 计算标题权值 42 | while (title.indexOf(p) > -1) { 43 | title = title.slice(0, title.indexOf(p)) + title.slice(title.indexOf(p) + len) 44 | result[index] += WEIGHT.title 45 | } 46 | 47 | // 计算内容权值 48 | while (content.indexOf(p) > -1) { 49 | content = content.slice(0, content.indexOf(p)) + content.slice(content.indexOf(p) + len) 50 | result[index] += WEIGHT.content 51 | } 52 | } catch (e) { 53 | console.log(e) 54 | } 55 | }) 56 | }) 57 | 58 | return result 59 | } 60 | 61 | // 根据权值排序,取前n个(降序排列) 62 | export function sortByWeigth (weight, n = weight.length) { 63 | const result = [] 64 | let i = weight.length > n ? n : weight.length 65 | 66 | while (i > 0) { 67 | let max = Math.max(...weight) 68 | if (max !== WEIGHT.init) { 69 | let index = weight.indexOf(max) 70 | result.push(doc[index]) 71 | weight.splice(index, 1, WEIGHT.init) 72 | i-- 73 | } else { 74 | break 75 | } 76 | } 77 | 78 | return result 79 | } 80 | -------------------------------------------------------------------------------- /src/views/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 30 | 31 | 55 | -------------------------------------------------------------------------------- /src/views/Detail.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 61 | 62 | 87 | -------------------------------------------------------------------------------- /src/views/Dev.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 122 | 123 | 260 | -------------------------------------------------------------------------------- /src/views/Index.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 90 | 91 | 126 | -------------------------------------------------------------------------------- /src/views/Settings.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 12 | -------------------------------------------------------------------------------- /static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qianjiahao/vue-problems-and-solutions/cb1fe8fd8d973121ea883d4a6e64797015d06ea9/static/.gitkeep -------------------------------------------------------------------------------- /static/tomorrow-night-eighties.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Night Eighties Theme */ 2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 3 | /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ 4 | 5 | /* Tomorrow Comment */ 6 | .hljs-comment { 7 | color: #999999; 8 | } 9 | 10 | /* Tomorrow Red */ 11 | .hljs-variable, 12 | .hljs-attribute, 13 | .hljs-tag, 14 | .hljs-regexp, 15 | .ruby .hljs-constant, 16 | .xml .hljs-tag .hljs-title, 17 | .xml .hljs-pi, 18 | .xml .hljs-doctype, 19 | .html .hljs-doctype, 20 | .css .hljs-id, 21 | .css .hljs-class, 22 | .css .hljs-pseudo { 23 | color: #f2777a; 24 | } 25 | 26 | /* Tomorrow Orange */ 27 | .hljs-number, 28 | .hljs-preprocessor, 29 | .hljs-pragma, 30 | .hljs-built_in, 31 | .hljs-literal, 32 | .hljs-params, 33 | .hljs-constant { 34 | color: #f99157; 35 | } 36 | 37 | /* Tomorrow Yellow */ 38 | .ruby .hljs-class .hljs-title, 39 | .css .hljs-rule .hljs-attribute { 40 | color: #ffcc66; 41 | } 42 | 43 | /* Tomorrow Green */ 44 | .hljs-string, 45 | .hljs-value, 46 | .hljs-inheritance, 47 | .hljs-header, 48 | .hljs-name, 49 | .ruby .hljs-symbol, 50 | .xml .hljs-cdata { 51 | color: #99cc99; 52 | } 53 | 54 | /* Tomorrow Aqua */ 55 | .hljs-title, 56 | .css .hljs-hexcolor { 57 | color: #66cccc; 58 | } 59 | 60 | /* Tomorrow Blue */ 61 | .hljs-function, 62 | .python .hljs-decorator, 63 | .python .hljs-title, 64 | .ruby .hljs-function .hljs-title, 65 | .ruby .hljs-title .hljs-keyword, 66 | .perl .hljs-sub, 67 | .javascript .hljs-title, 68 | .coffeescript .hljs-title { 69 | color: #6699cc; 70 | } 71 | 72 | /* Tomorrow Purple */ 73 | .hljs-keyword, 74 | .javascript .hljs-function { 75 | color: #cc99cc; 76 | } 77 | 78 | .hljs { 79 | display: block; 80 | overflow-x: auto; 81 | background: #2d2d2d; 82 | color: #cccccc; 83 | padding: 0.5em; 84 | -webkit-text-size-adjust: none; 85 | } 86 | 87 | .coffeescript .javascript, 88 | .javascript .xml, 89 | .tex .hljs-formula, 90 | .xml .javascript, 91 | .xml .vbscript, 92 | .xml .css, 93 | .xml .hljs-cdata { 94 | opacity: 0.5; 95 | } 96 | --------------------------------------------------------------------------------