├── .gitignore ├── README.md ├── chapter-10 ├── example-1 │ └── index.html └── example-2 │ └── index.html ├── chapter-11 └── example-1 │ └── index.html ├── chapter-12 └── example-1 │ ├── .gitignore │ ├── babel.config.js │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── favicon.ico │ └── index.html │ └── src │ ├── App.vue │ ├── assets │ └── logo.png │ ├── components │ ├── ErrorComponent.vue │ ├── HelloWorld.vue │ └── LoadingComponent.vue │ └── main.js ├── chapter-13 ├── example-1 │ └── index.html └── example-2 │ └── index.html ├── chapter-14 └── example-1 │ └── index.html ├── chapter-2 ├── example-1 │ └── index.html ├── example-2 │ └── index.html ├── example-3 │ └── index.html ├── example-4 │ └── index.html └── example-5 │ └── index.html ├── chapter-3 ├── example-1 │ └── index.html └── example-2 │ └── index.html ├── chapter-4 ├── example-1 │ └── index.html ├── example-2 │ └── index.html ├── example-3 │ └── index.html ├── example-4 │ └── index.html └── example-5 │ └── index.html ├── chapter-5 ├── example-1 │ └── index.html ├── example-2 │ └── index.html ├── example-3 │ └── index.html └── example-4 │ └── index.html ├── chapter-6 ├── example-1 │ ├── .gitignore │ ├── babel.config.js │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ └── index.html │ └── src │ │ ├── App.vue │ │ ├── assets │ │ └── logo.png │ │ ├── components │ │ └── HelloWorld.vue │ │ └── main.js ├── example-2 │ └── index.html └── example-3 │ ├── .gitignore │ ├── babel.config.js │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── favicon.ico │ └── index.html │ └── src │ ├── App.vue │ ├── assets │ └── logo.png │ ├── components │ └── HelloWorld.vue │ └── main.js ├── chapter-7 └── example-1 │ └── index.html ├── chapter-8 ├── example-1 │ └── index.html ├── example-2 │ └── index.html ├── example-3 │ └── index.html └── example-4 │ ├── .gitignore │ ├── babel.config.js │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── favicon.ico │ └── index.html │ └── src │ ├── App.vue │ ├── assets │ └── logo.png │ ├── components │ └── ArticleCard.vue │ ├── main.js │ └── withLoader.js ├── chapter-9 └── example-1 │ └── index.html ├── shared ├── avatars │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ └── 4.jpg ├── axios-0.18.0.js ├── button.css ├── carousel.css ├── cat.jpg ├── cat2.jpg ├── cat3.jpg ├── expandable.css ├── image.svg ├── image_card.css ├── list.css ├── main.css ├── modal.css ├── normalize-5.0.0.min.css ├── switch.css ├── table.css ├── tweet.css ├── vue-2.6.10.js └── vue-2.6.10.min.js └── template ├── app.js └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vue.js Component Patterns Book Examples 2 | 3 | This archive contains all examples from the book [Vue.js Component Patterns](https://fdietz.de/pages/vue-component-patterns-course/). 4 | -------------------------------------------------------------------------------- /chapter-10/example-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 |
17 | 18 | 23 | 24 | 29 | 30 | 35 | 36 | 41 | 42 | 43 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /chapter-10/example-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 29 | 30 | 35 | 36 | 41 | 42 | 47 | 48 | 49 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /chapter-11/example-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 43 | 44 | 45 | 46 |
47 | 51 | Click me 52 |
53 | 54 | 59 | 60 | 61 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /chapter-12/example-1/.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 | -------------------------------------------------------------------------------- /chapter-12/example-1/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } -------------------------------------------------------------------------------- /chapter-12/example-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-1", 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 | "vue": "^2.5.16" 12 | }, 13 | "devDependencies": { 14 | "@vue/cli-plugin-babel": "^3.0.0-rc.7", 15 | "@vue/cli-plugin-eslint": "^3.0.0-rc.7", 16 | "@vue/cli-service": "^3.0.0-rc.7", 17 | "vue-template-compiler": "^2.5.16" 18 | }, 19 | "eslintConfig": { 20 | "root": true, 21 | "env": { 22 | "node": true 23 | }, 24 | "extends": [ 25 | "plugin:vue/essential", 26 | "eslint:recommended" 27 | ], 28 | "rules": {}, 29 | "parserOptions": { 30 | "parser": "babel-eslint" 31 | } 32 | }, 33 | "postcss": { 34 | "plugins": { 35 | "autoprefixer": {} 36 | } 37 | }, 38 | "browserslist": [ 39 | "> 1%", 40 | "last 2 versions", 41 | "not ie <= 8" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /chapter-12/example-1/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdietz/vue_components_book_examples/a80ae43cb02a1e56731d6197f1a0d1e8a11576fc/chapter-12/example-1/public/favicon.ico -------------------------------------------------------------------------------- /chapter-12/example-1/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | example-1 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /chapter-12/example-1/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 38 | 39 | 49 | -------------------------------------------------------------------------------- /chapter-12/example-1/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdietz/vue_components_book_examples/a80ae43cb02a1e56731d6197f1a0d1e8a11576fc/chapter-12/example-1/src/assets/logo.png -------------------------------------------------------------------------------- /chapter-12/example-1/src/components/ErrorComponent.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /chapter-12/example-1/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | 16 | 17 | 33 | -------------------------------------------------------------------------------- /chapter-12/example-1/src/components/LoadingComponent.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /chapter-12/example-1/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | Vue.config.productionTip = false 5 | 6 | new Vue({ 7 | render: h => h(App) 8 | }).$mount('#app') 9 | -------------------------------------------------------------------------------- /chapter-13/example-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 43 | 44 | 45 | 46 | 47 |
48 | 49 | 50 | Content of the first tab 51 | 52 | 53 | Content of the second tab 54 | 55 | 56 | Content of the third tab 57 | 58 | 59 |
60 | 61 | 76 | 77 | 82 | 83 | 84 | 139 | 140 | -------------------------------------------------------------------------------- /chapter-13/example-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | Content of first item 19 | 20 | 21 | Content of second item 22 | 23 | 24 | Content of third item 25 | 26 | 27 |
28 | 29 | 45 | 46 | 51 | 52 | 53 | 112 | 113 | -------------------------------------------------------------------------------- /chapter-14/example-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 20 | 21 | 22 | 23 |
24 | 25 | 36 | 37 |
38 | 39 | 40 | 41 | 71 | 72 | -------------------------------------------------------------------------------- /chapter-2/example-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | cat 18 |
19 |

Striped Tiger Cat

20 |
Image by @lemepe
21 |
22 |
23 |
24 | 25 | 26 | 29 | 30 | -------------------------------------------------------------------------------- /chapter-2/example-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 |
19 | 20 | 29 | 30 | 31 | 38 | 39 | -------------------------------------------------------------------------------- /chapter-2/example-3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 |
19 | 20 | 29 | 30 | 31 | 43 | 44 | -------------------------------------------------------------------------------- /chapter-2/example-4/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 |
19 | 20 | 35 | 36 | 37 | 54 | 55 | -------------------------------------------------------------------------------- /chapter-2/example-5/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 |

Total Count: {{totalCount}}

19 |
20 | 21 | 36 | 37 | 38 | 72 | 73 | -------------------------------------------------------------------------------- /chapter-3/example-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |

Modal Header

18 |

This is a paragraph inside the modal.

19 |
20 | 21 |
22 | 23 | 35 | 36 | 37 | 49 | 50 | -------------------------------------------------------------------------------- /chapter-3/example-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 20 | 23 | 24 | 25 |
26 | 27 | 44 | 45 | 46 | 58 | 59 | -------------------------------------------------------------------------------- /chapter-4/example-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 | 19 | {{item.name}} 20 |
21 |
22 |
23 | 24 | 25 | 37 | 38 | -------------------------------------------------------------------------------- /chapter-4/example-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 |
18 | 19 |
{{item.name}}
20 |
21 |
22 |
23 | 24 | 31 | 32 | 33 | 55 | 56 | -------------------------------------------------------------------------------- /chapter-4/example-3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 21 | 22 |
23 | 24 | 31 | 32 | 33 | 55 | 56 | -------------------------------------------------------------------------------- /chapter-4/example-4/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 22 | 23 |
24 | 25 | 32 | 33 | 34 | 61 | 62 | -------------------------------------------------------------------------------- /chapter-4/example-5/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 22 | 23 |
24 | 25 | 32 | 33 | 34 | 61 | 62 | -------------------------------------------------------------------------------- /chapter-5/example-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 26 | 27 | 28 | 29 |
30 |
31 |

Button Toggle

32 | 33 | 37 | 38 |
39 | 40 |
41 |

Switch Toggle

42 | 43 | 47 | 48 |
49 |
50 | 51 | 56 | 57 | 63 | 64 | 65 | 100 | 101 | -------------------------------------------------------------------------------- /chapter-5/example-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 26 | 27 | 28 | 29 |
30 |
31 |

Button Toggle

32 | 33 | 37 | 38 |
39 | 40 |
41 |

Switch Toggle

