├── .gitignore ├── .prettierrc ├── README.md ├── babel.config.js ├── package.json ├── public ├── _redirects ├── favicon.ico └── index.html ├── src ├── App.vue ├── assets │ ├── images │ │ ├── 404.svg │ │ ├── av.png │ │ ├── github.svg │ │ ├── sspai.svg │ │ └── zeit.svg │ ├── logos │ │ ├── github.png │ │ ├── jike.png │ │ ├── medium.png │ │ ├── rss.png │ │ ├── sspai.png │ │ ├── steam.png │ │ ├── telegram.png │ │ ├── twitter.png │ │ ├── weibo.png │ │ └── zhihu.png │ └── styles │ │ ├── base.css │ │ └── nprogress.css ├── components │ ├── GitHubCard.vue │ └── StatCard.vue ├── main.js └── views │ ├── Home.vue │ ├── NotFound.vue │ ├── Projects.vue │ └── Social.vue └── yarn.lock /.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 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "semi": false, 4 | "trailingComma": "all", 5 | "tabWidth": 2, 6 | "printWidth": 120 7 | } 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Hosted on Vercel](https://badgen.net/badge/Vercel/$%20now%20spencerwooo%2Fportfolio/001122?icon=zeit&labelColor=black)](https://vercel.com/spencerwoo/home) 2 | [![Live at https://spencerwoo.com](https://badgen.net/https/now.swoo.workers.dev/dpl_FmTc9SGnGmSSJSvRqNFwNVw7i6Bb?labelColor=black)](https://spencerwoo.com) 3 | 4 | # Portfolio 5 | 6 | > 🍌 My personal home page, built and designed from scratch. 7 | 8 | Current master branch holds `v2.0` of my portfolio. For `v1.0`, please refer to branch [tree/v1.0](https://github.com/spencerwooo/portfolio/tree/v1.0). **Please note that this is my personal portfolio, so I won't be accepting any feature requests.** Feel free to implement features on your own. 💜 9 | 10 | 11 | 12 | ## One-click deployment 13 | 14 | Deploy your own instance of my portfolio to Vercel: 15 | 16 | [![Deploy to Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=spencerwooo%2Fportfolio) 17 | 18 | ## Copyrights 19 | 20 | Please add proper acknowledgements if you were to deploy this for your own portfolio. 21 | 22 | 如果你希望用我的模板部署自己的 Portfolio,还请加上设计来源。比如: 23 | 24 | [![copyright](https://img.shields.io/badge/Designed%20by-github.com%2Fspencerwooo-black?logo=github&style=for-the-badge&labelColor=24292e)](https://github.com/spencerwooo/portfolio) 25 | 26 | ```html 27 | copyright 28 | ``` 29 | 30 | ## Project setup 31 | 32 | ``` 33 | yarn install 34 | ``` 35 | 36 | ### Compiles and hot-reloads for development 37 | 38 | ``` 39 | yarn run serve 40 | ``` 41 | 42 | ### Compiles and minifies for production 43 | 44 | ``` 45 | yarn run build 46 | ``` 47 | 48 | ### Run your tests 49 | 50 | ``` 51 | yarn run test 52 | ``` 53 | 54 | ### Lints and fixes files 55 | 56 | ``` 57 | yarn run lint 58 | ``` 59 | 60 | --- 61 | 62 | **🍌 Portfolio** ©Spencer Woo. Released under the [MIT License](./LICENSE). 63 | 64 | Authored and maintained by Spencer Woo. 65 | 66 | [@Portfolio](https://spencerwoo.com) · [@GitHub](https://github.com/spencerwooo) · [@BIT](http://www.bit.edu.cn/) 67 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "portfolio", 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 | "lint-fix": "npx eslint --fix --ext .js --ext .jsx --ext .vue src/" 10 | }, 11 | "dependencies": { 12 | "axios": "^0.21.1", 13 | "core-js": "^2.6.5", 14 | "nprogress": "^0.2.0", 15 | "vue": "^2.6.10", 16 | "vue-content-loader": "^0.2.3", 17 | "vue-navigation-bar": "^2.0.0", 18 | "vue-router": "^3.1.3" 19 | }, 20 | "devDependencies": { 21 | "@vue/cli-plugin-babel": "^3.9.0", 22 | "@vue/cli-plugin-eslint": "^3.9.0", 23 | "@vue/cli-service": "^3.9.0", 24 | "babel-eslint": "^10.0.1", 25 | "eslint": "^5.16.0", 26 | "eslint-plugin-vue": "^5.0.0", 27 | "vue-template-compiler": "^2.6.10" 28 | }, 29 | "eslintConfig": { 30 | "root": true, 31 | "env": { 32 | "node": true 33 | }, 34 | "extends": [ 35 | "plugin:vue/essential", 36 | "eslint:recommended" 37 | ], 38 | "rules": {}, 39 | "parserOptions": { 40 | "parser": "babel-eslint" 41 | } 42 | }, 43 | "postcss": { 44 | "plugins": { 45 | "autoprefixer": {} 46 | } 47 | }, 48 | "browserslist": [ 49 | "> 1%", 50 | "last 2 versions" 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /public/_redirects: -------------------------------------------------------------------------------- 1 | # Make vue router compatible with Netlify 2 | /* /index.html 200 3 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Spencer Woo 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 71 | 72 | 149 | -------------------------------------------------------------------------------- /src/assets/images/404.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 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 | -------------------------------------------------------------------------------- /src/assets/images/av.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/images/av.png -------------------------------------------------------------------------------- /src/assets/images/github.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/assets/images/sspai.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/assets/images/zeit.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/assets/logos/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/github.png -------------------------------------------------------------------------------- /src/assets/logos/jike.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/jike.png -------------------------------------------------------------------------------- /src/assets/logos/medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/medium.png -------------------------------------------------------------------------------- /src/assets/logos/rss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/rss.png -------------------------------------------------------------------------------- /src/assets/logos/sspai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/sspai.png -------------------------------------------------------------------------------- /src/assets/logos/steam.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/steam.png -------------------------------------------------------------------------------- /src/assets/logos/telegram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/telegram.png -------------------------------------------------------------------------------- /src/assets/logos/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/twitter.png -------------------------------------------------------------------------------- /src/assets/logos/weibo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/weibo.png -------------------------------------------------------------------------------- /src/assets/logos/zhihu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spencerwooo/portfolio/445f7b22fc622d6e787ceb24332ee5d3f417ceb7/src/assets/logos/zhihu.png -------------------------------------------------------------------------------- /src/assets/styles/base.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;1,700&family=Open+Sans:wght@700&display=swap'); 2 | 3 | :root { 4 | --title-font-family: open sans, -apple-system, BlinkMacSystemFont, segoe ui, helvetica, arial, pingfang sc, 5 | source han sans sc, noto sans cjk sc, sarasa gothic sc, microsoft yahei, sans-serif, apple color emoji, 6 | segoe ui emoji; 7 | --main-font-family: lato, -apple-system, BlinkMacSystemFont, segoe ui, helvetica, arial, pingfang sc, 8 | source han sans sc, noto sans cjk sc, sarasa gothic sc, microsoft yahei, sans-serif, apple color emoji, 9 | segoe ui emoji; 10 | --monospace-font-family: sfmono-regular, consolas, liberation mono, menlo, monospace; 11 | 12 | --background-color: #fafafa; 13 | --text-color: #000000; 14 | --footer-color: #666666; 15 | --link-color: #0070f3; 16 | --code-color: #bd10e0; 17 | } 18 | 19 | html, 20 | body { 21 | margin: 0; 22 | padding: 0; 23 | background-color: var(--background-color); 24 | font-family: var(--main-font-family); 25 | -webkit-font-smoothing: antialiased; 26 | -moz-osx-font-smoothing: grayscale; 27 | color: var(--text-color); 28 | } 29 | 30 | h1 { 31 | font-size: 28px; 32 | } 33 | 34 | h1, 35 | h2, 36 | h3 { 37 | font-family: var(--title-font-family); 38 | font-weight: 700; 39 | } 40 | 41 | h2 { 42 | font-size: 20px; 43 | padding: 16px 0 4px 0; 44 | } 45 | 46 | h1, 47 | h2, 48 | h3, 49 | h4, 50 | p, 51 | span, 52 | li, 53 | ul { 54 | color: var(--text-color); 55 | } 56 | 57 | a { 58 | text-decoration: none; 59 | color: var(--link-color); 60 | } 61 | 62 | a:hover { 63 | border-bottom: none; 64 | } 65 | 66 | ul { 67 | padding-left: 15px; 68 | line-height: 30px; 69 | margin: 0; 70 | } 71 | 72 | p { 73 | line-height: 30px; 74 | } 75 | 76 | code { 77 | padding: 0.2em 0.4em; 78 | margin: 0; 79 | font-size: 85%; 80 | border-radius: 6px; 81 | color: var(--code-color); 82 | } 83 | 84 | code::before, 85 | code::after { 86 | content: '`'; 87 | } 88 | 89 | pre { 90 | padding: 16px; 91 | overflow: auto; 92 | font-size: 85%; 93 | line-height: 1.45; 94 | border-radius: 6px; 95 | word-break: normal; 96 | word-wrap: normal; 97 | border: 1px solid #eaeaea; 98 | margin: 24px 0; 99 | white-space: pre; 100 | -webkit-overflow-scrolling: touch; 101 | } 102 | 103 | code, 104 | pre { 105 | font-family: var(--monospace-font-family); 106 | } 107 | 108 | b { 109 | font-weight: 700; 110 | } 111 | -------------------------------------------------------------------------------- /src/assets/styles/nprogress.css: -------------------------------------------------------------------------------- 1 | /* Make clicks pass-through */ 2 | #nprogress { 3 | pointer-events: none; 4 | } 5 | 6 | #nprogress .bar { 7 | background: #000000; 8 | 9 | position: fixed; 10 | z-index: 1031; 11 | top: 0; 12 | left: 0; 13 | 14 | width: 100%; 15 | height: 2px; 16 | } 17 | 18 | /* Fancy blur effect */ 19 | #nprogress .peg { 20 | display: block; 21 | position: absolute; 22 | right: 0px; 23 | width: 100px; 24 | height: 100%; 25 | box-shadow: 0 0 10px #000000, 0 0 5px #000000; 26 | opacity: 1; 27 | 28 | -webkit-transform: rotate(3deg) translate(0px, -4px); 29 | -ms-transform: rotate(3deg) translate(0px, -4px); 30 | transform: rotate(3deg) translate(0px, -4px); 31 | } 32 | 33 | .nprogress-custom-parent { 34 | overflow: hidden; 35 | position: relative; 36 | } 37 | 38 | .nprogress-custom-parent #nprogress .bar { 39 | position: absolute; 40 | } 41 | -------------------------------------------------------------------------------- /src/components/GitHubCard.vue: -------------------------------------------------------------------------------- 1 | 53 | 54 | 73 | 74 | 146 | -------------------------------------------------------------------------------- /src/components/StatCard.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 37 | 38 | 110 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import VueRouter from 'vue-router' 4 | 5 | import Home from './views/Home.vue' 6 | import Projects from './views/Projects.vue' 7 | import Social from './views/Social.vue' 8 | import NotFound from './views/NotFound.vue' 9 | 10 | import './assets/styles/base.css' 11 | 12 | Vue.config.productionTip = false 13 | Vue.use(VueRouter) 14 | 15 | import VueNavigationBar from 'vue-navigation-bar' 16 | Vue.component('vue-navigation-bar', VueNavigationBar) 17 | 18 | import axios from 'axios' 19 | Vue.prototype.axios = axios 20 | 21 | // NProgress 22 | import NProgress from 'nprogress' 23 | import './assets/styles/nprogress.css' 24 | NProgress.configure({ easing: 'ease', speed: 500, showSpinner: false }) 25 | 26 | const router = new VueRouter({ 27 | mode: 'history', 28 | base: process.env.BASE_URL, 29 | routes: [ 30 | { path: '/', component: Home }, 31 | { path: '/projects', component: Projects }, 32 | { path: '/social', component: Social }, 33 | 34 | // Not found 35 | { path: '/*', component: NotFound } 36 | ] 37 | }) 38 | 39 | router.beforeEach((to, from, next) => { 40 | if (from.name !== null) { 41 | NProgress.start() 42 | } 43 | next() 44 | }) 45 | // eslint-disable-next-line no-unused-vars 46 | router.afterEach((to, from) => { 47 | NProgress.done() 48 | }) 49 | 50 | new Vue({ 51 | router, 52 | render: h => h(App) 53 | }).$mount('#app') 54 | -------------------------------------------------------------------------------- /src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 87 | 88 | 141 | -------------------------------------------------------------------------------- /src/views/NotFound.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 27 | -------------------------------------------------------------------------------- /src/views/Projects.vue: -------------------------------------------------------------------------------- 1 | 60 | 61 | 122 | 123 | 128 | -------------------------------------------------------------------------------- /src/views/Social.vue: -------------------------------------------------------------------------------- 1 | 105 | 106 | 175 | 176 | 225 | --------------------------------------------------------------------------------