├── .browserslistrc ├── .eslintrc.js ├── .gitignore ├── LICENSE ├── README.md ├── babel.config.js ├── package.json ├── postcss.config.js ├── public ├── favicon.ico ├── github.ico ├── img │ └── icons │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── apple-touch-icon-120x120.png │ │ ├── apple-touch-icon-152x152.png │ │ ├── apple-touch-icon-180x180.png │ │ ├── apple-touch-icon-60x60.png │ │ ├── apple-touch-icon-76x76.png │ │ ├── apple-touch-icon.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── msapplication-icon-144x144.png │ │ ├── mstile-150x150.png │ │ └── safari-pinned-tab.svg ├── index.html └── robots.txt ├── src ├── App.vue ├── assets │ ├── font │ │ ├── demo.css │ │ ├── demo_index.html │ │ ├── iconfont.css │ │ ├── iconfont.eot │ │ ├── iconfont.js │ │ ├── iconfont.json │ │ ├── iconfont.svg │ │ ├── iconfont.ttf │ │ ├── iconfont.woff │ │ └── iconfont.woff2 │ ├── image │ │ └── github.jpg │ └── scss │ │ ├── public.scss │ │ └── reset.scss ├── components │ ├── articles │ │ └── articles.vue │ ├── comments │ │ └── comments.vue │ ├── footer │ │ └── footer.vue │ ├── header │ │ └── header.vue │ └── swiper │ │ └── swiper.vue ├── config │ └── index.js ├── lib │ ├── axios.js │ ├── highlight.js │ └── markdown.js ├── main.js ├── registerServiceWorker.js ├── router │ └── index.js ├── service │ ├── archive.js │ ├── article.js │ ├── category.js │ ├── comment.js │ ├── index.js │ └── regist.js ├── store │ ├── index.js │ └── module │ │ ├── archive.js │ │ ├── article.js │ │ ├── category.js │ │ ├── comment.js │ │ └── login.js └── views │ ├── about │ └── about.vue │ ├── archive │ └── archive.vue │ ├── article-detail │ ├── article-detail.vue │ └── single-article.vue │ ├── category │ └── category.vue │ ├── home │ └── home.vue │ ├── layout │ └── layout.vue │ └── wall │ └── wall.vue └── vue.config.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: ["plugin:vue/essential", "@vue/prettier"], 7 | rules: { 8 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off", 9 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off", 10 | "no-unused-vars": 'off', 11 | 'quotes': ['error', 'single'], 12 | 'prettier/prettier': ['error', { 'singleQuote': true }] 13 | }, 14 | parserOptions: { 15 | parser: "babel-eslint" 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | yarn.lock -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 zhanghe888 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 项目地址: 2 | [博客地址](http://www.xxhblog.com) 3 | 4 | ### 项目介绍 5 | * vue-blog-web为博客前台 6 | * 前后端分离项目 7 | 8 | ### 技术栈 9 | * Vue全家桶 10 | * Axios 11 | * Sass 12 | * ElementUI 13 | * Eslint + Prettier 14 | * highlight.js 15 | ### 预览 16 | 17 | ### 已实现功能 18 | 19 | - [x] 登录 20 | - [x] github第三方授权 21 | - [x] 文章列表展示 22 | - [x] 文章详情展示 23 | - [x] 标签展示 24 | - [x] 评论功能 25 | - [x] 代码高亮 26 | - [x] 文章、评论点赞 27 | 28 | ### 待实现功能 29 | 30 | - [ ] 文章段落生成锚点 31 | - [ ] 推荐文章 32 | - [ ] 个人中心完善 33 | - [ ] UI 34 | 35 | ### 项目启动 36 | ``` 37 | git clone git@github.com:zhanghe888/vue-blog-web.git 38 | 39 | cd vue-blog-web 40 | 41 | npm install 42 | 43 | npm run serve 44 | ``` 45 | ### 项目结构 46 | ``` 47 | vue-blog-web 48 | ├─ .gitignore // git忽略文件 49 | ├─ src 50 | │ ├─ assets // 静态资源 51 | │ ├─ components // 公共组件 52 | │ ├─ config // 配置文件 53 | │ ├─ lib // 公共方法 54 | │ ├─ router // 路由表 55 | │ ├─ service // 请求层 56 | │ └─ store // 状态共享 57 | │ └─ views // 业务模块 58 | └─ babel.config.js // babel配置,Element按需加载 59 | ``` 60 | 61 | ### 未来 62 | * 采用webpack4+动配置工程环境 63 | * TypeScript重构此项目 64 | * 优化前台UI展示 65 | * 增加vue3.0新特性 -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@vue/cli-plugin-babel/preset'], 3 | plugins: [ 4 | [ 5 | 'component', 6 | { 7 | libraryName: 'element-ui', 8 | styleLibraryName: 'theme-chalk' 9 | } 10 | ] 11 | ] 12 | }; 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-blog-web", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "animate.css": "^3.7.2", 12 | "axios": "^0.19.0", 13 | "core-js": "^3.3.2", 14 | "element-ui": "^2.12.0", 15 | "highlight.js": "^9.16.2", 16 | "jwt-decode": "^2.2.0", 17 | "marked": "^0.7.0", 18 | "moment": "^2.24.0", 19 | "register-service-worker": "^1.6.2", 20 | "vue": "^2.6.10", 21 | "vue-router": "^3.1.3", 22 | "vuex": "^3.0.1", 23 | "xss": "^1.0.6" 24 | }, 25 | "devDependencies": { 26 | "@vue/cli-plugin-babel": "^4.0.0", 27 | "@vue/cli-plugin-eslint": "^4.0.0", 28 | "@vue/cli-plugin-pwa": "^4.0.0", 29 | "@vue/cli-plugin-router": "^4.0.0", 30 | "@vue/cli-plugin-vuex": "^4.0.0", 31 | "@vue/cli-service": "^4.0.0", 32 | "@vue/eslint-config-prettier": "^5.0.0", 33 | "babel-eslint": "^10.0.3", 34 | "babel-plugin-component": "^1.1.1", 35 | "eslint": "^5.16.0", 36 | "eslint-plugin-prettier": "^3.1.1", 37 | "eslint-plugin-vue": "^5.0.0", 38 | "node-sass": "^4.13.0", 39 | "prettier": "^1.18.2", 40 | "sass-loader": "^8.0.0", 41 | "vue-template-compiler": "^2.6.10" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {} 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/public/favicon.ico -------------------------------------------------------------------------------- /public/github.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/public/github.ico -------------------------------------------------------------------------------- /public/img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/public/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/img/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/public/img/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/public/img/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/public/img/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/public/img/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/public/img/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/public/img/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /public/img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/public/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /public/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/public/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /public/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/public/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /public/img/icons/msapplication-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/public/img/icons/msapplication-icon-144x144.png -------------------------------------------------------------------------------- /public/img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/public/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /public/img/icons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | vue-blog-web 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 9 | 17 | 18 | -------------------------------------------------------------------------------- /src/assets/font/demo.css: -------------------------------------------------------------------------------- 1 | /* Logo 字体 */ 2 | @font-face { 3 | font-family: "iconfont logo"; 4 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834'); 5 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'), 6 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'), 7 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'), 8 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg'); 9 | } 10 | 11 | .logo { 12 | font-family: "iconfont logo"; 13 | font-size: 160px; 14 | font-style: normal; 15 | -webkit-font-smoothing: antialiased; 16 | -moz-osx-font-smoothing: grayscale; 17 | } 18 | 19 | /* tabs */ 20 | .nav-tabs { 21 | position: relative; 22 | } 23 | 24 | .nav-tabs .nav-more { 25 | position: absolute; 26 | right: 0; 27 | bottom: 0; 28 | height: 42px; 29 | line-height: 42px; 30 | color: #666; 31 | } 32 | 33 | #tabs { 34 | border-bottom: 1px solid #eee; 35 | } 36 | 37 | #tabs li { 38 | cursor: pointer; 39 | width: 100px; 40 | height: 40px; 41 | line-height: 40px; 42 | text-align: center; 43 | font-size: 16px; 44 | border-bottom: 2px solid transparent; 45 | position: relative; 46 | z-index: 1; 47 | margin-bottom: -1px; 48 | color: #666; 49 | } 50 | 51 | 52 | #tabs .active { 53 | border-bottom-color: #f00; 54 | color: #222; 55 | } 56 | 57 | .tab-container .content { 58 | display: none; 59 | } 60 | 61 | /* 页面布局 */ 62 | .main { 63 | padding: 30px 100px; 64 | width: 960px; 65 | margin: 0 auto; 66 | } 67 | 68 | .main .logo { 69 | color: #333; 70 | text-align: left; 71 | margin-bottom: 30px; 72 | line-height: 1; 73 | height: 110px; 74 | margin-top: -50px; 75 | overflow: hidden; 76 | *zoom: 1; 77 | } 78 | 79 | .main .logo a { 80 | font-size: 160px; 81 | color: #333; 82 | } 83 | 84 | .helps { 85 | margin-top: 40px; 86 | } 87 | 88 | .helps pre { 89 | padding: 20px; 90 | margin: 10px 0; 91 | border: solid 1px #e7e1cd; 92 | background-color: #fffdef; 93 | overflow: auto; 94 | } 95 | 96 | .icon_lists { 97 | width: 100% !important; 98 | overflow: hidden; 99 | *zoom: 1; 100 | } 101 | 102 | .icon_lists li { 103 | width: 100px; 104 | margin-bottom: 10px; 105 | margin-right: 20px; 106 | text-align: center; 107 | list-style: none !important; 108 | cursor: default; 109 | } 110 | 111 | .icon_lists li .code-name { 112 | line-height: 1.2; 113 | } 114 | 115 | .icon_lists .icon { 116 | display: block; 117 | height: 100px; 118 | line-height: 100px; 119 | font-size: 42px; 120 | margin: 10px auto; 121 | color: #333; 122 | -webkit-transition: font-size 0.25s linear, width 0.25s linear; 123 | -moz-transition: font-size 0.25s linear, width 0.25s linear; 124 | transition: font-size 0.25s linear, width 0.25s linear; 125 | } 126 | 127 | .icon_lists .icon:hover { 128 | font-size: 100px; 129 | } 130 | 131 | .icon_lists .svg-icon { 132 | /* 通过设置 font-size 来改变图标大小 */ 133 | width: 1em; 134 | /* 图标和文字相邻时,垂直对齐 */ 135 | vertical-align: -0.15em; 136 | /* 通过设置 color 来改变 SVG 的颜色/fill */ 137 | fill: currentColor; 138 | /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示 139 | normalize.css 中也包含这行 */ 140 | overflow: hidden; 141 | } 142 | 143 | .icon_lists li .name, 144 | .icon_lists li .code-name { 145 | color: #666; 146 | } 147 | 148 | /* markdown 样式 */ 149 | .markdown { 150 | color: #666; 151 | font-size: 14px; 152 | line-height: 1.8; 153 | } 154 | 155 | .highlight { 156 | line-height: 1.5; 157 | } 158 | 159 | .markdown img { 160 | vertical-align: middle; 161 | max-width: 100%; 162 | } 163 | 164 | .markdown h1 { 165 | color: #404040; 166 | font-weight: 500; 167 | line-height: 40px; 168 | margin-bottom: 24px; 169 | } 170 | 171 | .markdown h2, 172 | .markdown h3, 173 | .markdown h4, 174 | .markdown h5, 175 | .markdown h6 { 176 | color: #404040; 177 | margin: 1.6em 0 0.6em 0; 178 | font-weight: 500; 179 | clear: both; 180 | } 181 | 182 | .markdown h1 { 183 | font-size: 28px; 184 | } 185 | 186 | .markdown h2 { 187 | font-size: 22px; 188 | } 189 | 190 | .markdown h3 { 191 | font-size: 16px; 192 | } 193 | 194 | .markdown h4 { 195 | font-size: 14px; 196 | } 197 | 198 | .markdown h5 { 199 | font-size: 12px; 200 | } 201 | 202 | .markdown h6 { 203 | font-size: 12px; 204 | } 205 | 206 | .markdown hr { 207 | height: 1px; 208 | border: 0; 209 | background: #e9e9e9; 210 | margin: 16px 0; 211 | clear: both; 212 | } 213 | 214 | .markdown p { 215 | margin: 1em 0; 216 | } 217 | 218 | .markdown>p, 219 | .markdown>blockquote, 220 | .markdown>.highlight, 221 | .markdown>ol, 222 | .markdown>ul { 223 | width: 80%; 224 | } 225 | 226 | .markdown ul>li { 227 | list-style: circle; 228 | } 229 | 230 | .markdown>ul li, 231 | .markdown blockquote ul>li { 232 | margin-left: 20px; 233 | padding-left: 4px; 234 | } 235 | 236 | .markdown>ul li p, 237 | .markdown>ol li p { 238 | margin: 0.6em 0; 239 | } 240 | 241 | .markdown ol>li { 242 | list-style: decimal; 243 | } 244 | 245 | .markdown>ol li, 246 | .markdown blockquote ol>li { 247 | margin-left: 20px; 248 | padding-left: 4px; 249 | } 250 | 251 | .markdown code { 252 | margin: 0 3px; 253 | padding: 0 5px; 254 | background: #eee; 255 | border-radius: 3px; 256 | } 257 | 258 | .markdown strong, 259 | .markdown b { 260 | font-weight: 600; 261 | } 262 | 263 | .markdown>table { 264 | border-collapse: collapse; 265 | border-spacing: 0px; 266 | empty-cells: show; 267 | border: 1px solid #e9e9e9; 268 | width: 95%; 269 | margin-bottom: 24px; 270 | } 271 | 272 | .markdown>table th { 273 | white-space: nowrap; 274 | color: #333; 275 | font-weight: 600; 276 | } 277 | 278 | .markdown>table th, 279 | .markdown>table td { 280 | border: 1px solid #e9e9e9; 281 | padding: 8px 16px; 282 | text-align: left; 283 | } 284 | 285 | .markdown>table th { 286 | background: #F7F7F7; 287 | } 288 | 289 | .markdown blockquote { 290 | font-size: 90%; 291 | color: #999; 292 | border-left: 4px solid #e9e9e9; 293 | padding-left: 0.8em; 294 | margin: 1em 0; 295 | } 296 | 297 | .markdown blockquote p { 298 | margin: 0; 299 | } 300 | 301 | .markdown .anchor { 302 | opacity: 0; 303 | transition: opacity 0.3s ease; 304 | margin-left: 8px; 305 | } 306 | 307 | .markdown .waiting { 308 | color: #ccc; 309 | } 310 | 311 | .markdown h1:hover .anchor, 312 | .markdown h2:hover .anchor, 313 | .markdown h3:hover .anchor, 314 | .markdown h4:hover .anchor, 315 | .markdown h5:hover .anchor, 316 | .markdown h6:hover .anchor { 317 | opacity: 1; 318 | display: inline-block; 319 | } 320 | 321 | .markdown>br, 322 | .markdown>p>br { 323 | clear: both; 324 | } 325 | 326 | 327 | .hljs { 328 | display: block; 329 | background: white; 330 | padding: 0.5em; 331 | color: #333333; 332 | overflow-x: auto; 333 | } 334 | 335 | .hljs-comment, 336 | .hljs-meta { 337 | color: #969896; 338 | } 339 | 340 | .hljs-string, 341 | .hljs-variable, 342 | .hljs-template-variable, 343 | .hljs-strong, 344 | .hljs-emphasis, 345 | .hljs-quote { 346 | color: #df5000; 347 | } 348 | 349 | .hljs-keyword, 350 | .hljs-selector-tag, 351 | .hljs-type { 352 | color: #a71d5d; 353 | } 354 | 355 | .hljs-literal, 356 | .hljs-symbol, 357 | .hljs-bullet, 358 | .hljs-attribute { 359 | color: #0086b3; 360 | } 361 | 362 | .hljs-section, 363 | .hljs-name { 364 | color: #63a35c; 365 | } 366 | 367 | .hljs-tag { 368 | color: #333333; 369 | } 370 | 371 | .hljs-title, 372 | .hljs-attr, 373 | .hljs-selector-id, 374 | .hljs-selector-class, 375 | .hljs-selector-attr, 376 | .hljs-selector-pseudo { 377 | color: #795da3; 378 | } 379 | 380 | .hljs-addition { 381 | color: #55a532; 382 | background-color: #eaffea; 383 | } 384 | 385 | .hljs-deletion { 386 | color: #bd2c00; 387 | background-color: #ffecec; 388 | } 389 | 390 | .hljs-link { 391 | text-decoration: underline; 392 | } 393 | 394 | /* 代码高亮 */ 395 | /* PrismJS 1.15.0 396 | https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */ 397 | /** 398 | * prism.js default theme for JavaScript, CSS and HTML 399 | * Based on dabblet (http://dabblet.com) 400 | * @author Lea Verou 401 | */ 402 | code[class*="language-"], 403 | pre[class*="language-"] { 404 | color: black; 405 | background: none; 406 | text-shadow: 0 1px white; 407 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 408 | text-align: left; 409 | white-space: pre; 410 | word-spacing: normal; 411 | word-break: normal; 412 | word-wrap: normal; 413 | line-height: 1.5; 414 | 415 | -moz-tab-size: 4; 416 | -o-tab-size: 4; 417 | tab-size: 4; 418 | 419 | -webkit-hyphens: none; 420 | -moz-hyphens: none; 421 | -ms-hyphens: none; 422 | hyphens: none; 423 | } 424 | 425 | pre[class*="language-"]::-moz-selection, 426 | pre[class*="language-"] ::-moz-selection, 427 | code[class*="language-"]::-moz-selection, 428 | code[class*="language-"] ::-moz-selection { 429 | text-shadow: none; 430 | background: #b3d4fc; 431 | } 432 | 433 | pre[class*="language-"]::selection, 434 | pre[class*="language-"] ::selection, 435 | code[class*="language-"]::selection, 436 | code[class*="language-"] ::selection { 437 | text-shadow: none; 438 | background: #b3d4fc; 439 | } 440 | 441 | @media print { 442 | 443 | code[class*="language-"], 444 | pre[class*="language-"] { 445 | text-shadow: none; 446 | } 447 | } 448 | 449 | /* Code blocks */ 450 | pre[class*="language-"] { 451 | padding: 1em; 452 | margin: .5em 0; 453 | overflow: auto; 454 | } 455 | 456 | :not(pre)>code[class*="language-"], 457 | pre[class*="language-"] { 458 | background: #f5f2f0; 459 | } 460 | 461 | /* Inline code */ 462 | :not(pre)>code[class*="language-"] { 463 | padding: .1em; 464 | border-radius: .3em; 465 | white-space: normal; 466 | } 467 | 468 | .token.comment, 469 | .token.prolog, 470 | .token.doctype, 471 | .token.cdata { 472 | color: slategray; 473 | } 474 | 475 | .token.punctuation { 476 | color: #999; 477 | } 478 | 479 | .namespace { 480 | opacity: .7; 481 | } 482 | 483 | .token.property, 484 | .token.tag, 485 | .token.boolean, 486 | .token.number, 487 | .token.constant, 488 | .token.symbol, 489 | .token.deleted { 490 | color: #905; 491 | } 492 | 493 | .token.selector, 494 | .token.attr-name, 495 | .token.string, 496 | .token.char, 497 | .token.builtin, 498 | .token.inserted { 499 | color: #690; 500 | } 501 | 502 | .token.operator, 503 | .token.entity, 504 | .token.url, 505 | .language-css .token.string, 506 | .style .token.string { 507 | color: #9a6e3a; 508 | background: hsla(0, 0%, 100%, .5); 509 | } 510 | 511 | .token.atrule, 512 | .token.attr-value, 513 | .token.keyword { 514 | color: #07a; 515 | } 516 | 517 | .token.function, 518 | .token.class-name { 519 | color: #DD4A68; 520 | } 521 | 522 | .token.regex, 523 | .token.important, 524 | .token.variable { 525 | color: #e90; 526 | } 527 | 528 | .token.important, 529 | .token.bold { 530 | font-weight: bold; 531 | } 532 | 533 | .token.italic { 534 | font-style: italic; 535 | } 536 | 537 | .token.entity { 538 | cursor: help; 539 | } 540 | -------------------------------------------------------------------------------- /src/assets/font/demo_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IconFont Demo 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |

19 | 29 |
30 |
31 |
    32 | 33 |
  • 34 | 35 |
    关于我
    36 |
    
    37 |
  • 38 | 39 |
  • 40 | 41 |
    评论
    42 |
    
    43 |
  • 44 | 45 |
  • 46 | 47 |
    眼睛
    48 |
    
    49 |
  • 50 | 51 |
  • 52 | 53 |
    上箭头
    54 |
    
    55 |
  • 56 | 57 |
  • 58 | 59 |
    搜索
    60 |
    
    61 |
  • 62 | 63 |
  • 64 | 65 |
    类目 品类 分类 类别
    66 |
    
    67 |
  • 68 | 69 |
  • 70 | 71 |
    点赞
    72 |
    
    73 |
  • 74 | 75 |
  • 76 | 77 |
    点赞(1)
    78 |
    
    79 |
  • 80 | 81 |
  • 82 | 83 |
    点赞(2)
    84 |
    
    85 |
  • 86 | 87 |
  • 88 | 89 |
    首页
    90 |
    
    91 |
  • 92 | 93 |
  • 94 | 95 |
    点赞1
    96 |
    
    97 |
  • 98 | 99 |
  • 100 | 101 |
    点赞
    102 |
    
    103 |
  • 104 | 105 |
  • 106 | 107 |
    回复
    108 |
    
    109 |
  • 110 | 111 |
  • 112 | 113 |
    信息 (1)
    114 |
    
    115 |
  • 116 | 117 |
  • 118 | 119 |
    搜索
    120 |
    
    121 |
  • 122 | 123 |
  • 124 | 125 |
    bad
    126 |
    
    127 |
  • 128 | 129 |
  • 130 | 131 |
    bad-o
    132 |
    
    133 |
  • 134 | 135 |
  • 136 | 137 |
    标签
    138 |
    
    139 |
  • 140 | 141 |
  • 142 | 143 |
    点赞
    144 |
    
    145 |
  • 146 | 147 |
  • 148 | 149 |
    点赞
    150 |
    
    151 |
  • 152 | 153 |
  • 154 | 155 |
    点赞
    156 |
    
    157 |
  • 158 | 159 |
  • 160 | 161 |
    点赞
    162 |
    
    163 |
  • 164 | 165 |
  • 166 | 167 |
    分类
    168 |
    
    169 |
  • 170 | 171 |
  • 172 | 173 |
    评论-色块icon
    174 |
    
    175 |
  • 176 | 177 |
  • 178 | 179 |
    点赞1
    180 |
    
    181 |
  • 182 | 183 |
  • 184 | 185 |
    信息
    186 |
    
    187 |
  • 188 | 189 |
  • 190 | 191 |
    分类
    192 |
    
    193 |
  • 194 | 195 |
  • 196 | 197 |
    归档
    198 |
    
    199 |
  • 200 | 201 |
  • 202 | 203 |
    点赞
    204 |
    
    205 |
  • 206 | 207 |
  • 208 | 209 |
    搜索
    210 |
    
    211 |
  • 212 | 213 |
  • 214 | 215 |
    分类
    216 |
    
    217 |
  • 218 | 219 |
  • 220 | 221 |
    点赞
    222 |
    
    223 |
  • 224 | 225 |
  • 226 | 227 |
    发送
    228 |
    
    229 |
  • 230 | 231 |
  • 232 | 233 |
    评论
    234 |
    
    235 |
  • 236 | 237 |
  • 238 | 239 |
    github
    240 |
    
    241 |
  • 242 | 243 |
  • 244 | 245 |
    菜单
    246 |
    
    247 |
  • 248 | 249 |
  • 250 | 251 |
    点赞
    252 |
    
    253 |
  • 254 | 255 |
  • 256 | 257 |
    KHCFDC_发送
    258 |
    
    259 |
  • 260 | 261 |
  • 262 | 263 |
    搜索
    264 |
    
    265 |
  • 266 | 267 |
  • 268 | 269 |
    搜索
    270 |
    
    271 |
  • 272 | 273 |
  • 274 | 275 |
    回复评论s
    276 |
    
    277 |
  • 278 | 279 |
280 |
281 |

Unicode 引用

282 |
283 | 284 |

Unicode 是字体在网页端最原始的应用方式,特点是:

285 |
    286 |
  • 兼容性最好,支持 IE6+,及所有现代浏览器。
  • 287 |
  • 支持按字体的方式去动态调整图标大小,颜色等等。
  • 288 |
  • 但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。
  • 289 |
290 |
291 |

注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式

292 |
293 |

Unicode 使用步骤如下:

294 |

第一步:拷贝项目下面生成的 @font-face

295 |
@font-face {
 297 |   font-family: 'iconfont';
 298 |   src: url('iconfont.eot');
 299 |   src: url('iconfont.eot?#iefix') format('embedded-opentype'),
 300 |       url('iconfont.woff2') format('woff2'),
 301 |       url('iconfont.woff') format('woff'),
 302 |       url('iconfont.ttf') format('truetype'),
 303 |       url('iconfont.svg#iconfont') format('svg');
 304 | }
 305 | 
306 |

第二步:定义使用 iconfont 的样式

307 |
.iconfont {
 309 |   font-family: "iconfont" !important;
 310 |   font-size: 16px;
 311 |   font-style: normal;
 312 |   -webkit-font-smoothing: antialiased;
 313 |   -moz-osx-font-smoothing: grayscale;
 314 | }
 315 | 
316 |

第三步:挑选相应图标并获取字体编码,应用于页面

317 |
 318 | <span class="iconfont">&#x33;</span>
 320 | 
321 |
322 |

"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。

323 |
324 |
325 |
326 |
327 |
    328 | 329 |
  • 330 | 331 |
    332 | 关于我 333 |
    334 |
    .icon-guanyuwo 335 |
    336 |
  • 337 | 338 |
  • 339 | 340 |
    341 | 评论 342 |
    343 |
    .icon-icon1 344 |
    345 |
  • 346 | 347 |
  • 348 | 349 |
    350 | 眼睛 351 |
    352 |
    .icon-yanjing 353 |
    354 |
  • 355 | 356 |
  • 357 | 358 |
    359 | 上箭头 360 |
    361 |
    .icon-iconfonticonfonti2copy 362 |
    363 |
  • 364 | 365 |
  • 366 | 367 |
    368 | 搜索 369 |
    370 |
    .icon-sousuo1 371 |
    372 |
  • 373 | 374 |
  • 375 | 376 |
    377 | 类目 品类 分类 类别 378 |
    379 |
    .icon-leimupinleifenleileibie 380 |
    381 |
  • 382 | 383 |
  • 384 | 385 |
    386 | 点赞 387 |
    388 |
    .icon-dianzan 389 |
    390 |
  • 391 | 392 |
  • 393 | 394 |
    395 | 点赞(1) 396 |
    397 |
    .icon-dianzan1 398 |
    399 |
  • 400 | 401 |
  • 402 | 403 |
    404 | 点赞(2) 405 |
    406 |
    .icon-dianzan2 407 |
    408 |
  • 409 | 410 |
  • 411 | 412 |
    413 | 首页 414 |
    415 |
    .icon-shouye 416 |
    417 |
  • 418 | 419 |
  • 420 | 421 |
    422 | 点赞1 423 |
    424 |
    .icon-dianzan21 425 |
    426 |
  • 427 | 428 |
  • 429 | 430 |
    431 | 点赞 432 |
    433 |
    .icon-iconfontzhizuobiaozhun44 434 |
    435 |
  • 436 | 437 |
  • 438 | 439 |
    440 | 回复 441 |
    442 |
    .icon-icon_reply 443 |
    444 |
  • 445 | 446 |
  • 447 | 448 |
    449 | 信息 (1) 450 |
    451 |
    .icon-xinxi1 452 |
    453 |
  • 454 | 455 |
  • 456 | 457 |
    458 | 搜索 459 |
    460 |
    .icon-sousuo2 461 |
    462 |
  • 463 | 464 |
  • 465 | 466 |
    467 | bad 468 |
    469 |
    .icon-bad 470 |
    471 |
  • 472 | 473 |
  • 474 | 475 |
    476 | bad-o 477 |
    478 |
    .icon-bad-o 479 |
    480 |
  • 481 | 482 |
  • 483 | 484 |
    485 | 标签 486 |
    487 |
    .icon-biaoqian 488 |
    489 |
  • 490 | 491 |
  • 492 | 493 |
    494 | 点赞 495 |
    496 |
    .icon-dianzan11 497 |
    498 |
  • 499 | 500 |
  • 501 | 502 |
    503 | 点赞 504 |
    505 |
    .icon-dianzan3 506 |
    507 |
  • 508 | 509 |
  • 510 | 511 |
    512 | 点赞 513 |
    514 |
    .icon-dianzan4 515 |
    516 |
  • 517 | 518 |
  • 519 | 520 |
    521 | 点赞 522 |
    523 |
    .icon-dianzan_active 524 |
    525 |
  • 526 | 527 |
  • 528 | 529 |
    530 | 分类 531 |
    532 |
    .icon-shuangsechangyongtubiao- 533 |
    534 |
  • 535 | 536 |
  • 537 | 538 |
    539 | 评论-色块icon 540 |
    541 |
    .icon-icon 542 |
    543 |
  • 544 | 545 |
  • 546 | 547 |
    548 | 点赞1 549 |
    550 |
    .icon-dianzan5 551 |
    552 |
  • 553 | 554 |
  • 555 | 556 |
    557 | 信息 558 |
    559 |
    .icon-xinxi 560 |
    561 |
  • 562 | 563 |
  • 564 | 565 |
    566 | 分类 567 |
    568 |
    .icon-tubiao- 569 |
    570 |
  • 571 | 572 |
  • 573 | 574 |
    575 | 归档 576 |
    577 |
    .icon-guidang 578 |
    579 |
  • 580 | 581 |
  • 582 | 583 |
    584 | 点赞 585 |
    586 |
    .icon-dianzan_active-copy 587 |
    588 |
  • 589 | 590 |
  • 591 | 592 |
    593 | 搜索 594 |
    595 |
    .icon-tianchongxing- 596 |
    597 |
  • 598 | 599 |
  • 600 | 601 |
    602 | 分类 603 |
    604 |
    .icon-icon-- 605 |
    606 |
  • 607 | 608 |
  • 609 | 610 |
    611 | 点赞 612 |
    613 |
    .icon-fabulous 614 |
    615 |
  • 616 | 617 |
  • 618 | 619 |
    620 | 发送 621 |
    622 |
    .icon-fasong 623 |
    624 |
  • 625 | 626 |
  • 627 | 628 |
    629 | 评论 630 |
    631 |
    .icon-pinglun 632 |
    633 |
  • 634 | 635 |
  • 636 | 637 |
    638 | github 639 |
    640 |
    .icon-github 641 |
    642 |
  • 643 | 644 |
  • 645 | 646 |
    647 | 菜单 648 |
    649 |
    .icon-ziyuan 650 |
    651 |
  • 652 | 653 |
  • 654 | 655 |
    656 | 点赞 657 |
    658 |
    .icon-dianzan6 659 |
    660 |
  • 661 | 662 |
  • 663 | 664 |
    665 | KHCFDC_发送 666 |
    667 |
    .icon-fasong1 668 |
    669 |
  • 670 | 671 |
  • 672 | 673 |
    674 | 搜索 675 |
    676 |
    .icon-sousuo- 677 |
    678 |
  • 679 | 680 |
  • 681 | 682 |
    683 | 搜索 684 |
    685 |
    .icon-sousuo 686 |
    687 |
  • 688 | 689 |
  • 690 | 691 |
    692 | 回复评论s 693 |
    694 |
    .icon-huifupingluns 695 |
    696 |
  • 697 | 698 |
699 |
700 |

font-class 引用

701 |
702 | 703 |

font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。

704 |

与 Unicode 使用方式相比,具有如下特点:

705 |
    706 |
  • 兼容性良好,支持 IE8+,及所有现代浏览器。
  • 707 |
  • 相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。
  • 708 |
  • 因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。
  • 709 |
  • 不过因为本质上还是使用的字体,所以多色图标还是不支持的。
  • 710 |
711 |

使用步骤如下:

712 |

第一步:引入项目下面生成的 fontclass 代码:

713 |
<link rel="stylesheet" href="./iconfont.css">
 714 | 
715 |

第二步:挑选相应图标并获取类名,应用于页面:

716 |
<span class="iconfont icon-xxx"></span>
 717 | 
718 |
719 |

" 720 | iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。

721 |
722 |
723 |
724 |
725 |
    726 | 727 |
  • 728 | 731 |
    关于我
    732 |
    #icon-guanyuwo
    733 |
  • 734 | 735 |
  • 736 | 739 |
    评论
    740 |
    #icon-icon1
    741 |
  • 742 | 743 |
  • 744 | 747 |
    眼睛
    748 |
    #icon-yanjing
    749 |
  • 750 | 751 |
  • 752 | 755 |
    上箭头
    756 |
    #icon-iconfonticonfonti2copy
    757 |
  • 758 | 759 |
  • 760 | 763 |
    搜索
    764 |
    #icon-sousuo1
    765 |
  • 766 | 767 |
  • 768 | 771 |
    类目 品类 分类 类别
    772 |
    #icon-leimupinleifenleileibie
    773 |
  • 774 | 775 |
  • 776 | 779 |
    点赞
    780 |
    #icon-dianzan
    781 |
  • 782 | 783 |
  • 784 | 787 |
    点赞(1)
    788 |
    #icon-dianzan1
    789 |
  • 790 | 791 |
  • 792 | 795 |
    点赞(2)
    796 |
    #icon-dianzan2
    797 |
  • 798 | 799 |
  • 800 | 803 |
    首页
    804 |
    #icon-shouye
    805 |
  • 806 | 807 |
  • 808 | 811 |
    点赞1
    812 |
    #icon-dianzan21
    813 |
  • 814 | 815 |
  • 816 | 819 |
    点赞
    820 |
    #icon-iconfontzhizuobiaozhun44
    821 |
  • 822 | 823 |
  • 824 | 827 |
    回复
    828 |
    #icon-icon_reply
    829 |
  • 830 | 831 |
  • 832 | 835 |
    信息 (1)
    836 |
    #icon-xinxi1
    837 |
  • 838 | 839 |
  • 840 | 843 |
    搜索
    844 |
    #icon-sousuo2
    845 |
  • 846 | 847 |
  • 848 | 851 |
    bad
    852 |
    #icon-bad
    853 |
  • 854 | 855 |
  • 856 | 859 |
    bad-o
    860 |
    #icon-bad-o
    861 |
  • 862 | 863 |
  • 864 | 867 |
    标签
    868 |
    #icon-biaoqian
    869 |
  • 870 | 871 |
  • 872 | 875 |
    点赞
    876 |
    #icon-dianzan11
    877 |
  • 878 | 879 |
  • 880 | 883 |
    点赞
    884 |
    #icon-dianzan3
    885 |
  • 886 | 887 |
  • 888 | 891 |
    点赞
    892 |
    #icon-dianzan4
    893 |
  • 894 | 895 |
  • 896 | 899 |
    点赞
    900 |
    #icon-dianzan_active
    901 |
  • 902 | 903 |
  • 904 | 907 |
    分类
    908 |
    #icon-shuangsechangyongtubiao-
    909 |
  • 910 | 911 |
  • 912 | 915 |
    评论-色块icon
    916 |
    #icon-icon
    917 |
  • 918 | 919 |
  • 920 | 923 |
    点赞1
    924 |
    #icon-dianzan5
    925 |
  • 926 | 927 |
  • 928 | 931 |
    信息
    932 |
    #icon-xinxi
    933 |
  • 934 | 935 |
  • 936 | 939 |
    分类
    940 |
    #icon-tubiao-
    941 |
  • 942 | 943 |
  • 944 | 947 |
    归档
    948 |
    #icon-guidang
    949 |
  • 950 | 951 |
  • 952 | 955 |
    点赞
    956 |
    #icon-dianzan_active-copy
    957 |
  • 958 | 959 |
  • 960 | 963 |
    搜索
    964 |
    #icon-tianchongxing-
    965 |
  • 966 | 967 |
  • 968 | 971 |
    分类
    972 |
    #icon-icon--
    973 |
  • 974 | 975 |
  • 976 | 979 |
    点赞
    980 |
    #icon-fabulous
    981 |
  • 982 | 983 |
  • 984 | 987 |
    发送
    988 |
    #icon-fasong
    989 |
  • 990 | 991 |
  • 992 | 995 |
    评论
    996 |
    #icon-pinglun
    997 |
  • 998 | 999 |
  • 1000 | 1003 |
    github
    1004 |
    #icon-github
    1005 |
  • 1006 | 1007 |
  • 1008 | 1011 |
    菜单
    1012 |
    #icon-ziyuan
    1013 |
  • 1014 | 1015 |
  • 1016 | 1019 |
    点赞
    1020 |
    #icon-dianzan6
    1021 |
  • 1022 | 1023 |
  • 1024 | 1027 |
    KHCFDC_发送
    1028 |
    #icon-fasong1
    1029 |
  • 1030 | 1031 |
  • 1032 | 1035 |
    搜索
    1036 |
    #icon-sousuo-
    1037 |
  • 1038 | 1039 |
  • 1040 | 1043 |
    搜索
    1044 |
    #icon-sousuo
    1045 |
  • 1046 | 1047 |
  • 1048 | 1051 |
    回复评论s
    1052 |
    #icon-huifupingluns
    1053 |
  • 1054 | 1055 |
1056 |
1057 |

Symbol 引用

1058 |
1059 | 1060 |

这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章 1061 | 这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:

1062 |
    1063 |
  • 支持多色图标了,不再受单色限制。
  • 1064 |
  • 通过一些技巧,支持像字体那样,通过 font-size, color 来调整样式。
  • 1065 |
  • 兼容性较差,支持 IE9+,及现代浏览器。
  • 1066 |
  • 浏览器渲染 SVG 的性能一般,还不如 png。
  • 1067 |
1068 |

使用步骤如下:

1069 |

第一步:引入项目下面生成的 symbol 代码:

1070 |
<script src="./iconfont.js"></script>
1071 | 
1072 |

第二步:加入通用 CSS 代码(引入一次就行):

1073 |
<style>
1074 | .icon {
1075 |   width: 1em;
1076 |   height: 1em;
1077 |   vertical-align: -0.15em;
1078 |   fill: currentColor;
1079 |   overflow: hidden;
1080 | }
1081 | </style>
1082 | 
1083 |

第三步:挑选相应图标并获取类名,应用于页面:

1084 |
<svg class="icon" aria-hidden="true">
1085 |   <use xlink:href="#icon-xxx"></use>
1086 | </svg>
1087 | 
1088 |
1089 |
1090 | 1091 |
1092 |
1093 | 1112 | 1113 | 1114 | -------------------------------------------------------------------------------- /src/assets/font/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face {font-family: "iconfont"; 2 | src: url('iconfont.eot?t=1575292836116'); /* IE9 */ 3 | src: url('iconfont.eot?t=1575292836116#iefix') format('embedded-opentype'), /* IE6-IE8 */ 4 | url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), 5 | url('iconfont.woff?t=1575292836116') format('woff'), 6 | url('iconfont.ttf?t=1575292836116') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ 7 | url('iconfont.svg?t=1575292836116#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .iconfont { 11 | font-family: "iconfont" !important; 12 | font-size: 16px; 13 | font-style: normal; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | .icon-guanyuwo:before { 19 | content: "\e605"; 20 | } 21 | 22 | .icon-icon1:before { 23 | content: "\e62e"; 24 | } 25 | 26 | .icon-yanjing:before { 27 | content: "\e627"; 28 | } 29 | 30 | .icon-iconfonticonfonti2copy:before { 31 | content: "\e62d"; 32 | } 33 | 34 | .icon-sousuo1:before { 35 | content: "\e684"; 36 | } 37 | 38 | .icon-leimupinleifenleileibie:before { 39 | content: "\e7f9"; 40 | } 41 | 42 | .icon-dianzan:before { 43 | content: "\e616"; 44 | } 45 | 46 | .icon-dianzan1:before { 47 | content: "\e60e"; 48 | } 49 | 50 | .icon-dianzan2:before { 51 | content: "\e60f"; 52 | } 53 | 54 | .icon-shouye:before { 55 | content: "\e626"; 56 | } 57 | 58 | .icon-dianzan21:before { 59 | content: "\e63a"; 60 | } 61 | 62 | .icon-iconfontzhizuobiaozhun44:before { 63 | content: "\e62b"; 64 | } 65 | 66 | .icon-icon_reply:before { 67 | content: "\e609"; 68 | } 69 | 70 | .icon-xinxi1:before { 71 | content: "\e625"; 72 | } 73 | 74 | .icon-sousuo2:before { 75 | content: "\e89c"; 76 | } 77 | 78 | .icon-bad:before { 79 | content: "\e683"; 80 | } 81 | 82 | .icon-bad-o:before { 83 | content: "\e685"; 84 | } 85 | 86 | .icon-biaoqian:before { 87 | content: "\e604"; 88 | } 89 | 90 | .icon-dianzan11:before { 91 | content: "\e600"; 92 | } 93 | 94 | .icon-dianzan3:before { 95 | content: "\e669"; 96 | } 97 | 98 | .icon-dianzan4:before { 99 | content: "\e676"; 100 | } 101 | 102 | .icon-dianzan_active:before { 103 | content: "\e610"; 104 | } 105 | 106 | .icon-shuangsechangyongtubiao-:before { 107 | content: "\e607"; 108 | } 109 | 110 | .icon-icon:before { 111 | content: "\e65c"; 112 | } 113 | 114 | .icon-dianzan5:before { 115 | content: "\e63b"; 116 | } 117 | 118 | .icon-xinxi:before { 119 | content: "\e646"; 120 | } 121 | 122 | .icon-tubiao-:before { 123 | content: "\e60d"; 124 | } 125 | 126 | .icon-guidang:before { 127 | content: "\e666"; 128 | } 129 | 130 | .icon-dianzan_active-copy:before { 131 | content: "\e601"; 132 | } 133 | 134 | .icon-tianchongxing-:before { 135 | content: "\e629"; 136 | } 137 | 138 | .icon-icon--:before { 139 | content: "\e63f"; 140 | } 141 | 142 | .icon-fabulous:before { 143 | content: "\e603"; 144 | } 145 | 146 | .icon-fasong:before { 147 | content: "\e602"; 148 | } 149 | 150 | .icon-pinglun:before { 151 | content: "\e62a"; 152 | } 153 | 154 | .icon-github:before { 155 | content: "\e690"; 156 | } 157 | 158 | .icon-ziyuan:before { 159 | content: "\e612"; 160 | } 161 | 162 | .icon-dianzan6:before { 163 | content: "\e680"; 164 | } 165 | 166 | .icon-fasong1:before { 167 | content: "\e6cc"; 168 | } 169 | 170 | .icon-sousuo-:before { 171 | content: "\e64d"; 172 | } 173 | 174 | .icon-sousuo:before { 175 | content: "\e624"; 176 | } 177 | 178 | .icon-huifupingluns:before { 179 | content: "\e651"; 180 | } 181 | 182 | -------------------------------------------------------------------------------- /src/assets/font/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/src/assets/font/iconfont.eot -------------------------------------------------------------------------------- /src/assets/font/iconfont.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "1527407", 3 | "name": "blog", 4 | "font_family": "iconfont", 5 | "css_prefix_text": "icon-", 6 | "description": "", 7 | "glyphs": [ 8 | { 9 | "icon_id": "93276", 10 | "name": "关于我", 11 | "font_class": "guanyuwo", 12 | "unicode": "e605", 13 | "unicode_decimal": 58885 14 | }, 15 | { 16 | "icon_id": "101061", 17 | "name": "评论", 18 | "font_class": "icon1", 19 | "unicode": "e62e", 20 | "unicode_decimal": 58926 21 | }, 22 | { 23 | "icon_id": "423695", 24 | "name": "眼睛", 25 | "font_class": "yanjing", 26 | "unicode": "e627", 27 | "unicode_decimal": 58919 28 | }, 29 | { 30 | "icon_id": "584243", 31 | "name": "上箭头", 32 | "font_class": "iconfonticonfonti2copy", 33 | "unicode": "e62d", 34 | "unicode_decimal": 58925 35 | }, 36 | { 37 | "icon_id": "669832", 38 | "name": "搜索", 39 | "font_class": "sousuo1", 40 | "unicode": "e684", 41 | "unicode_decimal": 59012 42 | }, 43 | { 44 | "icon_id": "689262", 45 | "name": "类目 品类 分类 类别", 46 | "font_class": "leimupinleifenleileibie", 47 | "unicode": "e7f9", 48 | "unicode_decimal": 59385 49 | }, 50 | { 51 | "icon_id": "706841", 52 | "name": "点赞", 53 | "font_class": "dianzan", 54 | "unicode": "e616", 55 | "unicode_decimal": 58902 56 | }, 57 | { 58 | "icon_id": "886696", 59 | "name": "点赞(1)", 60 | "font_class": "dianzan1", 61 | "unicode": "e60e", 62 | "unicode_decimal": 58894 63 | }, 64 | { 65 | "icon_id": "886697", 66 | "name": "点赞(2)", 67 | "font_class": "dianzan2", 68 | "unicode": "e60f", 69 | "unicode_decimal": 58895 70 | }, 71 | { 72 | "icon_id": "1002521", 73 | "name": "首页", 74 | "font_class": "shouye", 75 | "unicode": "e626", 76 | "unicode_decimal": 58918 77 | }, 78 | { 79 | "icon_id": "1004631", 80 | "name": "点赞1", 81 | "font_class": "dianzan21", 82 | "unicode": "e63a", 83 | "unicode_decimal": 58938 84 | }, 85 | { 86 | "icon_id": "1012782", 87 | "name": "点赞", 88 | "font_class": "iconfontzhizuobiaozhun44", 89 | "unicode": "e62b", 90 | "unicode_decimal": 58923 91 | }, 92 | { 93 | "icon_id": "1048856", 94 | "name": "回复", 95 | "font_class": "icon_reply", 96 | "unicode": "e609", 97 | "unicode_decimal": 58889 98 | }, 99 | { 100 | "icon_id": "1082509", 101 | "name": "信息 (1)", 102 | "font_class": "xinxi1", 103 | "unicode": "e625", 104 | "unicode_decimal": 58917 105 | }, 106 | { 107 | "icon_id": "1278266", 108 | "name": "搜索", 109 | "font_class": "sousuo2", 110 | "unicode": "e89c", 111 | "unicode_decimal": 59548 112 | }, 113 | { 114 | "icon_id": "1467314", 115 | "name": "bad", 116 | "font_class": "bad", 117 | "unicode": "e683", 118 | "unicode_decimal": 59011 119 | }, 120 | { 121 | "icon_id": "1467319", 122 | "name": "bad-o", 123 | "font_class": "bad-o", 124 | "unicode": "e685", 125 | "unicode_decimal": 59013 126 | }, 127 | { 128 | "icon_id": "1957876", 129 | "name": "标签", 130 | "font_class": "biaoqian", 131 | "unicode": "e604", 132 | "unicode_decimal": 58884 133 | }, 134 | { 135 | "icon_id": "3683441", 136 | "name": "点赞", 137 | "font_class": "dianzan11", 138 | "unicode": "e600", 139 | "unicode_decimal": 58880 140 | }, 141 | { 142 | "icon_id": "4163427", 143 | "name": "点赞", 144 | "font_class": "dianzan3", 145 | "unicode": "e669", 146 | "unicode_decimal": 58985 147 | }, 148 | { 149 | "icon_id": "4197845", 150 | "name": "点赞", 151 | "font_class": "dianzan4", 152 | "unicode": "e676", 153 | "unicode_decimal": 58998 154 | }, 155 | { 156 | "icon_id": "4904547", 157 | "name": "点赞", 158 | "font_class": "dianzan_active", 159 | "unicode": "e610", 160 | "unicode_decimal": 58896 161 | }, 162 | { 163 | "icon_id": "5065479", 164 | "name": "分类", 165 | "font_class": "shuangsechangyongtubiao-", 166 | "unicode": "e607", 167 | "unicode_decimal": 58887 168 | }, 169 | { 170 | "icon_id": "5117629", 171 | "name": "评论-色块icon", 172 | "font_class": "icon", 173 | "unicode": "e65c", 174 | "unicode_decimal": 58972 175 | }, 176 | { 177 | "icon_id": "5121485", 178 | "name": "点赞1", 179 | "font_class": "dianzan5", 180 | "unicode": "e63b", 181 | "unicode_decimal": 58939 182 | }, 183 | { 184 | "icon_id": "5174622", 185 | "name": "信息", 186 | "font_class": "xinxi", 187 | "unicode": "e646", 188 | "unicode_decimal": 58950 189 | }, 190 | { 191 | "icon_id": "5233413", 192 | "name": "分类", 193 | "font_class": "tubiao-", 194 | "unicode": "e60d", 195 | "unicode_decimal": 58893 196 | }, 197 | { 198 | "icon_id": "5809108", 199 | "name": "归档", 200 | "font_class": "guidang", 201 | "unicode": "e666", 202 | "unicode_decimal": 58982 203 | }, 204 | { 205 | "icon_id": "6256767", 206 | "name": "点赞", 207 | "font_class": "dianzan_active-copy", 208 | "unicode": "e601", 209 | "unicode_decimal": 58881 210 | }, 211 | { 212 | "icon_id": "6445933", 213 | "name": "搜索", 214 | "font_class": "tianchongxing-", 215 | "unicode": "e629", 216 | "unicode_decimal": 58921 217 | }, 218 | { 219 | "icon_id": "6556479", 220 | "name": "分类", 221 | "font_class": "icon--", 222 | "unicode": "e63f", 223 | "unicode_decimal": 58943 224 | }, 225 | { 226 | "icon_id": "7564152", 227 | "name": "点赞", 228 | "font_class": "fabulous", 229 | "unicode": "e603", 230 | "unicode_decimal": 58883 231 | }, 232 | { 233 | "icon_id": "7974070", 234 | "name": "发送", 235 | "font_class": "fasong", 236 | "unicode": "e602", 237 | "unicode_decimal": 58882 238 | }, 239 | { 240 | "icon_id": "8165730", 241 | "name": "评论", 242 | "font_class": "pinglun", 243 | "unicode": "e62a", 244 | "unicode_decimal": 58922 245 | }, 246 | { 247 | "icon_id": "9307591", 248 | "name": "github", 249 | "font_class": "github", 250 | "unicode": "e690", 251 | "unicode_decimal": 59024 252 | }, 253 | { 254 | "icon_id": "9559033", 255 | "name": "菜单", 256 | "font_class": "ziyuan", 257 | "unicode": "e612", 258 | "unicode_decimal": 58898 259 | }, 260 | { 261 | "icon_id": "9713061", 262 | "name": "点赞", 263 | "font_class": "dianzan6", 264 | "unicode": "e680", 265 | "unicode_decimal": 59008 266 | }, 267 | { 268 | "icon_id": "9874479", 269 | "name": "KHCFDC_发送", 270 | "font_class": "fasong1", 271 | "unicode": "e6cc", 272 | "unicode_decimal": 59084 273 | }, 274 | { 275 | "icon_id": "10651918", 276 | "name": "搜索", 277 | "font_class": "sousuo-", 278 | "unicode": "e64d", 279 | "unicode_decimal": 58957 280 | }, 281 | { 282 | "icon_id": "11261961", 283 | "name": "搜索", 284 | "font_class": "sousuo", 285 | "unicode": "e624", 286 | "unicode_decimal": 58916 287 | }, 288 | { 289 | "icon_id": "11537790", 290 | "name": "回复评论s", 291 | "font_class": "huifupingluns", 292 | "unicode": "e651", 293 | "unicode_decimal": 58961 294 | } 295 | ] 296 | } 297 | -------------------------------------------------------------------------------- /src/assets/font/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/src/assets/font/iconfont.ttf -------------------------------------------------------------------------------- /src/assets/font/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/src/assets/font/iconfont.woff -------------------------------------------------------------------------------- /src/assets/font/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/src/assets/font/iconfont.woff2 -------------------------------------------------------------------------------- /src/assets/image/github.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibupi/vue-blog-web/9d7eb311cde95e91520458c5402d0da2e6dd02bb/src/assets/image/github.jpg -------------------------------------------------------------------------------- /src/assets/scss/public.scss: -------------------------------------------------------------------------------- 1 | .clearfix:after { 2 | content: '.'; /* 这里尽量写点内容,否则在IE6-7会出现间隙 */ 3 | display: block; /* 转换为块级元素 */ 4 | height: 0; /* 高度为0 */ 5 | clear: both; /* 清除浮动 */ 6 | visibility: hidden; /* 隐藏盒子 */ 7 | } 8 | .clearfix { 9 | *zoom: 1; /* 这是专门给IE6-7做的清除浮动 */ 10 | } 11 | -------------------------------------------------------------------------------- /src/assets/scss/reset.scss: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, 7 | body, 8 | div, 9 | span, 10 | applet, 11 | object, 12 | iframe, 13 | p, 14 | blockquote, 15 | pre, 16 | a, 17 | abbr, 18 | acronym, 19 | address, 20 | big, 21 | cite, 22 | code, 23 | del, 24 | dfn, 25 | em, 26 | img, 27 | ins, 28 | kbd, 29 | q, 30 | s, 31 | samp, 32 | small, 33 | strike, 34 | strong, 35 | sub, 36 | sup, 37 | tt, 38 | var, 39 | b, 40 | u, 41 | i, 42 | center, 43 | dl, 44 | dt, 45 | dd, 46 | ol, 47 | ul, 48 | li, 49 | fieldset, 50 | form, 51 | label, 52 | legend, 53 | table, 54 | caption, 55 | tbody, 56 | tfoot, 57 | thead, 58 | tr, 59 | th, 60 | td, 61 | article, 62 | aside, 63 | canvas, 64 | details, 65 | embed, 66 | figure, 67 | figcaption, 68 | footer, 69 | header, 70 | hgroup, 71 | menu, 72 | nav, 73 | output, 74 | ruby, 75 | section, 76 | summary, 77 | time, 78 | mark, 79 | audio, 80 | video { 81 | margin: 0; 82 | padding: 0; 83 | border: 0; 84 | font-size: 100%; 85 | font: inherit; 86 | vertical-align: baseline; 87 | } 88 | /* HTML5 display-role reset for older browsers */ 89 | article, 90 | aside, 91 | details, 92 | figcaption, 93 | figure, 94 | footer, 95 | header, 96 | hgroup, 97 | menu, 98 | nav, 99 | section { 100 | display: block; 101 | } 102 | body { 103 | line-height: 1; 104 | } 105 | ol, 106 | ul { 107 | list-style: none; 108 | } 109 | blockquote, 110 | q { 111 | quotes: none; 112 | } 113 | blockquote:before, 114 | blockquote:after, 115 | q:before, 116 | q:after { 117 | content: ''; 118 | content: none; 119 | } 120 | table { 121 | border-collapse: collapse; 122 | border-spacing: 0; 123 | } 124 | body { 125 | font-family: 'Noto Sans', sans-serif; 126 | font-size: 16px; 127 | font-weight: 400; 128 | line-height: 1.5; 129 | word-wrap: break-word; 130 | word-break: break-word; 131 | overflow-y: hidden; 132 | } 133 | h1, 134 | h2, 135 | h3, 136 | h4, 137 | h5, 138 | h6 { 139 | margin: 0; 140 | padding-bottom: 10px; 141 | margin: 20px 0; 142 | border-bottom: 1px solid #ccc; 143 | } 144 | -------------------------------------------------------------------------------- /src/components/articles/articles.vue: -------------------------------------------------------------------------------- 1 | 56 | 73 | 190 | -------------------------------------------------------------------------------- /src/components/comments/comments.vue: -------------------------------------------------------------------------------- 1 | 148 | 329 | 490 | -------------------------------------------------------------------------------- /src/components/footer/footer.vue: -------------------------------------------------------------------------------- 1 | 6 | 9 | 16 | -------------------------------------------------------------------------------- /src/components/header/header.vue: -------------------------------------------------------------------------------- 1 | 159 | 338 | 501 | -------------------------------------------------------------------------------- /src/components/swiper/swiper.vue: -------------------------------------------------------------------------------- 1 | 6 | 9 | 15 | -------------------------------------------------------------------------------- /src/config/index.js: -------------------------------------------------------------------------------- 1 | export const baseURL = 2 | process.env.NODE_ENV === 'production' 3 | ? 'http://111.229.228.223:5001' 4 | : 'http://localhost:5001'; 5 | -------------------------------------------------------------------------------- /src/lib/axios.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { baseURL } from '@/config'; 3 | import { Loading } from 'element-ui'; 4 | class HttpRequest { 5 | constructor(baseUrl = baseURL) { 6 | this.baseUrl = baseUrl; 7 | this.queue = {}; 8 | } 9 | getInsideConfig() { 10 | const config = { 11 | baseURL: this.baseUrl, 12 | headers: { 13 | // 14 | } 15 | }; 16 | return config; 17 | } 18 | distroy(url) { 19 | delete this.queue[url]; 20 | if (!Object.keys(this.queue).length) { 21 | // Spin.hide() 22 | } 23 | } 24 | interceptors(instance, url) { 25 | instance.interceptors.request.use( 26 | config => { 27 | const token = localStorage.getItem('token'); 28 | // 添加全局的loading... 29 | if (!Object.keys(this.queue).length) { 30 | // Spin.show() 31 | } 32 | this.queue[url] = true; 33 | if (token) { 34 | config.headers.common['Authorization'] = 'Bearer ' + token; 35 | } 36 | return config; 37 | }, 38 | error => { 39 | return Promise.reject(error); 40 | } 41 | ); 42 | instance.interceptors.response.use( 43 | res => { 44 | this.distroy(url); 45 | const { data } = res; 46 | return data; 47 | }, 48 | error => { 49 | this.distroy(url); 50 | return Promise.reject(error.response.data); 51 | } 52 | ); 53 | } 54 | request(options) { 55 | const instance = axios.create(); 56 | options = Object.assign(this.getInsideConfig(), options); 57 | this.interceptors(instance, options.url); 58 | return instance(options); 59 | } 60 | } 61 | export default HttpRequest; 62 | -------------------------------------------------------------------------------- /src/lib/highlight.js: -------------------------------------------------------------------------------- 1 | // import Hljs from "highlight.js"; 2 | // let Highlight = {}; 3 | // Highlight.install = function(Vue) { 4 | // // 先有数据再绑定,调用highlightA 5 | // Vue.directive("highlightA", { 6 | // inserted: function(el) { 7 | // let blocks = el.querySelectorAll("code"); 8 | // for (let i = 0; i < blocks.length; i++) { 9 | // const item = blocks[i]; 10 | // Hljs.highlightBlock(item); 11 | // } 12 | // } 13 | // }); 14 | 15 | // // 先绑定,后面会有数据更新,调用highlightB 16 | // Vue.directive("highlight", { 17 | // componentUpdated: function(el) { 18 | // let blocks = el.querySelectorAll("code"); 19 | // for (let i = 0; i < blocks.length; i++) { 20 | // const item = blocks[i]; 21 | // Hljs.highlightBlock(item); 22 | // } 23 | // } 24 | // }); 25 | // }; 26 | 27 | // export default Highlight; 28 | -------------------------------------------------------------------------------- /src/lib/markdown.js: -------------------------------------------------------------------------------- 1 | import marked from 'marked'; 2 | import xss from 'xss'; 3 | import hljs from 'highlight.js'; 4 | export const translateMarkdown = (plainText, isGuardXss = false) => { 5 | return marked(isGuardXss ? xss(plainText) : plainText, { 6 | renderer: new marked.Renderer(), 7 | gfm: true, 8 | pedantic: false, 9 | sanitize: false, 10 | tables: true, 11 | breaks: true, 12 | smartLists: true, 13 | smartypants: true, 14 | highlight: function(code) { 15 | return hljs.highlightAuto(code).value; 16 | } 17 | }); 18 | }; 19 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import { 3 | Button, 4 | Input, 5 | Card, 6 | pagination, 7 | Dialog, 8 | Form, 9 | FormItem, 10 | Tag, 11 | Timeline, 12 | TimelineItem, 13 | Backtop, 14 | Tooltip, 15 | Icon, 16 | Image, 17 | Avatar 18 | } from 'element-ui'; 19 | import App from './App.vue'; 20 | // import "./registerServiceWorker"; 21 | import moment from 'moment'; 22 | import VueRouter from 'vue-router'; 23 | import router from './router'; 24 | import store from './store'; 25 | import animated from 'animate.css'; 26 | import './assets/scss/reset.scss'; 27 | import './assets/font/iconfont.css'; 28 | Vue.filter('dateformat', function(dataStr, pattern = 'YYYY-MM-DD') { 29 | return moment(dataStr).format(pattern); 30 | }); 31 | // 解决移动端重复点击路由报错 32 | const routerPush = VueRouter.prototype.push; 33 | VueRouter.prototype.push = function push(location) { 34 | return routerPush.call(this, location).catch(error => error); 35 | }; 36 | Vue.use(animated); 37 | Vue.use(Input) 38 | .use(Button) 39 | .use(pagination) 40 | .use(Dialog) 41 | .use(Form) 42 | .use(FormItem) 43 | .use(Tag) 44 | .use(Timeline) 45 | .use(TimelineItem) 46 | .use(Backtop) 47 | .use(Tooltip) 48 | .use(Icon) 49 | .use(Image) 50 | .use(Avatar) 51 | .use(Card); 52 | Vue.config.productionTip = false; 53 | // 解决elementui打开模态框给body加padding-right 17px的问题 54 | function handlePadding() { 55 | let MutationObserver = 56 | window.MutationObserver || 57 | window.WebKitMutationObserver || 58 | window.MozMutationObserver; 59 | 60 | let observer = new MutationObserver(mutations => { 61 | mutations.forEach(item => { 62 | if ('style' == item.attributeName) { 63 | document.body.style.padding = 0; 64 | } 65 | }); 66 | }); 67 | 68 | var body = document.body; 69 | 70 | var options = { 71 | attributes: true 72 | }; 73 | 74 | observer.observe(body, options); 75 | } 76 | handlePadding(); 77 | new Vue({ 78 | router, 79 | store, 80 | render: h => h(App) 81 | }).$mount('#app'); 82 | -------------------------------------------------------------------------------- /src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | // /* eslint-disable no-console */ 2 | 3 | // import { register } from "register-service-worker"; 4 | 5 | // if (process.env.NODE_ENV === "production") { 6 | // register(`${process.env.BASE_URL}service-worker.js`, { 7 | // ready() { 8 | // console.log( 9 | // "App is being served from cache by a service worker.\n" + 10 | // "For more details, visit https://goo.gl/AFskqB" 11 | // ); 12 | // }, 13 | // registered() { 14 | // console.log("Service worker has been registered."); 15 | // }, 16 | // cached() { 17 | // console.log("Content has been cached for offline use."); 18 | // }, 19 | // updatefound() { 20 | // console.log("New content is downloading."); 21 | // }, 22 | // updated() { 23 | // console.log("New content is available; please refresh."); 24 | // }, 25 | // offline() { 26 | // console.log( 27 | // "No internet connection found. App is running in offline mode." 28 | // ); 29 | // }, 30 | // error(error) { 31 | // console.error("Error during service worker registration:", error); 32 | // } 33 | // }); 34 | // } 35 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueRouter from 'vue-router'; 3 | // import Layout from '../views/layout/layout.vue' 4 | // import Home from '../views/home/home.vue' 5 | // import Category from '../views/category/category.vue' 6 | // import About from '../views/about/about.vue' 7 | // import ArticleDetail from '../views/article-detail/article-detail.vue' 8 | // import Wall from '../views/wall/wall.vue'; 9 | // import Archive from '../views/archive/archive.vue' 10 | 11 | Vue.use(VueRouter); 12 | 13 | const routes = [ 14 | { 15 | path: '/', 16 | name: 'layout', 17 | meta: { index: 0 }, 18 | redirect: '/home', 19 | component: () => 20 | import(/* webpackChunkName: "layout" */ '../views/layout/layout.vue'), 21 | children: [ 22 | { 23 | path: 'home', 24 | name: 'home', 25 | meta: { index: 1 }, //meta对象的index用来定义当前路由的层级,由小到大,由低到高 26 | component: () => 27 | import(/* webpackChunkName: "home" */ '../views/home/home.vue') 28 | }, 29 | { 30 | path: 'category', 31 | name: 'category', 32 | meta: { index: 1 }, 33 | component: () => 34 | import( 35 | /* webpackChunkName: "category" */ '../views/category/category.vue' 36 | ) 37 | }, 38 | { 39 | path: 'about', 40 | name: 'about', 41 | meta: { index: 1 }, 42 | component: () => 43 | import(/* webpackChunkName: "about" */ '../views/about/about.vue') 44 | }, 45 | { 46 | path: 'articleDetail', 47 | name: 'articleDetail', 48 | meta: { index: 1 }, 49 | component: () => 50 | import( 51 | /* webpackChunkName: "articleDetail" */ '../views/article-detail/article-detail.vue' 52 | ) 53 | }, 54 | { 55 | path: 'wall', 56 | name: 'wall', 57 | meta: { index: 1 }, 58 | component: () => 59 | import(/* webpackChunkName: "wall" */ '../views/wall/wall.vue') 60 | }, 61 | { 62 | path: 'archive', 63 | name: 'archive', 64 | meta: { index: 1 }, 65 | component: () => 66 | import( 67 | /* webpackChunkName: "archive" */ '../views/archive/archive.vue' 68 | ) 69 | } 70 | ] 71 | } 72 | // { 73 | // path: "/about", 74 | // name: "about", 75 | // // route level code-splitting 76 | // // this generates a separate chunk (about.[hash].js) for this route 77 | // // which is lazy-loaded when the route is visited. 78 | // component: () => 79 | // import(/* webpackChunkName: "about" */ "../views/About.vue") 80 | // } 81 | ]; 82 | 83 | const router = new VueRouter({ 84 | mode: 'history', 85 | routes 86 | }); 87 | 88 | export default router; 89 | -------------------------------------------------------------------------------- /src/service/archive.js: -------------------------------------------------------------------------------- 1 | // import axios from "./index"; 2 | // export const getArchive = params => { 3 | // console.log(params); 4 | // return axios.request({ 5 | // url: "/api/v1/web/archive", 6 | // params, 7 | // method: "get" 8 | // }); 9 | // }; 10 | -------------------------------------------------------------------------------- /src/service/article.js: -------------------------------------------------------------------------------- 1 | import axios from './index'; 2 | // import jwtToken from "jwt-decode"; 3 | export const getArticleList = ({ 4 | current, 5 | pageSize, 6 | keywords, 7 | displayName 8 | }) => { 9 | return axios.request({ 10 | url: '/api/v1/web/article/list', 11 | params: { 12 | current, 13 | pageSize, 14 | keywords, 15 | username: displayName 16 | }, 17 | method: 'get' 18 | }); 19 | }; 20 | export const getSingArticle = ({ article_id, user_id }) => { 21 | return axios.request({ 22 | url: '/api/v1/web/article', 23 | params: { 24 | article_id, 25 | user_id 26 | }, 27 | method: 'get' 28 | }); 29 | }; 30 | export const getCategoryArticleService = data => { 31 | return axios.request({ 32 | url: '/api/v1/web/articleOfCategory', 33 | params: { 34 | category_id: data.category_id, 35 | current: data.current, 36 | pageSize: data.pageSize, 37 | username: data.displayName 38 | }, 39 | method: 'get' 40 | }); 41 | }; 42 | export const clickLikeArticle = data => { 43 | return axios.request({ 44 | url: '/api/v1/web/click/like', 45 | data, 46 | method: 'post' 47 | }); 48 | }; 49 | -------------------------------------------------------------------------------- /src/service/category.js: -------------------------------------------------------------------------------- 1 | import axios from './index'; 2 | export const getCategory = () => { 3 | return axios.request({ 4 | url: '/api/v1/web/category/all', 5 | method: 'get' 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /src/service/comment.js: -------------------------------------------------------------------------------- 1 | import axios from './index'; 2 | export const sendComment = data => { 3 | return axios.request({ 4 | url: '/api/v1/web/comment/add', 5 | data, 6 | method: 'post' 7 | }); 8 | }; 9 | export const sendAnswerComment = data => { 10 | return axios.request({ 11 | url: '/api/v1/web/comment/answer/add', 12 | data, 13 | method: 'post' 14 | }); 15 | }; 16 | -------------------------------------------------------------------------------- /src/service/index.js: -------------------------------------------------------------------------------- 1 | import HttpRequest from '@/lib/axios'; 2 | const axios = new HttpRequest(); 3 | export default axios; 4 | -------------------------------------------------------------------------------- /src/service/regist.js: -------------------------------------------------------------------------------- 1 | import axios from './index'; 2 | export const register = userInfo => { 3 | return axios.request({ 4 | url: '/api/v1/admin/user/register', 5 | data: userInfo, 6 | method: 'post' 7 | }); 8 | }; 9 | export const login = userInfo => { 10 | return axios.request({ 11 | url: '/api/v1/admin/user/login', 12 | data: userInfo, 13 | method: 'post' 14 | }); 15 | }; 16 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Vuex from 'vuex'; 3 | import article from './module/article'; 4 | import category from './module/category'; 5 | import comment from './module/comment'; 6 | import login from './module/login'; 7 | import archive from './module/archive'; 8 | 9 | Vue.use(Vuex); 10 | 11 | export default new Vuex.Store({ 12 | modules: { 13 | article, 14 | category, 15 | comment, 16 | login, 17 | archive 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /src/store/module/archive.js: -------------------------------------------------------------------------------- 1 | // import { getArchive } from "@/service/archive.js"; 2 | 3 | // const state = { 4 | // archive: [] 5 | // }; 6 | // const getters = {}; 7 | // const mutations = { 8 | // GET_ARCHIVE(state, payload) { 9 | // state.archive = payload.archive; 10 | // } 11 | // }; 12 | // const actions = { 13 | // async getArchiveAction({ commit }, params) { 14 | // console.log(111); 15 | // try { 16 | // const { 17 | // code, 18 | // data: { archive } 19 | // } = await getArchive(params); 20 | // if (code === 0) { 21 | // commit("GET_ARCHIVE", { archive }); 22 | // } 23 | // } catch (err) { 24 | // console.log(err); 25 | // } 26 | // } 27 | // }; 28 | // export default { 29 | // state, 30 | // mutations, 31 | // getters, 32 | // actions 33 | // }; 34 | -------------------------------------------------------------------------------- /src/store/module/article.js: -------------------------------------------------------------------------------- 1 | import { getArticleList, getCategoryArticle } from '@/service/article.js'; 2 | 3 | const state = { 4 | articleList: [], 5 | pagination: { 6 | current: 1, 7 | pageSize: 5, 8 | keywords: '' 9 | }, 10 | count: null 11 | }; 12 | const getters = { 13 | articleList: state => { 14 | state.articleList.forEach(item => { 15 | item.color = '#1890ff'; 16 | }); 17 | return state.articleList; 18 | } 19 | }; 20 | const mutations = { 21 | GET_ARTICLE_LIST(state, payload) { 22 | state.articleList = payload.articleList; 23 | state.count = payload.count; 24 | }, 25 | CHANGE_CURRENT(state, payload) { 26 | state.pagination.current = payload; 27 | }, 28 | GET_CATEGORY_ARTICLE(state, payload) { 29 | state.articleList = payload; 30 | }, 31 | CLEAR_ARTICLE_LIST(state) { 32 | state.articleList = []; 33 | } 34 | }; 35 | const actions = { 36 | async getArticleListAction({ commit }, params) { 37 | try { 38 | const { 39 | code, 40 | data: { articleList, count } 41 | } = await getArticleList(params); 42 | if (code === 0) { 43 | commit('GET_ARTICLE_LIST', { articleList, count }); 44 | } 45 | } catch (err) { 46 | // console.log(err); 47 | } 48 | }, 49 | async getCategoryArticleAction({ commit }, category_id) { 50 | try { 51 | const { code, data } = await getCategoryArticle(category_id); 52 | if (code === 0) { 53 | commit('GET_CATEGORY_ARTICLE', data); 54 | } 55 | } catch (err) { 56 | // console.log(err); 57 | } 58 | }, 59 | clearArticleListAction({ commit }) { 60 | commit('CLEAR_ARTICLE_LIST'); 61 | } 62 | }; 63 | export default { 64 | state, 65 | mutations, 66 | getters, 67 | actions 68 | }; 69 | -------------------------------------------------------------------------------- /src/store/module/category.js: -------------------------------------------------------------------------------- 1 | import { getCategory } from '@/service/category.js'; 2 | const state = { 3 | category: [] 4 | }; 5 | const getters = {}; 6 | const mutations = { 7 | GET_CATEGORY(state, payload) { 8 | state.category = payload; 9 | } 10 | }; 11 | const actions = { 12 | async getCategoryAction({ commit }) { 13 | try { 14 | const { code, data } = await getCategory(); 15 | if (code === 0) { 16 | commit('GET_CATEGORY', data); 17 | } 18 | } catch (err) { 19 | // console.log(err); 20 | } 21 | } 22 | }; 23 | export default { 24 | state, 25 | mutations, 26 | getters, 27 | actions 28 | }; 29 | -------------------------------------------------------------------------------- /src/store/module/comment.js: -------------------------------------------------------------------------------- 1 | import { sendComment } from '@/service/comment.js'; 2 | const state = { 3 | comments: [] 4 | }; 5 | const getters = {}; 6 | const mutations = { 7 | GET_CATEGORY(state, payload) { 8 | state.comments = payload; 9 | } 10 | }; 11 | const actions = { 12 | async sendCommentAction({ commit }, params) { 13 | try { 14 | const res = await sendComment(params); 15 | // commit(); 16 | } catch (err) { 17 | // console.log(err); 18 | } 19 | } 20 | }; 21 | export default { 22 | state, 23 | mutations, 24 | getters, 25 | actions 26 | }; 27 | -------------------------------------------------------------------------------- /src/store/module/login.js: -------------------------------------------------------------------------------- 1 | const state = { 2 | isLogin: sessionStorage.getItem('islogin'), 3 | displayName: sessionStorage.getItem('displayName'), 4 | token: sessionStorage.getItem('token') 5 | }; 6 | const getters = {}; 7 | const mutations = { 8 | LOGIN_SUCCESS(state, payload) { 9 | const { code, displayName, token } = payload; 10 | if (code === 0) { 11 | sessionStorage.setItem('token', token); 12 | sessionStorage.setItem('displayName', displayName); 13 | state.displayName = displayName; 14 | state.isLogin = true; 15 | sessionStorage.setItem('islogin', state.isLogin); 16 | } 17 | }, 18 | LOG_OUT(state, payload) { 19 | state.isLogin = false; 20 | state.displayName = ''; 21 | } 22 | }; 23 | const actions = { 24 | logout({ commit }) { 25 | sessionStorage.removeItem('token'); 26 | sessionStorage.removeItem('displayName'); 27 | sessionStorage.removeItem('preUrl'); 28 | sessionStorage.removeItem('islogin'); 29 | commit('LOG_OUT'); 30 | } 31 | }; 32 | export default { 33 | state, 34 | mutations, 35 | getters, 36 | actions 37 | }; 38 | -------------------------------------------------------------------------------- /src/views/about/about.vue: -------------------------------------------------------------------------------- 1 | 70 | 80 | 146 | -------------------------------------------------------------------------------- /src/views/archive/archive.vue: -------------------------------------------------------------------------------- 1 | 28 | 69 | w 70 | 106 | -------------------------------------------------------------------------------- /src/views/article-detail/article-detail.vue: -------------------------------------------------------------------------------- 1 | 51 | 211 | 426 | -------------------------------------------------------------------------------- /src/views/article-detail/single-article.vue: -------------------------------------------------------------------------------- 1 | 9 | 42 | 77 | -------------------------------------------------------------------------------- /src/views/category/category.vue: -------------------------------------------------------------------------------- 1 | 48 | 112 | 203 | -------------------------------------------------------------------------------- /src/views/home/home.vue: -------------------------------------------------------------------------------- 1 | 19 | 58 | 66 | -------------------------------------------------------------------------------- /src/views/layout/layout.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 22 | 72 | -------------------------------------------------------------------------------- /src/views/wall/wall.vue: -------------------------------------------------------------------------------- 1 | 6 | 15 | 16 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | // module.exports = { 2 | // // 以下是pwa配置 3 | // pwa: { 4 | // iconPaths: { 5 | // favicon32: 'github.ico', 6 | // favicon16: 'github.ico', 7 | // appleTouchIcon: 'github.ico', 8 | // maskIcon: 'github.ico', 9 | // msTileImage: 'github.ico' 10 | // } 11 | // }, 12 | // configureWebpack: config => { 13 | // config.externals = { 14 | // vue: 'Vue', 15 | // 'vue-router': 'VueRouter', 16 | // "highlight.js": "hljs", 17 | // lodash: { 18 | // commonjs: 'lodash', 19 | // umd: 'lodash', 20 | // root: '_' 21 | // } 22 | // }; 23 | // } 24 | // }; 25 | // const BundleAnalyzer = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; 26 | 27 | module.exports = { 28 | // 以下是pwa配置 29 | pwa: { 30 | iconPaths: { 31 | favicon32: 'github.ico', 32 | favicon16: 'github.ico', 33 | appleTouchIcon: 'github.ico', 34 | maskIcon: 'github.ico', 35 | msTileImage: 'github.ico' 36 | } 37 | }, 38 | configureWebpack: { 39 | externals: { 40 | 'highlight.js': 'hljs' 41 | } 42 | // plugins: [new BundleAnalyzer()] 43 | }, 44 | chainWebpack: config => { 45 | config.optimization.splitChunks({ 46 | cacheGroups: { 47 | vendors: { 48 | name: 'chunk-vendors', 49 | test: /[\\/]node_modules[\\/]/, 50 | priority: -10, 51 | chunks: 'initial' 52 | }, 53 | common: { 54 | name: 'chunk-common', 55 | minChunks: 2, 56 | priority: -20, 57 | chunks: 'initial', 58 | reuseExistingChunk: true 59 | }, 60 | elementUi: { 61 | name: 'elementUi', 62 | test: /[\\/]node_modules[\\/](element-ui)[\\/]/, 63 | chunks: 'all' 64 | }, 65 | moment: { 66 | name: 'moment', 67 | test: /[\\/]node_modules[\\/](moment)[\\/]/, 68 | chunks: 'all' 69 | }, 70 | coreJs: { 71 | name: 'coreJs', 72 | test: /[\\/]node_modules[\\/](core-js)[\\/]/, 73 | chunks: 'all' 74 | }, 75 | marked: { 76 | name: 'marked', 77 | test: /[\\/]node_modules[\\/](marked)[\\/]/, 78 | chunks: 'all' 79 | }, 80 | axios: { 81 | name: 'axios', 82 | test: /[\\/]node_modules[\\/](axios)[\\/]/, 83 | chunks: 'all' 84 | } 85 | } 86 | }); 87 | } 88 | }; 89 | --------------------------------------------------------------------------------