42 | 43 | 47 | 48 |
49 |
50 | 51 | 57 | 58 | 59 | 99 | 100 | -------------------------------------------------------------------------------- /chapter-5/example-3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 21 | 22 | 23 | 24 |
25 | 26 | 42 | 43 |
44 | 45 | 46 | 76 | 77 | -------------------------------------------------------------------------------- /chapter-5/example-4/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 21 | 22 | 23 | 24 |
25 | 26 | 42 | 43 |
44 | 45 | 46 | 81 | 82 | -------------------------------------------------------------------------------- /chapter-6/example-1/.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 | -------------------------------------------------------------------------------- /chapter-6/example-1/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } -------------------------------------------------------------------------------- /chapter-6/example-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "render-function", 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 | "vue": "^2.5.16" 12 | }, 13 | "devDependencies": { 14 | "@vue/cli-plugin-babel": "^3.0.0-rc.5", 15 | "@vue/cli-plugin-eslint": "^3.0.0-rc.5", 16 | "@vue/cli-service": "^3.0.0-rc.5", 17 | "vue-template-compiler": "^2.5.16" 18 | }, 19 | "eslintConfig": { 20 | "root": true, 21 | "env": { 22 | "node": true 23 | }, 24 | "extends": [ 25 | "plugin:vue/essential", 26 | "eslint:recommended" 27 | ], 28 | "rules": {}, 29 | "parserOptions": { 30 | "parser": "babel-eslint" 31 | } 32 | }, 33 | "postcss": { 34 | "plugins": { 35 | "autoprefixer": {} 36 | } 37 | }, 38 | "browserslist": [ 39 | "> 1%", 40 | "last 2 versions", 41 | "not ie <= 8" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /chapter-6/example-1/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdietz/vue_components_book_examples/a80ae43cb02a1e56731d6197f1a0d1e8a11576fc/chapter-6/example-1/public/favicon.ico -------------------------------------------------------------------------------- /chapter-6/example-1/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | render-function 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /chapter-6/example-1/src/App.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 25 | 26 | 36 | -------------------------------------------------------------------------------- /chapter-6/example-1/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdietz/vue_components_book_examples/a80ae43cb02a1e56731d6197f1a0d1e8a11576fc/chapter-6/example-1/src/assets/logo.png -------------------------------------------------------------------------------- /chapter-6/example-1/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /chapter-6/example-1/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | Vue.config.productionTip = false 5 | 6 | new Vue({ 7 | render: h => h(App) 8 | }).$mount('#app') 9 | -------------------------------------------------------------------------------- /chapter-6/example-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 21 | 22 | 23 | 24 |
25 | 26 |

I was clicked: {{clickCount}}

27 |
28 |
29 | 30 | 31 | 56 | 57 | -------------------------------------------------------------------------------- /chapter-6/example-3/.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 | -------------------------------------------------------------------------------- /chapter-6/example-3/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } -------------------------------------------------------------------------------- /chapter-6/example-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-3", 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 | "vue": "^2.5.16" 12 | }, 13 | "devDependencies": { 14 | "@vue/cli-plugin-babel": "^3.0.0-rc.5", 15 | "@vue/cli-plugin-eslint": "^3.0.0-rc.5", 16 | "@vue/cli-service": "^3.0.0-rc.5", 17 | "vue-template-compiler": "^2.5.16" 18 | }, 19 | "eslintConfig": { 20 | "root": true, 21 | "env": { 22 | "node": true 23 | }, 24 | "extends": [ 25 | "plugin:vue/essential", 26 | "eslint:recommended" 27 | ], 28 | "rules": {}, 29 | "parserOptions": { 30 | "parser": "babel-eslint" 31 | } 32 | }, 33 | "postcss": { 34 | "plugins": { 35 | "autoprefixer": {} 36 | } 37 | }, 38 | "browserslist": [ 39 | "> 1%", 40 | "last 2 versions", 41 | "not ie <= 8" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /chapter-6/example-3/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdietz/vue_components_book_examples/a80ae43cb02a1e56731d6197f1a0d1e8a11576fc/chapter-6/example-3/public/favicon.ico -------------------------------------------------------------------------------- /chapter-6/example-3/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | example-3 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /chapter-6/example-3/src/App.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 25 | 26 | 36 | -------------------------------------------------------------------------------- /chapter-6/example-3/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdietz/vue_components_book_examples/a80ae43cb02a1e56731d6197f1a0d1e8a11576fc/chapter-6/example-3/src/assets/logo.png -------------------------------------------------------------------------------- /chapter-6/example-3/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /chapter-6/example-3/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | Vue.config.productionTip = false 5 | 6 | new Vue({ 7 | render: h => h(App) 8 | }).$mount('#app') 9 | -------------------------------------------------------------------------------- /chapter-7/example-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 40 | 41 | 42 | 43 |
44 | 56 | 57 | 60 | 61 |
62 | 63 | 64 | 90 | 91 | -------------------------------------------------------------------------------- /chapter-8/example-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
31 | 32 | 43 | 44 | 45 | 85 | 86 | -------------------------------------------------------------------------------- /chapter-8/example-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 | 40 | 41 | 42 | 43 | 44 | 76 | 77 | -------------------------------------------------------------------------------- /chapter-8/example-3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 27 | 28 | 29 | 30 |
31 | 32 | 33 |
34 | 35 | 44 | 45 | 55 | 56 | 57 | 58 | 59 | 102 | 103 | -------------------------------------------------------------------------------- /chapter-8/example-4/.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 | -------------------------------------------------------------------------------- /chapter-8/example-4/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } -------------------------------------------------------------------------------- /chapter-8/example-4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-4", 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 | "axios": "^0.18.0", 12 | "vue": "^2.5.16" 13 | }, 14 | "devDependencies": { 15 | "@vue/cli-plugin-babel": "^3.0.0-rc.5", 16 | "@vue/cli-plugin-eslint": "^3.0.0-rc.5", 17 | "@vue/cli-service": "^3.0.0-rc.5", 18 | "vue-template-compiler": "^2.5.16" 19 | }, 20 | "eslintConfig": { 21 | "root": true, 22 | "env": { 23 | "node": true 24 | }, 25 | "extends": [ 26 | "plugin:vue/essential", 27 | "eslint:recommended" 28 | ], 29 | "rules": {}, 30 | "parserOptions": { 31 | "parser": "babel-eslint" 32 | } 33 | }, 34 | "postcss": { 35 | "plugins": { 36 | "autoprefixer": {} 37 | } 38 | }, 39 | "browserslist": [ 40 | "> 1%", 41 | "last 2 versions", 42 | "not ie <= 8" 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /chapter-8/example-4/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdietz/vue_components_book_examples/a80ae43cb02a1e56731d6197f1a0d1e8a11576fc/chapter-8/example-4/public/favicon.ico -------------------------------------------------------------------------------- /chapter-8/example-4/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | example-4 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /chapter-8/example-4/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | 20 | 30 | -------------------------------------------------------------------------------- /chapter-8/example-4/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdietz/vue_components_book_examples/a80ae43cb02a1e56731d6197f1a0d1e8a11576fc/chapter-8/example-4/src/assets/logo.png -------------------------------------------------------------------------------- /chapter-8/example-4/src/components/ArticleCard.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 20 | 21 | 28 | -------------------------------------------------------------------------------- /chapter-8/example-4/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | 4 | Vue.config.productionTip = false 5 | 6 | new Vue({ 7 | render: h => h(App) 8 | }).$mount('#app') 9 | -------------------------------------------------------------------------------- /chapter-8/example-4/src/withLoader.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import axios from "axios"; 3 | 4 | const withLoader = component => { 5 | return Vue.component("with-loader", { 6 | render(createElement) { 7 | return createElement(component, { 8 | props: { 9 | loading: this.loading, 10 | title: this.title, 11 | body: this.body 12 | } 13 | }); 14 | }, 15 | props: ["id"], 16 | data() { 17 | return { 18 | loading: false, 19 | title: "", 20 | body: "", 21 | } 22 | }, 23 | methods: { 24 | load(id) { 25 | this.loading = true; 26 | return axios.get(`https://jsonplaceholder.typicode.com/posts/${id}`) 27 | .then(response => { 28 | this.title = response.data.title; 29 | this.body = response.data.body; 30 | this.loading = false; 31 | }); 32 | } 33 | }, 34 | created() { 35 | this.load(this.id); 36 | } 37 | }); 38 | }; 39 | 40 | export default withLoader; -------------------------------------------------------------------------------- /chapter-9/example-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 |
18 | 19 | 22 | 23 | 30 | 31 | 32 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /shared/avatars/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdietz/vue_components_book_examples/a80ae43cb02a1e56731d6197f1a0d1e8a11576fc/shared/avatars/1.jpg -------------------------------------------------------------------------------- /shared/avatars/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdietz/vue_components_book_examples/a80ae43cb02a1e56731d6197f1a0d1e8a11576fc/shared/avatars/2.jpg -------------------------------------------------------------------------------- /shared/avatars/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdietz/vue_components_book_examples/a80ae43cb02a1e56731d6197f1a0d1e8a11576fc/shared/avatars/3.jpg -------------------------------------------------------------------------------- /shared/avatars/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdietz/vue_components_book_examples/a80ae43cb02a1e56731d6197f1a0d1e8a11576fc/shared/avatars/4.jpg -------------------------------------------------------------------------------- /shared/axios-0.18.0.js: -------------------------------------------------------------------------------- 1 | /* axios v0.18.0 | (c) 2018 by Matt Zabriskie */ 2 | (function webpackUniversalModuleDefinition(root, factory) { 3 | if(typeof exports === 'object' && typeof module === 'object') 4 | module.exports = factory(); 5 | else if(typeof define === 'function' && define.amd) 6 | define([], factory); 7 | else if(typeof exports === 'object') 8 | exports["axios"] = factory(); 9 | else 10 | root["axios"] = factory(); 11 | })(this, function() { 12 | return /******/ (function(modules) { // webpackBootstrap 13 | /******/ // The module cache 14 | /******/ var installedModules = {}; 15 | /******/ 16 | /******/ // The require function 17 | /******/ function __webpack_require__(moduleId) { 18 | /******/ 19 | /******/ // Check if module is in cache 20 | /******/ if(installedModules[moduleId]) 21 | /******/ return installedModules[moduleId].exports; 22 | /******/ 23 | /******/ // Create a new module (and put it into the cache) 24 | /******/ var module = installedModules[moduleId] = { 25 | /******/ exports: {}, 26 | /******/ id: moduleId, 27 | /******/ loaded: false 28 | /******/ }; 29 | /******/ 30 | /******/ // Execute the module function 31 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 32 | /******/ 33 | /******/ // Flag the module as loaded 34 | /******/ module.loaded = true; 35 | /******/ 36 | /******/ // Return the exports of the module 37 | /******/ return module.exports; 38 | /******/ } 39 | /******/ 40 | /******/ 41 | /******/ // expose the modules object (__webpack_modules__) 42 | /******/ __webpack_require__.m = modules; 43 | /******/ 44 | /******/ // expose the module cache 45 | /******/ __webpack_require__.c = installedModules; 46 | /******/ 47 | /******/ // __webpack_public_path__ 48 | /******/ __webpack_require__.p = ""; 49 | /******/ 50 | /******/ // Load entry module and return exports 51 | /******/ return __webpack_require__(0); 52 | /******/ }) 53 | /************************************************************************/ 54 | /******/ ([ 55 | /* 0 */ 56 | /***/ (function(module, exports, __webpack_require__) { 57 | 58 | module.exports = __webpack_require__(1); 59 | 60 | /***/ }), 61 | /* 1 */ 62 | /***/ (function(module, exports, __webpack_require__) { 63 | 64 | 'use strict'; 65 | 66 | var utils = __webpack_require__(2); 67 | var bind = __webpack_require__(3); 68 | var Axios = __webpack_require__(5); 69 | var defaults = __webpack_require__(6); 70 | 71 | /** 72 | * Create an instance of Axios 73 | * 74 | * @param {Object} defaultConfig The default config for the instance 75 | * @return {Axios} A new instance of Axios 76 | */ 77 | function createInstance(defaultConfig) { 78 | var context = new Axios(defaultConfig); 79 | var instance = bind(Axios.prototype.request, context); 80 | 81 | // Copy axios.prototype to instance 82 | utils.extend(instance, Axios.prototype, context); 83 | 84 | // Copy context to instance 85 | utils.extend(instance, context); 86 | 87 | return instance; 88 | } 89 | 90 | // Create the default instance to be exported 91 | var axios = createInstance(defaults); 92 | 93 | // Expose Axios class to allow class inheritance 94 | axios.Axios = Axios; 95 | 96 | // Factory for creating new instances 97 | axios.create = function create(instanceConfig) { 98 | return createInstance(utils.merge(defaults, instanceConfig)); 99 | }; 100 | 101 | // Expose Cancel & CancelToken 102 | axios.Cancel = __webpack_require__(23); 103 | axios.CancelToken = __webpack_require__(24); 104 | axios.isCancel = __webpack_require__(20); 105 | 106 | // Expose all/spread 107 | axios.all = function all(promises) { 108 | return Promise.all(promises); 109 | }; 110 | axios.spread = __webpack_require__(25); 111 | 112 | module.exports = axios; 113 | 114 | // Allow use of default import syntax in TypeScript 115 | module.exports.default = axios; 116 | 117 | 118 | /***/ }), 119 | /* 2 */ 120 | /***/ (function(module, exports, __webpack_require__) { 121 | 122 | 'use strict'; 123 | 124 | var bind = __webpack_require__(3); 125 | var isBuffer = __webpack_require__(4); 126 | 127 | /*global toString:true*/ 128 | 129 | // utils is a library of generic helper functions non-specific to axios 130 | 131 | var toString = Object.prototype.toString; 132 | 133 | /** 134 | * Determine if a value is an Array 135 | * 136 | * @param {Object} val The value to test 137 | * @returns {boolean} True if value is an Array, otherwise false 138 | */ 139 | function isArray(val) { 140 | return toString.call(val) === '[object Array]'; 141 | } 142 | 143 | /** 144 | * Determine if a value is an ArrayBuffer 145 | * 146 | * @param {Object} val The value to test 147 | * @returns {boolean} True if value is an ArrayBuffer, otherwise false 148 | */ 149 | function isArrayBuffer(val) { 150 | return toString.call(val) === '[object ArrayBuffer]'; 151 | } 152 | 153 | /** 154 | * Determine if a value is a FormData 155 | * 156 | * @param {Object} val The value to test 157 | * @returns {boolean} True if value is an FormData, otherwise false 158 | */ 159 | function isFormData(val) { 160 | return (typeof FormData !== 'undefined') && (val instanceof FormData); 161 | } 162 | 163 | /** 164 | * Determine if a value is a view on an ArrayBuffer 165 | * 166 | * @param {Object} val The value to test 167 | * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false 168 | */ 169 | function isArrayBufferView(val) { 170 | var result; 171 | if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) { 172 | result = ArrayBuffer.isView(val); 173 | } else { 174 | result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer); 175 | } 176 | return result; 177 | } 178 | 179 | /** 180 | * Determine if a value is a String 181 | * 182 | * @param {Object} val The value to test 183 | * @returns {boolean} True if value is a String, otherwise false 184 | */ 185 | function isString(val) { 186 | return typeof val === 'string'; 187 | } 188 | 189 | /** 190 | * Determine if a value is a Number 191 | * 192 | * @param {Object} val The value to test 193 | * @returns {boolean} True if value is a Number, otherwise false 194 | */ 195 | function isNumber(val) { 196 | return typeof val === 'number'; 197 | } 198 | 199 | /** 200 | * Determine if a value is undefined 201 | * 202 | * @param {Object} val The value to test 203 | * @returns {boolean} True if the value is undefined, otherwise false 204 | */ 205 | function isUndefined(val) { 206 | return typeof val === 'undefined'; 207 | } 208 | 209 | /** 210 | * Determine if a value is an Object 211 | * 212 | * @param {Object} val The value to test 213 | * @returns {boolean} True if value is an Object, otherwise false 214 | */ 215 | function isObject(val) { 216 | return val !== null && typeof val === 'object'; 217 | } 218 | 219 | /** 220 | * Determine if a value is a Date 221 | * 222 | * @param {Object} val The value to test 223 | * @returns {boolean} True if value is a Date, otherwise false 224 | */ 225 | function isDate(val) { 226 | return toString.call(val) === '[object Date]'; 227 | } 228 | 229 | /** 230 | * Determine if a value is a File 231 | * 232 | * @param {Object} val The value to test 233 | * @returns {boolean} True if value is a File, otherwise false 234 | */ 235 | function isFile(val) { 236 | return toString.call(val) === '[object File]'; 237 | } 238 | 239 | /** 240 | * Determine if a value is a Blob 241 | * 242 | * @param {Object} val The value to test 243 | * @returns {boolean} True if value is a Blob, otherwise false 244 | */ 245 | function isBlob(val) { 246 | return toString.call(val) === '[object Blob]'; 247 | } 248 | 249 | /** 250 | * Determine if a value is a Function 251 | * 252 | * @param {Object} val The value to test 253 | * @returns {boolean} True if value is a Function, otherwise false 254 | */ 255 | function isFunction(val) { 256 | return toString.call(val) === '[object Function]'; 257 | } 258 | 259 | /** 260 | * Determine if a value is a Stream 261 | * 262 | * @param {Object} val The value to test 263 | * @returns {boolean} True if value is a Stream, otherwise false 264 | */ 265 | function isStream(val) { 266 | return isObject(val) && isFunction(val.pipe); 267 | } 268 | 269 | /** 270 | * Determine if a value is a URLSearchParams object 271 | * 272 | * @param {Object} val The value to test 273 | * @returns {boolean} True if value is a URLSearchParams object, otherwise false 274 | */ 275 | function isURLSearchParams(val) { 276 | return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams; 277 | } 278 | 279 | /** 280 | * Trim excess whitespace off the beginning and end of a string 281 | * 282 | * @param {String} str The String to trim 283 | * @returns {String} The String freed of excess whitespace 284 | */ 285 | function trim(str) { 286 | return str.replace(/^\s*/, '').replace(/\s*$/, ''); 287 | } 288 | 289 | /** 290 | * Determine if we're running in a standard browser environment 291 | * 292 | * This allows axios to run in a web worker, and react-native. 293 | * Both environments support XMLHttpRequest, but not fully standard globals. 294 | * 295 | * web workers: 296 | * typeof window -> undefined 297 | * typeof document -> undefined 298 | * 299 | * react-native: 300 | * navigator.product -> 'ReactNative' 301 | */ 302 | function isStandardBrowserEnv() { 303 | if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') { 304 | return false; 305 | } 306 | return ( 307 | typeof window !== 'undefined' && 308 | typeof document !== 'undefined' 309 | ); 310 | } 311 | 312 | /** 313 | * Iterate over an Array or an Object invoking a function for each item. 314 | * 315 | * If `obj` is an Array callback will be called passing 316 | * the value, index, and complete array for each item. 317 | * 318 | * If 'obj' is an Object callback will be called passing 319 | * the value, key, and complete object for each property. 320 | * 321 | * @param {Object|Array} obj The object to iterate 322 | * @param {Function} fn The callback to invoke for each item 323 | */ 324 | function forEach(obj, fn) { 325 | // Don't bother if no value provided 326 | if (obj === null || typeof obj === 'undefined') { 327 | return; 328 | } 329 | 330 | // Force an array if not already something iterable 331 | if (typeof obj !== 'object') { 332 | /*eslint no-param-reassign:0*/ 333 | obj = [obj]; 334 | } 335 | 336 | if (isArray(obj)) { 337 | // Iterate over array values 338 | for (var i = 0, l = obj.length; i < l; i++) { 339 | fn.call(null, obj[i], i, obj); 340 | } 341 | } else { 342 | // Iterate over object keys 343 | for (var key in obj) { 344 | if (Object.prototype.hasOwnProperty.call(obj, key)) { 345 | fn.call(null, obj[key], key, obj); 346 | } 347 | } 348 | } 349 | } 350 | 351 | /** 352 | * Accepts varargs expecting each argument to be an object, then 353 | * immutably merges the properties of each object and returns result. 354 | * 355 | * When multiple objects contain the same key the later object in 356 | * the arguments list will take precedence. 357 | * 358 | * Example: 359 | * 360 | * ```js 361 | * var result = merge({foo: 123}, {foo: 456}); 362 | * console.log(result.foo); // outputs 456 363 | * ``` 364 | * 365 | * @param {Object} obj1 Object to merge 366 | * @returns {Object} Result of all merge properties 367 | */ 368 | function merge(/* obj1, obj2, obj3, ... */) { 369 | var result = {}; 370 | function assignValue(val, key) { 371 | if (typeof result[key] === 'object' && typeof val === 'object') { 372 | result[key] = merge(result[key], val); 373 | } else { 374 | result[key] = val; 375 | } 376 | } 377 | 378 | for (var i = 0, l = arguments.length; i < l; i++) { 379 | forEach(arguments[i], assignValue); 380 | } 381 | return result; 382 | } 383 | 384 | /** 385 | * Extends object a by mutably adding to it the properties of object b. 386 | * 387 | * @param {Object} a The object to be extended 388 | * @param {Object} b The object to copy properties from 389 | * @param {Object} thisArg The object to bind function to 390 | * @return {Object} The resulting value of object a 391 | */ 392 | function extend(a, b, thisArg) { 393 | forEach(b, function assignValue(val, key) { 394 | if (thisArg && typeof val === 'function') { 395 | a[key] = bind(val, thisArg); 396 | } else { 397 | a[key] = val; 398 | } 399 | }); 400 | return a; 401 | } 402 | 403 | module.exports = { 404 | isArray: isArray, 405 | isArrayBuffer: isArrayBuffer, 406 | isBuffer: isBuffer, 407 | isFormData: isFormData, 408 | isArrayBufferView: isArrayBufferView, 409 | isString: isString, 410 | isNumber: isNumber, 411 | isObject: isObject, 412 | isUndefined: isUndefined, 413 | isDate: isDate, 414 | isFile: isFile, 415 | isBlob: isBlob, 416 | isFunction: isFunction, 417 | isStream: isStream, 418 | isURLSearchParams: isURLSearchParams, 419 | isStandardBrowserEnv: isStandardBrowserEnv, 420 | forEach: forEach, 421 | merge: merge, 422 | extend: extend, 423 | trim: trim 424 | }; 425 | 426 | 427 | /***/ }), 428 | /* 3 */ 429 | /***/ (function(module, exports) { 430 | 431 | 'use strict'; 432 | 433 | module.exports = function bind(fn, thisArg) { 434 | return function wrap() { 435 | var args = new Array(arguments.length); 436 | for (var i = 0; i < args.length; i++) { 437 | args[i] = arguments[i]; 438 | } 439 | return fn.apply(thisArg, args); 440 | }; 441 | }; 442 | 443 | 444 | /***/ }), 445 | /* 4 */ 446 | /***/ (function(module, exports) { 447 | 448 | /*! 449 | * Determine if an object is a Buffer 450 | * 451 | * @author Feross Aboukhadijeh 452 | * @license MIT 453 | */ 454 | 455 | // The _isBuffer check is for Safari 5-7 support, because it's missing 456 | // Object.prototype.constructor. Remove this eventually 457 | module.exports = function (obj) { 458 | return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) 459 | } 460 | 461 | function isBuffer (obj) { 462 | return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) 463 | } 464 | 465 | // For Node v0.10 support. Remove this eventually. 466 | function isSlowBuffer (obj) { 467 | return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) 468 | } 469 | 470 | 471 | /***/ }), 472 | /* 5 */ 473 | /***/ (function(module, exports, __webpack_require__) { 474 | 475 | 'use strict'; 476 | 477 | var defaults = __webpack_require__(6); 478 | var utils = __webpack_require__(2); 479 | var InterceptorManager = __webpack_require__(17); 480 | var dispatchRequest = __webpack_require__(18); 481 | 482 | /** 483 | * Create a new instance of Axios 484 | * 485 | * @param {Object} instanceConfig The default config for the instance 486 | */ 487 | function Axios(instanceConfig) { 488 | this.defaults = instanceConfig; 489 | this.interceptors = { 490 | request: new InterceptorManager(), 491 | response: new InterceptorManager() 492 | }; 493 | } 494 | 495 | /** 496 | * Dispatch a request 497 | * 498 | * @param {Object} config The config specific for this request (merged with this.defaults) 499 | */ 500 | Axios.prototype.request = function request(config) { 501 | /*eslint no-param-reassign:0*/ 502 | // Allow for axios('example/url'[, config]) a la fetch API 503 | if (typeof config === 'string') { 504 | config = utils.merge({ 505 | url: arguments[0] 506 | }, arguments[1]); 507 | } 508 | 509 | config = utils.merge(defaults, {method: 'get'}, this.defaults, config); 510 | config.method = config.method.toLowerCase(); 511 | 512 | // Hook up interceptors middleware 513 | var chain = [dispatchRequest, undefined]; 514 | var promise = Promise.resolve(config); 515 | 516 | this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { 517 | chain.unshift(interceptor.fulfilled, interceptor.rejected); 518 | }); 519 | 520 | this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { 521 | chain.push(interceptor.fulfilled, interceptor.rejected); 522 | }); 523 | 524 | while (chain.length) { 525 | promise = promise.then(chain.shift(), chain.shift()); 526 | } 527 | 528 | return promise; 529 | }; 530 | 531 | // Provide aliases for supported request methods 532 | utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) { 533 | /*eslint func-names:0*/ 534 | Axios.prototype[method] = function(url, config) { 535 | return this.request(utils.merge(config || {}, { 536 | method: method, 537 | url: url 538 | })); 539 | }; 540 | }); 541 | 542 | utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { 543 | /*eslint func-names:0*/ 544 | Axios.prototype[method] = function(url, data, config) { 545 | return this.request(utils.merge(config || {}, { 546 | method: method, 547 | url: url, 548 | data: data 549 | })); 550 | }; 551 | }); 552 | 553 | module.exports = Axios; 554 | 555 | 556 | /***/ }), 557 | /* 6 */ 558 | /***/ (function(module, exports, __webpack_require__) { 559 | 560 | 'use strict'; 561 | 562 | var utils = __webpack_require__(2); 563 | var normalizeHeaderName = __webpack_require__(7); 564 | 565 | var DEFAULT_CONTENT_TYPE = { 566 | 'Content-Type': 'application/x-www-form-urlencoded' 567 | }; 568 | 569 | function setContentTypeIfUnset(headers, value) { 570 | if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) { 571 | headers['Content-Type'] = value; 572 | } 573 | } 574 | 575 | function getDefaultAdapter() { 576 | var adapter; 577 | if (typeof XMLHttpRequest !== 'undefined') { 578 | // For browsers use XHR adapter 579 | adapter = __webpack_require__(8); 580 | } else if (typeof process !== 'undefined') { 581 | // For node use HTTP adapter 582 | adapter = __webpack_require__(8); 583 | } 584 | return adapter; 585 | } 586 | 587 | var defaults = { 588 | adapter: getDefaultAdapter(), 589 | 590 | transformRequest: [function transformRequest(data, headers) { 591 | normalizeHeaderName(headers, 'Content-Type'); 592 | if (utils.isFormData(data) || 593 | utils.isArrayBuffer(data) || 594 | utils.isBuffer(data) || 595 | utils.isStream(data) || 596 | utils.isFile(data) || 597 | utils.isBlob(data) 598 | ) { 599 | return data; 600 | } 601 | if (utils.isArrayBufferView(data)) { 602 | return data.buffer; 603 | } 604 | if (utils.isURLSearchParams(data)) { 605 | setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8'); 606 | return data.toString(); 607 | } 608 | if (utils.isObject(data)) { 609 | setContentTypeIfUnset(headers, 'application/json;charset=utf-8'); 610 | return JSON.stringify(data); 611 | } 612 | return data; 613 | }], 614 | 615 | transformResponse: [function transformResponse(data) { 616 | /*eslint no-param-reassign:0*/ 617 | if (typeof data === 'string') { 618 | try { 619 | data = JSON.parse(data); 620 | } catch (e) { /* Ignore */ } 621 | } 622 | return data; 623 | }], 624 | 625 | /** 626 | * A timeout in milliseconds to abort a request. If set to 0 (default) a 627 | * timeout is not created. 628 | */ 629 | timeout: 0, 630 | 631 | xsrfCookieName: 'XSRF-TOKEN', 632 | xsrfHeaderName: 'X-XSRF-TOKEN', 633 | 634 | maxContentLength: -1, 635 | 636 | validateStatus: function validateStatus(status) { 637 | return status >= 200 && status < 300; 638 | } 639 | }; 640 | 641 | defaults.headers = { 642 | common: { 643 | 'Accept': 'application/json, text/plain, */*' 644 | } 645 | }; 646 | 647 | utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) { 648 | defaults.headers[method] = {}; 649 | }); 650 | 651 | utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { 652 | defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE); 653 | }); 654 | 655 | module.exports = defaults; 656 | 657 | 658 | /***/ }), 659 | /* 7 */ 660 | /***/ (function(module, exports, __webpack_require__) { 661 | 662 | 'use strict'; 663 | 664 | var utils = __webpack_require__(2); 665 | 666 | module.exports = function normalizeHeaderName(headers, normalizedName) { 667 | utils.forEach(headers, function processHeader(value, name) { 668 | if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) { 669 | headers[normalizedName] = value; 670 | delete headers[name]; 671 | } 672 | }); 673 | }; 674 | 675 | 676 | /***/ }), 677 | /* 8 */ 678 | /***/ (function(module, exports, __webpack_require__) { 679 | 680 | 'use strict'; 681 | 682 | var utils = __webpack_require__(2); 683 | var settle = __webpack_require__(9); 684 | var buildURL = __webpack_require__(12); 685 | var parseHeaders = __webpack_require__(13); 686 | var isURLSameOrigin = __webpack_require__(14); 687 | var createError = __webpack_require__(10); 688 | var btoa = (typeof window !== 'undefined' && window.btoa && window.btoa.bind(window)) || __webpack_require__(15); 689 | 690 | module.exports = function xhrAdapter(config) { 691 | return new Promise(function dispatchXhrRequest(resolve, reject) { 692 | var requestData = config.data; 693 | var requestHeaders = config.headers; 694 | 695 | if (utils.isFormData(requestData)) { 696 | delete requestHeaders['Content-Type']; // Let the browser set it 697 | } 698 | 699 | var request = new XMLHttpRequest(); 700 | var loadEvent = 'onreadystatechange'; 701 | var xDomain = false; 702 | 703 | // For IE 8/9 CORS support 704 | // Only supports POST and GET calls and doesn't returns the response headers. 705 | // DON'T do this for testing b/c XMLHttpRequest is mocked, not XDomainRequest. 706 | if (("production") !== 'test' && 707 | typeof window !== 'undefined' && 708 | window.XDomainRequest && !('withCredentials' in request) && 709 | !isURLSameOrigin(config.url)) { 710 | request = new window.XDomainRequest(); 711 | loadEvent = 'onload'; 712 | xDomain = true; 713 | request.onprogress = function handleProgress() {}; 714 | request.ontimeout = function handleTimeout() {}; 715 | } 716 | 717 | // HTTP basic authentication 718 | if (config.auth) { 719 | var username = config.auth.username || ''; 720 | var password = config.auth.password || ''; 721 | requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password); 722 | } 723 | 724 | request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true); 725 | 726 | // Set the request timeout in MS 727 | request.timeout = config.timeout; 728 | 729 | // Listen for ready state 730 | request[loadEvent] = function handleLoad() { 731 | if (!request || (request.readyState !== 4 && !xDomain)) { 732 | return; 733 | } 734 | 735 | // The request errored out and we didn't get a response, this will be 736 | // handled by onerror instead 737 | // With one exception: request that using file: protocol, most browsers 738 | // will return status as 0 even though it's a successful request 739 | if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { 740 | return; 741 | } 742 | 743 | // Prepare the response 744 | var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null; 745 | var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response; 746 | var response = { 747 | data: responseData, 748 | // IE sends 1223 instead of 204 (https://github.com/axios/axios/issues/201) 749 | status: request.status === 1223 ? 204 : request.status, 750 | statusText: request.status === 1223 ? 'No Content' : request.statusText, 751 | headers: responseHeaders, 752 | config: config, 753 | request: request 754 | }; 755 | 756 | settle(resolve, reject, response); 757 | 758 | // Clean up request 759 | request = null; 760 | }; 761 | 762 | // Handle low level network errors 763 | request.onerror = function handleError() { 764 | // Real errors are hidden from us by the browser 765 | // onerror should only fire if it's a network error 766 | reject(createError('Network Error', config, null, request)); 767 | 768 | // Clean up request 769 | request = null; 770 | }; 771 | 772 | // Handle timeout 773 | request.ontimeout = function handleTimeout() { 774 | reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED', 775 | request)); 776 | 777 | // Clean up request 778 | request = null; 779 | }; 780 | 781 | // Add xsrf header 782 | // This is only done if running in a standard browser environment. 783 | // Specifically not if we're in a web worker, or react-native. 784 | if (utils.isStandardBrowserEnv()) { 785 | var cookies = __webpack_require__(16); 786 | 787 | // Add xsrf header 788 | var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ? 789 | cookies.read(config.xsrfCookieName) : 790 | undefined; 791 | 792 | if (xsrfValue) { 793 | requestHeaders[config.xsrfHeaderName] = xsrfValue; 794 | } 795 | } 796 | 797 | // Add headers to the request 798 | if ('setRequestHeader' in request) { 799 | utils.forEach(requestHeaders, function setRequestHeader(val, key) { 800 | if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') { 801 | // Remove Content-Type if data is undefined 802 | delete requestHeaders[key]; 803 | } else { 804 | // Otherwise add header to the request 805 | request.setRequestHeader(key, val); 806 | } 807 | }); 808 | } 809 | 810 | // Add withCredentials to request if needed 811 | if (config.withCredentials) { 812 | request.withCredentials = true; 813 | } 814 | 815 | // Add responseType to request if needed 816 | if (config.responseType) { 817 | try { 818 | request.responseType = config.responseType; 819 | } catch (e) { 820 | // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2. 821 | // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function. 822 | if (config.responseType !== 'json') { 823 | throw e; 824 | } 825 | } 826 | } 827 | 828 | // Handle progress if needed 829 | if (typeof config.onDownloadProgress === 'function') { 830 | request.addEventListener('progress', config.onDownloadProgress); 831 | } 832 | 833 | // Not all browsers support upload events 834 | if (typeof config.onUploadProgress === 'function' && request.upload) { 835 | request.upload.addEventListener('progress', config.onUploadProgress); 836 | } 837 | 838 | if (config.cancelToken) { 839 | // Handle cancellation 840 | config.cancelToken.promise.then(function onCanceled(cancel) { 841 | if (!request) { 842 | return; 843 | } 844 | 845 | request.abort(); 846 | reject(cancel); 847 | // Clean up request 848 | request = null; 849 | }); 850 | } 851 | 852 | if (requestData === undefined) { 853 | requestData = null; 854 | } 855 | 856 | // Send the request 857 | request.send(requestData); 858 | }); 859 | }; 860 | 861 | 862 | /***/ }), 863 | /* 9 */ 864 | /***/ (function(module, exports, __webpack_require__) { 865 | 866 | 'use strict'; 867 | 868 | var createError = __webpack_require__(10); 869 | 870 | /** 871 | * Resolve or reject a Promise based on response status. 872 | * 873 | * @param {Function} resolve A function that resolves the promise. 874 | * @param {Function} reject A function that rejects the promise. 875 | * @param {object} response The response. 876 | */ 877 | module.exports = function settle(resolve, reject, response) { 878 | var validateStatus = response.config.validateStatus; 879 | // Note: status is not exposed by XDomainRequest 880 | if (!response.status || !validateStatus || validateStatus(response.status)) { 881 | resolve(response); 882 | } else { 883 | reject(createError( 884 | 'Request failed with status code ' + response.status, 885 | response.config, 886 | null, 887 | response.request, 888 | response 889 | )); 890 | } 891 | }; 892 | 893 | 894 | /***/ }), 895 | /* 10 */ 896 | /***/ (function(module, exports, __webpack_require__) { 897 | 898 | 'use strict'; 899 | 900 | var enhanceError = __webpack_require__(11); 901 | 902 | /** 903 | * Create an Error with the specified message, config, error code, request and response. 904 | * 905 | * @param {string} message The error message. 906 | * @param {Object} config The config. 907 | * @param {string} [code] The error code (for example, 'ECONNABORTED'). 908 | * @param {Object} [request] The request. 909 | * @param {Object} [response] The response. 910 | * @returns {Error} The created error. 911 | */ 912 | module.exports = function createError(message, config, code, request, response) { 913 | var error = new Error(message); 914 | return enhanceError(error, config, code, request, response); 915 | }; 916 | 917 | 918 | /***/ }), 919 | /* 11 */ 920 | /***/ (function(module, exports) { 921 | 922 | 'use strict'; 923 | 924 | /** 925 | * Update an Error with the specified config, error code, and response. 926 | * 927 | * @param {Error} error The error to update. 928 | * @param {Object} config The config. 929 | * @param {string} [code] The error code (for example, 'ECONNABORTED'). 930 | * @param {Object} [request] The request. 931 | * @param {Object} [response] The response. 932 | * @returns {Error} The error. 933 | */ 934 | module.exports = function enhanceError(error, config, code, request, response) { 935 | error.config = config; 936 | if (code) { 937 | error.code = code; 938 | } 939 | error.request = request; 940 | error.response = response; 941 | return error; 942 | }; 943 | 944 | 945 | /***/ }), 946 | /* 12 */ 947 | /***/ (function(module, exports, __webpack_require__) { 948 | 949 | 'use strict'; 950 | 951 | var utils = __webpack_require__(2); 952 | 953 | function encode(val) { 954 | return encodeURIComponent(val). 955 | replace(/%40/gi, '@'). 956 | replace(/%3A/gi, ':'). 957 | replace(/%24/g, '$'). 958 | replace(/%2C/gi, ','). 959 | replace(/%20/g, '+'). 960 | replace(/%5B/gi, '['). 961 | replace(/%5D/gi, ']'); 962 | } 963 | 964 | /** 965 | * Build a URL by appending params to the end 966 | * 967 | * @param {string} url The base of the url (e.g., http://www.google.com) 968 | * @param {object} [params] The params to be appended 969 | * @returns {string} The formatted url 970 | */ 971 | module.exports = function buildURL(url, params, paramsSerializer) { 972 | /*eslint no-param-reassign:0*/ 973 | if (!params) { 974 | return url; 975 | } 976 | 977 | var serializedParams; 978 | if (paramsSerializer) { 979 | serializedParams = paramsSerializer(params); 980 | } else if (utils.isURLSearchParams(params)) { 981 | serializedParams = params.toString(); 982 | } else { 983 | var parts = []; 984 | 985 | utils.forEach(params, function serialize(val, key) { 986 | if (val === null || typeof val === 'undefined') { 987 | return; 988 | } 989 | 990 | if (utils.isArray(val)) { 991 | key = key + '[]'; 992 | } else { 993 | val = [val]; 994 | } 995 | 996 | utils.forEach(val, function parseValue(v) { 997 | if (utils.isDate(v)) { 998 | v = v.toISOString(); 999 | } else if (utils.isObject(v)) { 1000 | v = JSON.stringify(v); 1001 | } 1002 | parts.push(encode(key) + '=' + encode(v)); 1003 | }); 1004 | }); 1005 | 1006 | serializedParams = parts.join('&'); 1007 | } 1008 | 1009 | if (serializedParams) { 1010 | url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams; 1011 | } 1012 | 1013 | return url; 1014 | }; 1015 | 1016 | 1017 | /***/ }), 1018 | /* 13 */ 1019 | /***/ (function(module, exports, __webpack_require__) { 1020 | 1021 | 'use strict'; 1022 | 1023 | var utils = __webpack_require__(2); 1024 | 1025 | // Headers whose duplicates are ignored by node 1026 | // c.f. https://nodejs.org/api/http.html#http_message_headers 1027 | var ignoreDuplicateOf = [ 1028 | 'age', 'authorization', 'content-length', 'content-type', 'etag', 1029 | 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since', 1030 | 'last-modified', 'location', 'max-forwards', 'proxy-authorization', 1031 | 'referer', 'retry-after', 'user-agent' 1032 | ]; 1033 | 1034 | /** 1035 | * Parse headers into an object 1036 | * 1037 | * ``` 1038 | * Date: Wed, 27 Aug 2014 08:58:49 GMT 1039 | * Content-Type: application/json 1040 | * Connection: keep-alive 1041 | * Transfer-Encoding: chunked 1042 | * ``` 1043 | * 1044 | * @param {String} headers Headers needing to be parsed 1045 | * @returns {Object} Headers parsed into an object 1046 | */ 1047 | module.exports = function parseHeaders(headers) { 1048 | var parsed = {}; 1049 | var key; 1050 | var val; 1051 | var i; 1052 | 1053 | if (!headers) { return parsed; } 1054 | 1055 | utils.forEach(headers.split('\n'), function parser(line) { 1056 | i = line.indexOf(':'); 1057 | key = utils.trim(line.substr(0, i)).toLowerCase(); 1058 | val = utils.trim(line.substr(i + 1)); 1059 | 1060 | if (key) { 1061 | if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) { 1062 | return; 1063 | } 1064 | if (key === 'set-cookie') { 1065 | parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]); 1066 | } else { 1067 | parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; 1068 | } 1069 | } 1070 | }); 1071 | 1072 | return parsed; 1073 | }; 1074 | 1075 | 1076 | /***/ }), 1077 | /* 14 */ 1078 | /***/ (function(module, exports, __webpack_require__) { 1079 | 1080 | 'use strict'; 1081 | 1082 | var utils = __webpack_require__(2); 1083 | 1084 | module.exports = ( 1085 | utils.isStandardBrowserEnv() ? 1086 | 1087 | // Standard browser envs have full support of the APIs needed to test 1088 | // whether the request URL is of the same origin as current location. 1089 | (function standardBrowserEnv() { 1090 | var msie = /(msie|trident)/i.test(navigator.userAgent); 1091 | var urlParsingNode = document.createElement('a'); 1092 | var originURL; 1093 | 1094 | /** 1095 | * Parse a URL to discover it's components 1096 | * 1097 | * @param {String} url The URL to be parsed 1098 | * @returns {Object} 1099 | */ 1100 | function resolveURL(url) { 1101 | var href = url; 1102 | 1103 | if (msie) { 1104 | // IE needs attribute set twice to normalize properties 1105 | urlParsingNode.setAttribute('href', href); 1106 | href = urlParsingNode.href; 1107 | } 1108 | 1109 | urlParsingNode.setAttribute('href', href); 1110 | 1111 | // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils 1112 | return { 1113 | href: urlParsingNode.href, 1114 | protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '', 1115 | host: urlParsingNode.host, 1116 | search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '', 1117 | hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '', 1118 | hostname: urlParsingNode.hostname, 1119 | port: urlParsingNode.port, 1120 | pathname: (urlParsingNode.pathname.charAt(0) === '/') ? 1121 | urlParsingNode.pathname : 1122 | '/' + urlParsingNode.pathname 1123 | }; 1124 | } 1125 | 1126 | originURL = resolveURL(window.location.href); 1127 | 1128 | /** 1129 | * Determine if a URL shares the same origin as the current location 1130 | * 1131 | * @param {String} requestURL The URL to test 1132 | * @returns {boolean} True if URL shares the same origin, otherwise false 1133 | */ 1134 | return function isURLSameOrigin(requestURL) { 1135 | var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL; 1136 | return (parsed.protocol === originURL.protocol && 1137 | parsed.host === originURL.host); 1138 | }; 1139 | })() : 1140 | 1141 | // Non standard browser envs (web workers, react-native) lack needed support. 1142 | (function nonStandardBrowserEnv() { 1143 | return function isURLSameOrigin() { 1144 | return true; 1145 | }; 1146 | })() 1147 | ); 1148 | 1149 | 1150 | /***/ }), 1151 | /* 15 */ 1152 | /***/ (function(module, exports) { 1153 | 1154 | 'use strict'; 1155 | 1156 | // btoa polyfill for IE<10 courtesy https://github.com/davidchambers/Base64.js 1157 | 1158 | var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; 1159 | 1160 | function E() { 1161 | this.message = 'String contains an invalid character'; 1162 | } 1163 | E.prototype = new Error; 1164 | E.prototype.code = 5; 1165 | E.prototype.name = 'InvalidCharacterError'; 1166 | 1167 | function btoa(input) { 1168 | var str = String(input); 1169 | var output = ''; 1170 | for ( 1171 | // initialize result and counter 1172 | var block, charCode, idx = 0, map = chars; 1173 | // if the next str index does not exist: 1174 | // change the mapping table to "=" 1175 | // check if d has no fractional digits 1176 | str.charAt(idx | 0) || (map = '=', idx % 1); 1177 | // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 1178 | output += map.charAt(63 & block >> 8 - idx % 1 * 8) 1179 | ) { 1180 | charCode = str.charCodeAt(idx += 3 / 4); 1181 | if (charCode > 0xFF) { 1182 | throw new E(); 1183 | } 1184 | block = block << 8 | charCode; 1185 | } 1186 | return output; 1187 | } 1188 | 1189 | module.exports = btoa; 1190 | 1191 | 1192 | /***/ }), 1193 | /* 16 */ 1194 | /***/ (function(module, exports, __webpack_require__) { 1195 | 1196 | 'use strict'; 1197 | 1198 | var utils = __webpack_require__(2); 1199 | 1200 | module.exports = ( 1201 | utils.isStandardBrowserEnv() ? 1202 | 1203 | // Standard browser envs support document.cookie 1204 | (function standardBrowserEnv() { 1205 | return { 1206 | write: function write(name, value, expires, path, domain, secure) { 1207 | var cookie = []; 1208 | cookie.push(name + '=' + encodeURIComponent(value)); 1209 | 1210 | if (utils.isNumber(expires)) { 1211 | cookie.push('expires=' + new Date(expires).toGMTString()); 1212 | } 1213 | 1214 | if (utils.isString(path)) { 1215 | cookie.push('path=' + path); 1216 | } 1217 | 1218 | if (utils.isString(domain)) { 1219 | cookie.push('domain=' + domain); 1220 | } 1221 | 1222 | if (secure === true) { 1223 | cookie.push('secure'); 1224 | } 1225 | 1226 | document.cookie = cookie.join('; '); 1227 | }, 1228 | 1229 | read: function read(name) { 1230 | var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)')); 1231 | return (match ? decodeURIComponent(match[3]) : null); 1232 | }, 1233 | 1234 | remove: function remove(name) { 1235 | this.write(name, '', Date.now() - 86400000); 1236 | } 1237 | }; 1238 | })() : 1239 | 1240 | // Non standard browser env (web workers, react-native) lack needed support. 1241 | (function nonStandardBrowserEnv() { 1242 | return { 1243 | write: function write() {}, 1244 | read: function read() { return null; }, 1245 | remove: function remove() {} 1246 | }; 1247 | })() 1248 | ); 1249 | 1250 | 1251 | /***/ }), 1252 | /* 17 */ 1253 | /***/ (function(module, exports, __webpack_require__) { 1254 | 1255 | 'use strict'; 1256 | 1257 | var utils = __webpack_require__(2); 1258 | 1259 | function InterceptorManager() { 1260 | this.handlers = []; 1261 | } 1262 | 1263 | /** 1264 | * Add a new interceptor to the stack 1265 | * 1266 | * @param {Function} fulfilled The function to handle `then` for a `Promise` 1267 | * @param {Function} rejected The function to handle `reject` for a `Promise` 1268 | * 1269 | * @return {Number} An ID used to remove interceptor later 1270 | */ 1271 | InterceptorManager.prototype.use = function use(fulfilled, rejected) { 1272 | this.handlers.push({ 1273 | fulfilled: fulfilled, 1274 | rejected: rejected 1275 | }); 1276 | return this.handlers.length - 1; 1277 | }; 1278 | 1279 | /** 1280 | * Remove an interceptor from the stack 1281 | * 1282 | * @param {Number} id The ID that was returned by `use` 1283 | */ 1284 | InterceptorManager.prototype.eject = function eject(id) { 1285 | if (this.handlers[id]) { 1286 | this.handlers[id] = null; 1287 | } 1288 | }; 1289 | 1290 | /** 1291 | * Iterate over all the registered interceptors 1292 | * 1293 | * This method is particularly useful for skipping over any 1294 | * interceptors that may have become `null` calling `eject`. 1295 | * 1296 | * @param {Function} fn The function to call for each interceptor 1297 | */ 1298 | InterceptorManager.prototype.forEach = function forEach(fn) { 1299 | utils.forEach(this.handlers, function forEachHandler(h) { 1300 | if (h !== null) { 1301 | fn(h); 1302 | } 1303 | }); 1304 | }; 1305 | 1306 | module.exports = InterceptorManager; 1307 | 1308 | 1309 | /***/ }), 1310 | /* 18 */ 1311 | /***/ (function(module, exports, __webpack_require__) { 1312 | 1313 | 'use strict'; 1314 | 1315 | var utils = __webpack_require__(2); 1316 | var transformData = __webpack_require__(19); 1317 | var isCancel = __webpack_require__(20); 1318 | var defaults = __webpack_require__(6); 1319 | var isAbsoluteURL = __webpack_require__(21); 1320 | var combineURLs = __webpack_require__(22); 1321 | 1322 | /** 1323 | * Throws a `Cancel` if cancellation has been requested. 1324 | */ 1325 | function throwIfCancellationRequested(config) { 1326 | if (config.cancelToken) { 1327 | config.cancelToken.throwIfRequested(); 1328 | } 1329 | } 1330 | 1331 | /** 1332 | * Dispatch a request to the server using the configured adapter. 1333 | * 1334 | * @param {object} config The config that is to be used for the request 1335 | * @returns {Promise} The Promise to be fulfilled 1336 | */ 1337 | module.exports = function dispatchRequest(config) { 1338 | throwIfCancellationRequested(config); 1339 | 1340 | // Support baseURL config 1341 | if (config.baseURL && !isAbsoluteURL(config.url)) { 1342 | config.url = combineURLs(config.baseURL, config.url); 1343 | } 1344 | 1345 | // Ensure headers exist 1346 | config.headers = config.headers || {}; 1347 | 1348 | // Transform request data 1349 | config.data = transformData( 1350 | config.data, 1351 | config.headers, 1352 | config.transformRequest 1353 | ); 1354 | 1355 | // Flatten headers 1356 | config.headers = utils.merge( 1357 | config.headers.common || {}, 1358 | config.headers[config.method] || {}, 1359 | config.headers || {} 1360 | ); 1361 | 1362 | utils.forEach( 1363 | ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'], 1364 | function cleanHeaderConfig(method) { 1365 | delete config.headers[method]; 1366 | } 1367 | ); 1368 | 1369 | var adapter = config.adapter || defaults.adapter; 1370 | 1371 | return adapter(config).then(function onAdapterResolution(response) { 1372 | throwIfCancellationRequested(config); 1373 | 1374 | // Transform response data 1375 | response.data = transformData( 1376 | response.data, 1377 | response.headers, 1378 | config.transformResponse 1379 | ); 1380 | 1381 | return response; 1382 | }, function onAdapterRejection(reason) { 1383 | if (!isCancel(reason)) { 1384 | throwIfCancellationRequested(config); 1385 | 1386 | // Transform response data 1387 | if (reason && reason.response) { 1388 | reason.response.data = transformData( 1389 | reason.response.data, 1390 | reason.response.headers, 1391 | config.transformResponse 1392 | ); 1393 | } 1394 | } 1395 | 1396 | return Promise.reject(reason); 1397 | }); 1398 | }; 1399 | 1400 | 1401 | /***/ }), 1402 | /* 19 */ 1403 | /***/ (function(module, exports, __webpack_require__) { 1404 | 1405 | 'use strict'; 1406 | 1407 | var utils = __webpack_require__(2); 1408 | 1409 | /** 1410 | * Transform the data for a request or a response 1411 | * 1412 | * @param {Object|String} data The data to be transformed 1413 | * @param {Array} headers The headers for the request or response 1414 | * @param {Array|Function} fns A single function or Array of functions 1415 | * @returns {*} The resulting transformed data 1416 | */ 1417 | module.exports = function transformData(data, headers, fns) { 1418 | /*eslint no-param-reassign:0*/ 1419 | utils.forEach(fns, function transform(fn) { 1420 | data = fn(data, headers); 1421 | }); 1422 | 1423 | return data; 1424 | }; 1425 | 1426 | 1427 | /***/ }), 1428 | /* 20 */ 1429 | /***/ (function(module, exports) { 1430 | 1431 | 'use strict'; 1432 | 1433 | module.exports = function isCancel(value) { 1434 | return !!(value && value.__CANCEL__); 1435 | }; 1436 | 1437 | 1438 | /***/ }), 1439 | /* 21 */ 1440 | /***/ (function(module, exports) { 1441 | 1442 | 'use strict'; 1443 | 1444 | /** 1445 | * Determines whether the specified URL is absolute 1446 | * 1447 | * @param {string} url The URL to test 1448 | * @returns {boolean} True if the specified URL is absolute, otherwise false 1449 | */ 1450 | module.exports = function isAbsoluteURL(url) { 1451 | // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). 1452 | // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed 1453 | // by any combination of letters, digits, plus, period, or hyphen. 1454 | return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url); 1455 | }; 1456 | 1457 | 1458 | /***/ }), 1459 | /* 22 */ 1460 | /***/ (function(module, exports) { 1461 | 1462 | 'use strict'; 1463 | 1464 | /** 1465 | * Creates a new URL by combining the specified URLs 1466 | * 1467 | * @param {string} baseURL The base URL 1468 | * @param {string} relativeURL The relative URL 1469 | * @returns {string} The combined URL 1470 | */ 1471 | module.exports = function combineURLs(baseURL, relativeURL) { 1472 | return relativeURL 1473 | ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') 1474 | : baseURL; 1475 | }; 1476 | 1477 | 1478 | /***/ }), 1479 | /* 23 */ 1480 | /***/ (function(module, exports) { 1481 | 1482 | 'use strict'; 1483 | 1484 | /** 1485 | * A `Cancel` is an object that is thrown when an operation is canceled. 1486 | * 1487 | * @class 1488 | * @param {string=} message The message. 1489 | */ 1490 | function Cancel(message) { 1491 | this.message = message; 1492 | } 1493 | 1494 | Cancel.prototype.toString = function toString() { 1495 | return 'Cancel' + (this.message ? ': ' + this.message : ''); 1496 | }; 1497 | 1498 | Cancel.prototype.__CANCEL__ = true; 1499 | 1500 | module.exports = Cancel; 1501 | 1502 | 1503 | /***/ }), 1504 | /* 24 */ 1505 | /***/ (function(module, exports, __webpack_require__) { 1506 | 1507 | 'use strict'; 1508 | 1509 | var Cancel = __webpack_require__(23); 1510 | 1511 | /** 1512 | * A `CancelToken` is an object that can be used to request cancellation of an operation. 1513 | * 1514 | * @class 1515 | * @param {Function} executor The executor function. 1516 | */ 1517 | function CancelToken(executor) { 1518 | if (typeof executor !== 'function') { 1519 | throw new TypeError('executor must be a function.'); 1520 | } 1521 | 1522 | var resolvePromise; 1523 | this.promise = new Promise(function promiseExecutor(resolve) { 1524 | resolvePromise = resolve; 1525 | }); 1526 | 1527 | var token = this; 1528 | executor(function cancel(message) { 1529 | if (token.reason) { 1530 | // Cancellation has already been requested 1531 | return; 1532 | } 1533 | 1534 | token.reason = new Cancel(message); 1535 | resolvePromise(token.reason); 1536 | }); 1537 | } 1538 | 1539 | /** 1540 | * Throws a `Cancel` if cancellation has been requested. 1541 | */ 1542 | CancelToken.prototype.throwIfRequested = function throwIfRequested() { 1543 | if (this.reason) { 1544 | throw this.reason; 1545 | } 1546 | }; 1547 | 1548 | /** 1549 | * Returns an object that contains a new `CancelToken` and a function that, when called, 1550 | * cancels the `CancelToken`. 1551 | */ 1552 | CancelToken.source = function source() { 1553 | var cancel; 1554 | var token = new CancelToken(function executor(c) { 1555 | cancel = c; 1556 | }); 1557 | return { 1558 | token: token, 1559 | cancel: cancel 1560 | }; 1561 | }; 1562 | 1563 | module.exports = CancelToken; 1564 | 1565 | 1566 | /***/ }), 1567 | /* 25 */ 1568 | /***/ (function(module, exports) { 1569 | 1570 | 'use strict'; 1571 | 1572 | /** 1573 | * Syntactic sugar for invoking a function and expanding an array for arguments. 1574 | * 1575 | * Common use case would be to use `Function.prototype.apply`. 1576 | * 1577 | * ```js 1578 | * function f(x, y, z) {} 1579 | * var args = [1, 2, 3]; 1580 | * f.apply(null, args); 1581 | * ``` 1582 | * 1583 | * With `spread` this example can be re-written. 1584 | * 1585 | * ```js 1586 | * spread(function(x, y, z) {})([1, 2, 3]); 1587 | * ``` 1588 | * 1589 | * @param {Function} callback 1590 | * @returns {Function} 1591 | */ 1592 | module.exports = function spread(callback) { 1593 | return function wrap(arr) { 1594 | return callback.apply(null, arr); 1595 | }; 1596 | }; 1597 | 1598 | 1599 | /***/ }) 1600 | /******/ ]) 1601 | }); 1602 | ; 1603 | //# sourceMappingURL=axios.map -------------------------------------------------------------------------------- /shared/button.css: -------------------------------------------------------------------------------- 1 | .button { 2 | display: inline-block; 3 | border: none; 4 | padding: 0.5em 1em; 5 | margin: 0; 6 | text-decoration: none; 7 | background: #0069ed; 8 | color: #ffffff; 9 | font-family: sans-serif; 10 | font-size: 1rem; 11 | cursor: pointer; 12 | text-align: center; 13 | -webkit-appearance: none; 14 | -moz-appearance: none; 15 | } -------------------------------------------------------------------------------- /shared/carousel.css: -------------------------------------------------------------------------------- 1 | .carousel { 2 | width: 300px; 3 | } 4 | 5 | .slide-container { 6 | position: relative; 7 | height: 200px 8 | } 9 | 10 | .slide { 11 | position: absolute; 12 | top: 0; 13 | left: 0; 14 | height: 200px 15 | } 16 | 17 | .slide img { 18 | width: auto; 19 | height: 200px; 20 | } 21 | 22 | .carousel-controls { 23 | display: flex; 24 | justify-content: center; 25 | margin-top: 1rem; 26 | } 27 | 28 | .carousel-controls button + button { 29 | margin-left: 1rem; 30 | } 31 | 32 | .fade-enter-active, .fade-leave-active { 33 | transition: opacity .5s; 34 | } 35 | .fade-enter, .fade-leave-to { 36 | opacity: 0; 37 | } -------------------------------------------------------------------------------- /shared/cat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdietz/vue_components_book_examples/a80ae43cb02a1e56731d6197f1a0d1e8a11576fc/shared/cat.jpg -------------------------------------------------------------------------------- /shared/cat2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdietz/vue_components_book_examples/a80ae43cb02a1e56731d6197f1a0d1e8a11576fc/shared/cat2.jpg -------------------------------------------------------------------------------- /shared/cat3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fdietz/vue_components_book_examples/a80ae43cb02a1e56731d6197f1a0d1e8a11576fc/shared/cat3.jpg -------------------------------------------------------------------------------- /shared/expandable.css: -------------------------------------------------------------------------------- 1 | .expandable { 2 | width: 100%; 3 | } 4 | 5 | .expandable__header { 6 | display: flex; 7 | align-items: center; 8 | margin: 0; 9 | padding: 0.5em 0; 10 | 11 | border-top: 2px solid #555; 12 | } 13 | 14 | .expandable__trigger { 15 | all: inherit; 16 | margin-left: auto; 17 | border: 0; 18 | } 19 | 20 | .expandable__trigger svg { 21 | height: 1em; 22 | margin-left: 0.5em; 23 | fill: #555; 24 | } 25 | 26 | .expandable__trigger:focus svg { 27 | outline: 2px solid #aaa; 28 | } 29 | 30 | .expandable__content { 31 | padding: 1rem 0; 32 | } -------------------------------------------------------------------------------- /shared/image.svg: -------------------------------------------------------------------------------- 1 | artificial_intelligence -------------------------------------------------------------------------------- /shared/image_card.css: -------------------------------------------------------------------------------- 1 | .image-card { 2 | position: relative; 3 | display: flex; 4 | flex-direction: column; 5 | width: 300px; 6 | margin: 1rem; 7 | border-radius: 5px; 8 | color: #555; 9 | box-shadow: 0 0 3px 0 #aaa; 10 | background: #fff; 11 | user-select: none; 12 | } 13 | 14 | .image-card:hover { 15 | box-shadow:0 0 3px 0 #777; 16 | } 17 | 18 | .image-card__image { 19 | width: 300px; 20 | border-radius: 5px 5px 0 0; 21 | height: auto; 22 | } 23 | 24 | .image-card__body { 25 | display: flex; 26 | flex-direction: column; 27 | 28 | padding: 1rem; 29 | } 30 | 31 | .image-card__body h3 { 32 | margin-top: 0; 33 | margin-bottom: 0.2rem; 34 | } 35 | 36 | .image-card__author { 37 | margin: 0; 38 | font-size: 0.8rem; 39 | color: #999; 40 | } 41 | 42 | .image-card__heart { 43 | position: absolute; 44 | top: 1rem; 45 | left: 1rem; 46 | width: 24px; 47 | height: 24px; 48 | 49 | /* reset button */ 50 | background: none; 51 | border: 0; 52 | color: inherit; 53 | font: inherit; 54 | line-height: normal; 55 | overflow: visible; 56 | padding: 0; 57 | 58 | -webkit-appearance: none; 59 | -moz-appearance: none; 60 | appearance: none; 61 | 62 | cursor: pointer; 63 | 64 | fill: #fff; 65 | stroke: white; 66 | stroke-width: 2px; 67 | 68 | transition: all .35s ease-out; 69 | } 70 | 71 | .image-card__count { 72 | position: absolute; 73 | top: 1.2rem; 74 | left: 3rem; 75 | width: 24px; 76 | height: 24px; 77 | 78 | color: #FFF; 79 | } 80 | 81 | .image-card__heart:hover { 82 | fill: #fe4365; 83 | stroke: #fe4365; 84 | } 85 | 86 | .image-card__status { 87 | margin: 0.5rem 0; 88 | font-size: 0.8rem; 89 | } 90 | -------------------------------------------------------------------------------- /shared/list.css: -------------------------------------------------------------------------------- 1 | .list { 2 | display: flex; 3 | flex-direction: column; 4 | color: #555; 5 | width: 320px; 6 | } 7 | 8 | .list-item { 9 | display: flex; 10 | align-items: center; 11 | padding: 0.8rem 1rem; 12 | border: 1px solid #ccc; 13 | border-radius: 4px; 14 | background-color: white; 15 | margin-bottom: 0.5rem; 16 | } 17 | 18 | .list-item:hover { 19 | background-color: #fafafa; 20 | } 21 | 22 | .list-item__checkbox { 23 | margin-right: 1rem; 24 | } 25 | 26 | .list-item__title { 27 | margin-right: 1rem; 28 | } 29 | 30 | .list-item__remove { 31 | display: none; 32 | 33 | color: #555; 34 | font-size: 1rem; 35 | appearance: none; 36 | -webkit-appearance: none; 37 | margin: 0; 38 | padding: 0; 39 | border: 0; 40 | background: none; 41 | 42 | margin-left: auto; 43 | } 44 | 45 | .list-item:hover .list-item__remove { 46 | display: flex; 47 | } -------------------------------------------------------------------------------- /shared/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | /* background: #e5edfd; */ 3 | /* background: #f9efef; */ 4 | margin: 2rem; 5 | } 6 | 7 | #demo { 8 | display: block; 9 | } 10 | 11 | [v-cloak] {display: none} 12 | -------------------------------------------------------------------------------- /shared/modal.css: -------------------------------------------------------------------------------- 1 | .modal-background { 2 | position: fixed; 3 | z-index: 9998; 4 | top: 0; 5 | left: 0; 6 | width: 100%; 7 | height: 100%; 8 | background-color: rgba(0, 0, 0, .5); 9 | 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | } 14 | 15 | .modal-container { 16 | display: flex; 17 | flex-direction: column; 18 | 19 | width: 320px; 20 | height: 200px; 21 | padding: 1rem; 22 | background-color: #fff; 23 | border-radius: 2px; 24 | box-shadow: 0 2px 8px rgba(0, 0, 0, .33); 25 | } 26 | 27 | .modal-body { 28 | display: flex; 29 | flex-direction: column; 30 | flex: 1 1; 31 | } 32 | 33 | .modal-footer { 34 | display: flex; 35 | justify-content: flex-end; 36 | } 37 | -------------------------------------------------------------------------------- /shared/normalize-5.0.0.min.css: -------------------------------------------------------------------------------- 1 | button,hr,input{overflow:visible}audio,canvas,progress,video{display:inline-block}progress,sub,sup{vertical-align:baseline}html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0} menu,article,aside,details,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{}button,select{text-transform:none}[type=submit], [type=reset],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:ButtonText dotted 1px}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}[hidden],template{display:none}/*# sourceMappingURL=normalize.min.css.map */ -------------------------------------------------------------------------------- /shared/switch.css: -------------------------------------------------------------------------------- 1 | /** 2 | Switch component CSS from https://codepen.io/wilsonpage/pen/cxKEs from Wilson Page 3 | **/ 4 | .switch input { 5 | position: absolute; 6 | opacity: 0; 7 | } 8 | 9 | .switch { 10 | display: inline-block; 11 | font-size: 20px; /* 1 */ 12 | height: 1em; 13 | width: 2em; 14 | background: #efefef; 15 | border-radius: 1em; 16 | } 17 | 18 | .switch div { 19 | height: 1em; 20 | width: 1em; 21 | border-radius: 1em; 22 | background: #FFF; 23 | box-shadow: 0 0.1em 0.3em rgba(0,0,0,0.3); 24 | transition: all 300ms; 25 | } 26 | 27 | .switch input:checked + div { 28 | transform: translate3d(100%, 0, 0); 29 | } 30 | -------------------------------------------------------------------------------- /shared/table.css: -------------------------------------------------------------------------------- 1 | th { 2 | cursor: pointer; 3 | user-select: none; 4 | border-bottom: 2px solid #efefef; 5 | } 6 | 7 | 8 | th, td { 9 | padding: 10px 20px; 10 | } 11 | 12 | th.active { 13 | color: #1DA1F2; 14 | } 15 | 16 | th.active .arrow { 17 | color: #1DA1F2; 18 | opacity: 1; 19 | } 20 | 21 | .arrow { 22 | display: inline-block; 23 | vertical-align: middle; 24 | width: 0; 25 | height: 0; 26 | margin-left: 5px; 27 | opacity: 0; 28 | } 29 | 30 | .arrow.asc { 31 | border-left: 4px solid transparent; 32 | border-right: 4px solid transparent; 33 | border-bottom: 4px solid #1DA1F2; 34 | } 35 | 36 | .arrow.dsc { 37 | border-left: 4px solid transparent; 38 | border-right: 4px solid transparent; 39 | border-top: 4px solid #1DA1F2; 40 | } -------------------------------------------------------------------------------- /shared/tweet.css: -------------------------------------------------------------------------------- 1 | .tweet-item { 2 | display: flex; 3 | width: 600px; 4 | color: #333; 5 | background-color: white; 6 | border-bottom: 1px solid #e6ecf0; 7 | padding: 1.5rem 1rem; 8 | 9 | cursor: pointer; 10 | } 11 | 12 | .tweet-item:hover { 13 | background-color: #f5f8fa; 14 | } 15 | 16 | .tweet-media { 17 | 18 | } 19 | 20 | .tweet-media .circle { 21 | width: 48px; 22 | height: 48px; 23 | margin-right: 1rem; 24 | display: inline-block; 25 | overflow: hidden; 26 | background: #f3f6f9; 27 | border-radius: 50%; 28 | } 29 | 30 | .tweet-media .circle img { 31 | width: 100%; 32 | min-height: 100%; 33 | object-fit: cover; 34 | object-position: center; 35 | } 36 | 37 | .tweet-content { 38 | width: 100%; 39 | } 40 | 41 | .tweet-meta { 42 | margin-bottom: 0.5rem; 43 | color: rgb(101, 119, 134); 44 | } 45 | 46 | .tweet-meta .name { 47 | font-weight: bold; 48 | margin-right: 0.5rem; 49 | color: #333; 50 | } 51 | 52 | .tweet-meta .name:hover { 53 | color: #1DA1F2; 54 | text-decoration: underline; 55 | } 56 | 57 | .tweet-meta .handle { 58 | margin-right: 0.5rem 59 | } 60 | 61 | .tweet-body { 62 | margin-bottom: 1rem; 63 | } 64 | 65 | .tweet-body a { 66 | color: #1DA1F2; 67 | } 68 | 69 | .tweet-body a:hover { 70 | text-decoration: underline; 71 | } 72 | 73 | .image-wrapper img { 74 | display: block; 75 | width: 100%; 76 | height: auto; 77 | border-radius: 4px; 78 | } 79 | 80 | .video-wrapper { 81 | position: relative; 82 | width: 100%; 83 | height: 0; 84 | padding-bottom: 56.25%; 85 | } 86 | 87 | .video-wrapper .video { 88 | position: absolute; 89 | top: 0; 90 | left: 0; 91 | width: 100%; 92 | height: 100%; 93 | } 94 | 95 | .tweet-actions { 96 | display: flex; 97 | color: rgb(101, 119, 134); 98 | } 99 | 100 | .tweet-actions .svg-icon { 101 | width: 20px; 102 | height: 20px; 103 | 104 | fill: rgb(101, 119, 134); 105 | 106 | margin-right: 6rem; 107 | } 108 | 109 | .tweet-actions .svg-icon:hover { 110 | fill: #1DA1F2; 111 | } -------------------------------------------------------------------------------- /template/app.js: -------------------------------------------------------------------------------- 1 | Vue.component('image-card', { 2 | template: "#template-image-card", 3 | data: function () { 4 | return { 5 | count: 0 6 | } 7 | } 8 | }) 9 | 10 | new Vue({ el: '#demo' }); 11 | -------------------------------------------------------------------------------- /template/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Demo 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 |
19 | 20 | 37 | 38 | 39 | 40 | 41 | --------------------------------------------------------------------------------