├── Chapter01 ├── 001 - Mustache templating example.html ├── 002 - Data option as a function.html ├── 003 - Vanilla JS code.html ├── 004 - Vue code is easy to understand.html ├── 005 - Reactive forms with v-model.html ├── 006 - Directive modifiers.html ├── 007 - using the v-on directive.html ├── 008 - vue methods example.html └── 009 - computed properties example.html ├── Chapter02 ├── 001-what-is-reactivity │ └── 001.html ├── 002-computed-properties-and-methods │ ├── 002.css │ ├── 002.html │ └── 002.js ├── 003-computed-properties-and-methods-updated-code │ ├── 003.css │ ├── 003.html │ └── 003.js ├── 004-understanding-components │ ├── 004.html │ └── 004.js ├── 005-using-a-string-template-without-a-component │ ├── 005.html │ └── 005.js ├── 006-adding-props-and-data-for-better-components │ ├── 006.css │ ├── 006.html │ └── 006.js ├── 007-adding-content-to-our-components-with-the-help-of-the-data-object │ ├── 007.css │ ├── 007.html │ ├── 007.js │ └── 008.js ├── 008-using-data-as-a-function-inside-our-component │ ├── 008.css │ ├── 008.html │ └── 008.js ├── 009-props-can-also-be-defined-as-objects │ ├── 009.css │ ├── 009.html │ └── 009.js ├── 010-the-child-component-will-revert-to-its-default-property │ ├── 010.css │ ├── 010.html │ └── 010.js ├── 011-building-component-templates-with-x-template │ ├── 011.css │ ├── 011.html │ └── 011.js ├── 012-building-a-simple-web-page-out-of-components │ ├── 012.css │ ├── 012.html │ └── 012.js ├── 013-creating-a-more-complex-page-out-of-components │ ├── 013.css │ ├── 013.html │ └── 013.js ├── 014-improving-our-vue-based-layouts-with-v-for │ ├── 014.css │ ├── 014.html │ └── 014.js ├── 015-watchers-in-vue │ ├── 015.css │ ├── 015.html │ └── 015.js └── 016-how-do-we-use-lifecycle-hooks │ ├── 016.css │ ├── 016.html │ └── 016.js ├── Chapter03 ├── 001-Global-Vue-component │ ├── 001.css │ ├── 001.html │ └── 001.js ├── 002-Local-Vue-component │ ├── 002.css │ ├── 002.html │ └── 002.js ├── 003-Local-Vue-component-making-it-work │ ├── 003.css │ ├── 003.html │ └── 003.js └── 005-example-of-slots-in-use │ ├── 005.css │ ├── 005.html │ └── 005.js ├── Chapter04 ├── 001-filter-that-rounds-up-decimal-scores │ ├── 001.css │ ├── 001.html │ └── 001.js ├── 002-calculate-student's-grade-based-on-points │ ├── 002.html │ └── 002.js ├── 003-using-filters-as-replacement-for-conditional-directives │ ├── 003.html │ └── 003.js ├── 004-chaining-fitlers-in-vue │ ├── 004.html │ └── 004.js ├── 005-extracting-reusable-functionality-into-mixins-in-Vue │ ├── 005.html │ └── 005.js ├── 006-staying-dry-with-mixins │ ├── 006.html │ └── 006.js ├── 007-updated-version-of-the-app │ ├── 007.html │ └── 007.js └── 008-refactoring-our-viewport-size-mixin │ ├── 008.html │ └── 008.js ├── Chapter05 ├── 001-a-simple-custom-directive │ ├── index.html │ └── js │ │ └── index.js ├── 002-simple-custom-local-directive │ ├── css │ │ └── style.css │ ├── index.html │ └── js │ │ └── index.js └── 003-passing-values-to-custom-directives │ ├── index.html │ └── js │ └── index.js ├── Chapter06 ├── 001-change-of-background-no-css-transition │ ├── css │ │ └── style.css │ └── index.html ├── 002-change-of-background-with-css-transition │ ├── css │ │ └── style.css │ └── index.html ├── 003-change-of-background-with-css-animation │ ├── css │ │ └── style.css │ └── index.html ├── 004-change-of-background-with-css-animation-multistep │ ├── css │ │ └── style.css │ └── index.html ├── 005-css-transitions-in-vue │ ├── css │ │ └── style.css │ ├── index.html │ └── js │ │ └── index.js ├── 006-using-transition-element-in-vue │ ├── css │ │ └── style.css │ ├── index.html │ └── js │ │ └── index.js ├── 007-using-transition-element-in-vue-with-animation-hooks-enter │ ├── css │ │ └── style.css │ ├── index.html │ └── js │ │ └── index.js ├── 008-using-transition-element-in-vue-with-animation-hooks-leave │ ├── css │ │ └── style.css │ ├── index.html │ └── js │ │ └── index.js ├── 009-animation-hooks-in-vue-pt2 │ ├── css │ │ └── style.css │ ├── index.html │ └── js │ │ └── index.js ├── 010-animation-hooks-with-named-transitions │ ├── css │ │ └── style.css │ ├── index.html │ └── js │ │ └── index.js ├── 011-css-animations-in-vue-transitions │ ├── css │ │ └── style.css │ ├── index.html │ └── js │ │ └── index.js ├── 012-custom-transition-classes-in-vue │ ├── css │ │ └── style.css │ ├── index.html │ └── js │ │ └── index.js ├── 013-transition-modes-in-vue-2 │ ├── css │ │ └── style.css │ ├── index.html │ └── js │ │ └── index.js ├── 014-binding-css-classes │ ├── index.html │ └── js │ │ └── index.js ├── 015-improving-dynamic-css-classes-example │ ├── index.html │ └── js │ │ └── index.js ├── 016-improving-dynamic-css-classes-example │ ├── index.html │ └── js │ │ └── index.js ├── 017-transition-groups-in-vue-2 │ ├── css │ │ └── style.css │ ├── index.html │ └── js │ │ └── index.js └── 018-transition-groups-with-js-animation-hooks │ ├── css │ └── style.css │ ├── index.html │ └── js │ └── index.js ├── Chapter07 ├── 001-a-very-basic-vuex-app │ ├── index.html │ └── js │ │ └── index.js └── 002-extending-the-fruit-counter │ ├── index.html │ └── js │ └── index.js ├── Chapter08 ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── README.md ├── assets │ └── README.md ├── components │ ├── AppLogo.vue │ ├── Navigation.vue │ └── README.md ├── layouts │ ├── README.md │ └── default.vue ├── middleware │ └── README.md ├── nuxt.config.js ├── package-lock.json ├── package.json ├── pages │ ├── README.md │ ├── contact.vue │ ├── index.vue │ └── news.vue ├── plugins │ └── README.md ├── static │ ├── README.md │ └── favicon.ico └── store │ └── README.md ├── LICENSE └── README.md /Chapter01/001 - Mustache templating example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | CodePen - 001 - Mustache templating example 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 33 | 34 |
35 |

{{ heading1 }}

36 |

Just an {{ heading2 }}

37 |

{{paragraph1}} is fun

38 |
39 | 40 | 41 | 42 | 43 | 44 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Chapter01/002 - Data option as a function.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | CodePen - 002 - Data option as a function 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 33 | 34 |
35 |

{{ heading1 }}

36 |

Just an {{ heading2 }}

37 |

{{paragraph1}} is fun

38 |
39 | 40 | 41 | 42 | 43 | 44 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /Chapter01/003 - Vanilla JS code.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | CodePen - 003 - Vanilla JS code 12 | 13 | 14 | 15 | 16 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Chapter01/004 - Vue code is easy to understand.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | CodePen - 004 - Vue code is easy to understand 12 | 13 | 14 | 15 | 16 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 46 | 47 | 48 | 49 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /Chapter01/005 - Reactive forms with v-model.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | CodePen - 005 - Reactive forms with v-model 12 | 13 | 14 | 15 | 16 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 | Enter the weight in kilograms: 38 | 39 |
The weight in pounds is: {{ someNum * 2.20 }}
40 |
41 | 42 | 43 | 44 | 45 | 46 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /Chapter01/006 - Directive modifiers.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | CodePen - 006 - Directive modifiers 12 | 13 | 14 | 15 | 16 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 | 38 |

You have typed in: {{ userInput }}

39 |
40 | 41 | 42 | 43 | 44 | 45 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /Chapter01/007 - using the v-on directive.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | CodePen - 007 - Using the v-on directive 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
31 | 32 | 33 | 34 | 35 | 36 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Chapter01/008 - vue methods example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | CodePen - 008 - Vue methods example 12 | 13 | 14 | 15 | 16 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
33 | 34 | 35 | 36 |
37 | 38 | 39 | 40 | 41 | 42 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /Chapter01/009 - computed properties example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | CodePen - 009 - Vue computed properties example 12 | 13 | 14 | 15 | 16 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
33 |

User name: {{ userName }}

34 | 35 |

User name prefixed with a title: "{{ prefixedMessage }}"

36 |
37 | 38 | 39 | 40 | 41 | 42 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /Chapter02/001-what-is-reactivity/001.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 | 13 | 14 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Chapter02/002-computed-properties-and-methods/002.css: -------------------------------------------------------------------------------- 1 | body, input { 2 | font-family: Arial, sans-serif; 3 | font-size: 20px; 4 | } -------------------------------------------------------------------------------- /Chapter02/002-computed-properties-and-methods/002.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 002-computed properties and methods 9 | 10 | 11 | 12 | 13 | 14 |
15 |

Enter owner name and the thing that is owned: 16 | 17 | 18 |

19 | {{ ownerName }} 20 | has a 21 | {{ thing }} 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter02/002-computed-properties-and-methods/002.js: -------------------------------------------------------------------------------- 1 | var example = new Vue({ 2 | el: '#example', 3 | data: { 4 | ownerName: 'e.g Old McDonald', 5 | thing: 'e.g cow' 6 | }, 7 | computed: { 8 | // a computed getter 9 | ownerHasThing: function () { 10 | // `this` points to the Vue instance's data option 11 | return this.ownerName + " " + this.thing 12 | } 13 | } 14 | }) -------------------------------------------------------------------------------- /Chapter02/003-computed-properties-and-methods-updated-code/003.css: -------------------------------------------------------------------------------- 1 | body, input { 2 | font-family: Arial, sans-serif; 3 | font-size: 20px; 4 | } -------------------------------------------------------------------------------- /Chapter02/003-computed-properties-and-methods-updated-code/003.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 003-computed properties and methods - updated code 9 | 10 | 11 | 12 | 13 | 14 |
15 |

Enter owner name: 16 | 17 |

18 |

Enter thing owned: 19 | 20 |

21 |

{{ ownerHasThing }}

22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter02/003-computed-properties-and-methods-updated-code/003.js: -------------------------------------------------------------------------------- 1 | var example = new Vue({ 2 | el: '#example', 3 | data: { 4 | ownerName: '', 5 | thing: '' 6 | }, 7 | computed: { 8 | // a computed getter 9 | ownerHasThing: function () { 10 | // `this` points to the Vue instance's data option 11 | return this.ownerName + " has a " + this.thing 12 | } 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /Chapter02/004-understanding-components/004.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 004-understanding-components 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter02/004-understanding-components/004.js: -------------------------------------------------------------------------------- 1 | Vue.component('custom-article', { 2 | template: ` 3 |
4 | Our own custom article component! 5 |
` 6 | }) 7 | new Vue({ 8 | el: '#app' 9 | }) -------------------------------------------------------------------------------- /Chapter02/005-using-a-string-template-without-a-component/005.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 005-using-a-string-template-without-a-component 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Chapter02/005-using-a-string-template-without-a-component/005.js: -------------------------------------------------------------------------------- 1 | new Vue({ 2 | el: '#app', 3 | template: '
A string template without a component!
' 4 | }) -------------------------------------------------------------------------------- /Chapter02/006-adding-props-and-data-for-better-components/006.css: -------------------------------------------------------------------------------- 1 | article { 2 | font-size: 40px; 3 | padding: 20px; 4 | color: limegreen; 5 | font-family: Arial; 6 | border: 3px solid green; 7 | border-radius: 10px; 8 | } -------------------------------------------------------------------------------- /Chapter02/006-adding-props-and-data-for-better-components/006.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 006-adding props and data for better components 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter02/006-adding-props-and-data-for-better-components/006.js: -------------------------------------------------------------------------------- 1 | Vue.component('custom-article', { 2 | props: ['content'], 3 | template: '
{{content}}
' 4 | }) 5 | new Vue({ 6 | el: '#app', 7 | }) -------------------------------------------------------------------------------- /Chapter02/007-adding-content-to-our-components-with-the-help-of-the-data-object/007.css: -------------------------------------------------------------------------------- 1 | article { 2 | font-size: 40px; 3 | padding: 20px; 4 | color: limegreen; 5 | font-family: Arial; 6 | border: 3px solid green; 7 | border-radius: 10px; 8 | } -------------------------------------------------------------------------------- /Chapter02/007-adding-content-to-our-components-with-the-help-of-the-data-object/007.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 007-adding content to our objects with the help of the data object 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Chapter02/007-adding-content-to-our-components-with-the-help-of-the-data-object/007.js: -------------------------------------------------------------------------------- 1 | Vue.component('custom-article', { 2 | props: ['content'], 3 | template: '
{{content}}
' 4 | }) 5 | new Vue({ 6 | el: '#app', 7 | data: { 8 | datacontent: 'This component was made with the help of a data object in the Vue instance' 9 | } 10 | }) -------------------------------------------------------------------------------- /Chapter02/007-adding-content-to-our-components-with-the-help-of-the-data-object/008.js: -------------------------------------------------------------------------------- 1 | Vue.component('custom-article', { 2 | template: '
{{datacontent}}
', 3 | data: function () { 4 | return { 5 | datacontent: 'This component was made with the help of a data function in the Vue component called custom-article' 6 | } 7 | } 8 | }) 9 | new Vue({ 10 | el: '#app' 11 | }) -------------------------------------------------------------------------------- /Chapter02/008-using-data-as-a-function-inside-our-component/008.css: -------------------------------------------------------------------------------- 1 | article { 2 | font-size: 30px; 3 | padding: 20px; 4 | color: limegreen; 5 | font-family: Arial; 6 | border: 3px solid green; 7 | border-radius: 10px; 8 | } -------------------------------------------------------------------------------- /Chapter02/008-using-data-as-a-function-inside-our-component/008.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 008-using-data-as-a-function-inside-our-component 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter02/008-using-data-as-a-function-inside-our-component/008.js: -------------------------------------------------------------------------------- 1 | Vue.component('custom-article', { 2 | template: '
{{datacontent}}
', 3 | data: function() { 4 | return { 5 | datacontent: 'This component was made with the help of a data function in the Vue component called custom-article' 6 | } 7 | } 8 | }) 9 | new Vue({ 10 | el: '#app' 11 | }) -------------------------------------------------------------------------------- /Chapter02/009-props-can-also-be-defined-as-objects/009.css: -------------------------------------------------------------------------------- 1 | .thetemplate { 2 | font-size: 30px; 3 | padding: 20px; 4 | color: limegreen; 5 | font-family: Arial; 6 | border: 3px solid green; 7 | border-radius: 10px; 8 | } 9 | -------------------------------------------------------------------------------- /Chapter02/009-props-can-also-be-defined-as-objects/009.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 009 - Props can also be defined as objects 9 | 10 | 11 | 12 | 13 |

The custom-article component below is expecting the parent to pass it a prop named message. 14 | 15 |

16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Chapter02/009-props-can-also-be-defined-as-objects/009.js: -------------------------------------------------------------------------------- 1 | Vue.component('custom-article', { 2 | props: { 3 | message: { 4 | type: String, 5 | required: true, 6 | default: 'Hello Vue' 7 | } 8 | }, 9 | template: `
{{ message }}
` 10 | }); 11 | 12 | new Vue({ 13 | el: "#app", 14 | data: function() { 15 | return { 16 | datacontent: 'This component was made with the help of a data function in the Vue component called custom-article, and the data passed was validated with the help of the props object inside the Vue component' 17 | } 18 | } 19 | }) -------------------------------------------------------------------------------- /Chapter02/010-the-child-component-will-revert-to-its-default-property/010.css: -------------------------------------------------------------------------------- 1 | .thetemplate { 2 | font-size: 30px; 3 | padding: 20px; 4 | color: limegreen; 5 | font-family: Arial; 6 | border: 3px solid green; 7 | border-radius: 10px; 8 | } -------------------------------------------------------------------------------- /Chapter02/010-the-child-component-will-revert-to-its-default-property/010.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 010 - The child component reverting to the default property in the props object 9 | 10 | 11 | 12 | 13 |

This is what happens if the datacontent is not providing the correct data - the child component will revert to its default property in the props object.

14 | 15 |
16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Chapter02/010-the-child-component-will-revert-to-its-default-property/010.js: -------------------------------------------------------------------------------- 1 | Vue.component('custom-article', { 2 | props: { 3 | message: { 4 | type: String, 5 | required: true, 6 | default: 'Hello Vue' 7 | } 8 | }, 9 | template: `
{{ message }}
` 10 | }); 11 | 12 | new Vue({ 13 | el: "#app", 14 | data: function() { 15 | return { 16 | datacontent: undefined 17 | } 18 | } 19 | }) -------------------------------------------------------------------------------- /Chapter02/011-building-component-templates-with-x-template/011.css: -------------------------------------------------------------------------------- 1 | #app { 2 | font-size: 30px; 3 | padding: 20px; 4 | color: limegreen; 5 | font-family: Arial; 6 | border: 3px solid green; 7 | border-radius: 10px; 8 | } -------------------------------------------------------------------------------- /Chapter02/011-building-component-templates-with-x-template/011.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 011 - Building component templates with x-template 9 | 10 | 11 | 12 | 13 |

This is what happens if the datacontent is not providing the correct data - the child component will revert to its default property in the props object.

14 | 15 |
16 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Chapter02/011-building-component-templates-with-x-template/011.js: -------------------------------------------------------------------------------- 1 | Vue.component('custom-article', { 2 | template: '#custom-article-template', 3 | props: ['name'] 4 | }) 5 | new Vue({ 6 | el: '#app', 7 | name: 'Some content' 8 | }) -------------------------------------------------------------------------------- /Chapter02/012-building-a-simple-web-page-out-of-components/012.css: -------------------------------------------------------------------------------- 1 | #app { 2 | /* 3 | we're loading CDN Bootstrap 4.1 from the HTML file 4 | */ 5 | } -------------------------------------------------------------------------------- /Chapter02/012-building-a-simple-web-page-out-of-components/012.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 012 - Building a single web-page out of components 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Chapter02/012-building-a-simple-web-page-out-of-components/012.js: -------------------------------------------------------------------------------- 1 | Vue.component('the-header', { 2 | template: '

Our example header

' 3 | }) 4 | 5 | Vue.component('the-footer', { 6 | template: '' 7 | }) 8 | 9 | //Root Instance 10 | new Vue({ 11 | el: '#app', 12 | data: {} 13 | }) -------------------------------------------------------------------------------- /Chapter02/013-creating-a-more-complex-page-out-of-components/013.css: -------------------------------------------------------------------------------- 1 | /* 2 | loading Bootstrap 4.1 from a CDN! 3 | */ -------------------------------------------------------------------------------- /Chapter02/013-creating-a-more-complex-page-out-of-components/013.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 013 - Creating a more complex page 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 | 17 |
18 |
19 | 20 |
21 |
22 | 23 |
24 |
25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Chapter02/013-creating-a-more-complex-page-out-of-components/013.js: -------------------------------------------------------------------------------- 1 | Vue.component('the-header', { 2 | template: '

{{header}}

', 3 | data: function() { 4 | return { 5 | header: 'Just another simple header' 6 | } 7 | } 8 | }); 9 | 10 | Vue.component('the-card', { 11 | template: '
Special title treatment

With supporting text below as a natural lead-in to addtional content.

Go somewhere
', 12 | }); 13 | 14 | //Root Instance 15 | new Vue({ 16 | el: '#app', 17 | data: {} 18 | }) -------------------------------------------------------------------------------- /Chapter02/014-improving-our-vue-based-layouts-with-v-for/014.css: -------------------------------------------------------------------------------- 1 | /* */ -------------------------------------------------------------------------------- /Chapter02/014-improving-our-vue-based-layouts-with-v-for/014.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 014 - Improving our Vue-based layouts with the v-for directive 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 | 17 |
18 |
19 | 20 |
21 |
22 | 23 |
24 |
25 |
26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Chapter02/014-improving-our-vue-based-layouts-with-v-for/014.js: -------------------------------------------------------------------------------- 1 | //Register main title component 2 | Vue.component("main-title-component", { 3 | template: '

{{title}}

', 4 | data: function() { 5 | return { 6 | title: "Just another title" 7 | }; 8 | } 9 | }); 10 | 11 | //Register list group component 12 | Vue.component("list-group-component", { 13 | template: ` 14 | `, 17 | data: function() { 18 | return { 19 | items: [ 20 | { 21 | description: "Description one" 22 | }, 23 | { 24 | description: "Description two" 25 | }, 26 | { 27 | description: "Description three" 28 | } 29 | ] 30 | }; 31 | } 32 | }); 33 | 34 | // Register card component 35 | Vue.component("card-component", { 36 | template: ` 37 |
38 |
39 |
{{title}}
40 |

{{text}}

41 | Go somewhere 42 |
43 |
`, 44 | data: function() { 45 | return { 46 | title: "This is the card title", 47 | text: "This is the card text" 48 | }; 49 | } 50 | }); 51 | 52 | //Root Instance 53 | new Vue({ 54 | el: '#app', 55 | data: {} 56 | }) -------------------------------------------------------------------------------- /Chapter02/015-watchers-in-vue/015.css: -------------------------------------------------------------------------------- 1 | body, input { 2 | font-family: Arial, sans-serif; 3 | font-size: 20px; 4 | } -------------------------------------------------------------------------------- /Chapter02/015-watchers-in-vue/015.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 015 - Watchers in Vue 9 | 10 | 11 | 12 | 13 |
14 |

Enter owner name and the thing that is owned: 15 | 16 | 17 |

18 | {{ ownerName }} 19 | has a 20 | {{ thing }} 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Chapter02/015-watchers-in-vue/015.js: -------------------------------------------------------------------------------- 1 | var example = new Vue({ 2 | el: '#example', 3 | data: { 4 | ownerName: 'e.g Old McDonald', 5 | thing: 'e.g cow' 6 | }, 7 | watch: { 8 | ownerName(currentValue, previousValue) { 9 | console.log(`The value in the first input has changed from: ${previousValue} to: ${currentValue}`); 10 | } 11 | }, 12 | computed: { 13 | // a computed getter 14 | ownerHasThing: function () { 15 | // `this` points to the Vue instance's data option 16 | return this.ownerName + " " + this.thing 17 | } 18 | } 19 | }) -------------------------------------------------------------------------------- /Chapter02/016-how-do-we-use-lifecycle-hooks/016.css: -------------------------------------------------------------------------------- 1 | div,.thetemplate { 2 | font-size: 30px; 3 | padding: 20px; 4 | color: limegreen; 5 | font-family: Arial; 6 | border: 3px solid green; 7 | border-radius: 10px; 8 | } -------------------------------------------------------------------------------- /Chapter02/016-how-do-we-use-lifecycle-hooks/016.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 016 - Lifecycle hooks 9 | 10 | 11 | 12 | 13 |
Lorem ipsum dolor sit amet
14 |
15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter02/016-how-do-we-use-lifecycle-hooks/016.js: -------------------------------------------------------------------------------- 1 | Vue.component('custom-article', { 2 | props: { 3 | message: { 4 | type: String, 5 | required: true, 6 | default: 'Hello Vue' 7 | } 8 | }, 9 | template: `
{{ message }}
` 10 | }); 11 | 12 | new Vue({ 13 | el: "#app", 14 | beforeCreate() { 15 | alert("Lifecycle hook beforeCreate has been run"); 16 | }, 17 | created() { 18 | setTimeout(function(){ 19 | alert('This message is showing 5 seconds after the \'created\' lifecycle hook'); 20 | },5000); 21 | }, 22 | data: function() { 23 | return { 24 | datacontent: 'This component was made with the help of a data function in the Vue component called custom-article, and the data passed was validated with the help of the props object inside the Vue component' 25 | } 26 | } 27 | }); -------------------------------------------------------------------------------- /Chapter03/001-Global-Vue-component/001.css: -------------------------------------------------------------------------------- 1 | div,.thetemplate { 2 | font-size: 30px; 3 | padding: 20px; 4 | color: limegreen; 5 | font-family: Arial; 6 | border: 3px solid green; 7 | border-radius: 10px; 8 | } -------------------------------------------------------------------------------- /Chapter03/001-Global-Vue-component/001.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 003-001 - Global Vue component 9 | 10 | 11 | 12 | 13 |
Lorem ipsum dolor sit amet
14 |
15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter03/001-Global-Vue-component/001.js: -------------------------------------------------------------------------------- 1 | Vue.component('custom-article', { 2 | props: { 3 | message: { 4 | type: String, 5 | required: true, 6 | default: 'Hello Vue' 7 | } 8 | }, 9 | template: `
{{ message }}
` 10 | }); 11 | 12 | new Vue({ 13 | el: "#app", 14 | beforeCreate() { 15 | alert("Lifecycle hook beforeCreate has been run"); 16 | }, 17 | created() { 18 | setTimeout(function(){ 19 | alert('This message is showing 5 seconds after the \'created\' lifecycle hook'); 20 | },5000); 21 | }, 22 | data: function() { 23 | return { 24 | datacontent: 'This component was made with the help of a data function in the Vue component called custom-article, and the data passed was validated with the help of the props object inside the Vue component' 25 | } 26 | } 27 | }); -------------------------------------------------------------------------------- /Chapter03/002-Local-Vue-component/002.css: -------------------------------------------------------------------------------- 1 | article { 2 | font-size: 40px; 3 | padding: 20px; 4 | color: limegreen; 5 | font-family: Arial; 6 | border: 3px solid green; 7 | border-radius: 10px; 8 | } -------------------------------------------------------------------------------- /Chapter03/002-Local-Vue-component/002.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 003-002 - Local Vue component 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Chapter03/002-Local-Vue-component/002.js: -------------------------------------------------------------------------------- 1 | var customArticle = { 2 | template: ` 3 |
4 | Our own custom article component! 5 |
` 6 | } 7 | Vue.component('another-custom-article', { 8 | template: ` 9 |
10 | Another custom article component! 11 | This one has it's own child component too! 12 | Here it is: 13 | 14 |
`, 15 | //components: { 16 | // 'customArticle': customArticle 17 | //} 18 | }) 19 | new Vue({ 20 | el: '#app', 21 | components: { 22 | 'customArticle': customArticle 23 | } 24 | }) -------------------------------------------------------------------------------- /Chapter03/003-Local-Vue-component-making-it-work/003.css: -------------------------------------------------------------------------------- 1 | article { 2 | font-size: 40px; 3 | padding: 20px; 4 | color: limegreen; 5 | font-family: Arial; 6 | border: 3px solid green; 7 | border-radius: 10px; 8 | } -------------------------------------------------------------------------------- /Chapter03/003-Local-Vue-component-making-it-work/003.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 003-003 - Local Vue component - making it work 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Chapter03/003-Local-Vue-component-making-it-work/003.js: -------------------------------------------------------------------------------- 1 | var customArticle = { 2 | template: ` 3 |
4 | Our own custom article component! 5 |
` 6 | } 7 | Vue.component('another-custom-article', { 8 | template: ` 9 |
10 | Another custom article component! 11 | This one has it's own child component too! 12 | Here it is: 13 | 14 |
`, 15 | components: { 16 | 'customArticle': customArticle 17 | } 18 | }) 19 | new Vue({ 20 | el: '#app', 21 | components: { 22 | 'customArticle': customArticle 23 | } 24 | }) -------------------------------------------------------------------------------- /Chapter03/005-example-of-slots-in-use/005.css: -------------------------------------------------------------------------------- 1 | div { 2 | font-size: 30px; 3 | padding: 20px; 4 | color: darkgoldenrod; 5 | font-family: Arial; 6 | border: 3px solid darkgoldenrod; 7 | border-radius: 0px; 8 | } -------------------------------------------------------------------------------- /Chapter03/005-example-of-slots-in-use/005.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 003-005 - Example of slots in use 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Chapter03/005-example-of-slots-in-use/005.js: -------------------------------------------------------------------------------- 1 | Vue.component("basicComponent", { 2 | template: ` 3 |
4 | 5 | 6 | This is some default information 7 |
8 | ` 9 | }); 10 | 11 | new Vue({ 12 | el: "#app", 13 | template: ` 14 | 15 |

This content will populate the slot named 'firstSlot' in the 'basicComponent' template

16 | 17 |

This content will populate the slot named 'secondSlot' in the 'basicComponent' template

18 | 19 |
20 | ` 21 | }); -------------------------------------------------------------------------------- /Chapter04/001-filter-that-rounds-up-decimal-scores/001.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-Quick-Start-Guide/5d1cff154f12dd38b050e10c6c24d3c991b2d2f8/Chapter04/001-filter-that-rounds-up-decimal-scores/001.css -------------------------------------------------------------------------------- /Chapter04/001-filter-that-rounds-up-decimal-scores/001.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 003-001 - Global Vue component 9 | 10 | 11 | 12 | 13 |
14 |

A simple grade-rounding Vue app

15 |

Points from test: {{ points }}

16 |

Rounded points are: {{ points | pointsRoundedUp }}

17 |
18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter04/001-filter-that-rounds-up-decimal-scores/001.js: -------------------------------------------------------------------------------- 1 | new Vue({ 2 | el: "#app", 3 | data() { 4 | return { 5 | points: 74.44 6 | } 7 | }, 8 | filters: { 9 | pointsRoundedUp(points){ 10 | return Math.ceil(parseFloat(points)); 11 | } 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /Chapter04/002-calculate-student's-grade-based-on-points/002.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 004-002 - Calculate student's grades based on points 9 | 10 | 11 | 12 | 13 |
14 |

A simple grade-rounding Vue app

15 |

Points from test: {{ points }}

16 |

Rounded points are: {{ points | pointsRoundedUp }}

17 |

Final grade: A

18 |

Final grade: B

19 |

Final grade: C

20 |

Final grade: D

21 |

Final grade: E

22 |

Final grade: F

23 |
24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter04/002-calculate-student's-grade-based-on-points/002.js: -------------------------------------------------------------------------------- 1 | new Vue({ 2 | el: "#app", 3 | data() { 4 | return { 5 | points: 94.44 6 | } 7 | }, 8 | filters: { 9 | pointsRoundedUp(points){ 10 | return Math.ceil(parseFloat(points)); 11 | } 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /Chapter04/003-using-filters-as-replacement-for-conditional-directives/003.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 004-003 - Using filters as replacement for conditional directives 9 | 10 | 11 | 12 | 13 |
14 |

A simple grade-rounding Vue app

15 |

Points from test: {{ points }}

16 |

Rounded points are: {{ points | pointsRoundedUp }}

17 |

Final grade: {{ points | pointsToGrade }}

18 |
19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Chapter04/003-using-filters-as-replacement-for-conditional-directives/003.js: -------------------------------------------------------------------------------- 1 | new Vue({ 2 | el: "#app", 3 | data() { 4 | return { 5 | points: 84.44 6 | } 7 | }, 8 | filters: { 9 | pointsRoundedUp(points){ 10 | return Math.ceil(parseFloat(points)); 11 | }, 12 | pointsToGrade(points){ 13 | if(points>90) { 14 | return "A" 15 | } 16 | else if(points>80 && points<90) { 17 | return "B" 18 | } 19 | else if(points>70 && points<80) { 20 | return "C" 21 | } 22 | else if(points>60 && points<70) { 23 | return "D" 24 | } 25 | else if(points>50 && points<60) { 26 | return "E" 27 | } 28 | else { 29 | return "F" 30 | } 31 | } 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /Chapter04/004-chaining-fitlers-in-vue/004.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 004-004 - Chaining filters in Vue 9 | 10 | 11 | 12 | 13 |
14 |

A simple grade-rounding Vue app

15 |

Points from test: {{ points }}

16 |

Rounded points are: {{ points | pointsRoundedUp }}

17 |

Student info: 18 | 21 |

22 | Name: 23 | {{ lastName | toLowerCase | capitalizeFirstLetter }}, 24 | {{ firstName | toLowerCase | capitalizeFirstLetter }} 25 |

26 |

Year of study: {{ yearOfStudy | yearNumberToWord }}

27 |

Final grade: {{ points | pointsToGrade }}

28 |
29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Chapter04/004-chaining-fitlers-in-vue/004.js: -------------------------------------------------------------------------------- 1 | new Vue({ 2 | el: "#app", 3 | data() { 4 | return { 5 | firstName: "JANE", 6 | lastName: "DOE", 7 | yearOfStudy: 1, 8 | points: 84.44, 9 | additionalPoints: 8 10 | } 11 | }, 12 | filters: { 13 | pointsRoundedUp(points){ 14 | return Math.ceil(parseFloat(points)); 15 | }, 16 | pointsToGrade(points){ 17 | if(points>90) { 18 | return "A" 19 | } 20 | else if(points>80 && points<90) { 21 | return "B" 22 | } 23 | else if(points>70 && points<80) { 24 | return "C" 25 | } 26 | else if(points>60 && points<70) { 27 | return "D" 28 | } 29 | else if(points>50 && points<60) { 30 | return "E" 31 | } 32 | else { 33 | return "F" 34 | } 35 | }, 36 | yearNumberToWord(yearOfStudy){ 37 | // freshman 1, sophomore 2, junior 3, senior 4 38 | if(yearOfStudy==1) { 39 | return "freshman" 40 | } else if(yearOfStudy==2){ 41 | return "sophomore" 42 | } else if(yearOfStudy==3){ 43 | return "junior" 44 | } else if(yearOfStudy==4){ 45 | return "senior" 46 | } else { 47 | return "unknown" 48 | } 49 | }, 50 | firstAndLastName(firstName, lastName){ 51 | return lastName + ", " + firstName 52 | }, 53 | toLowerCase(value){ 54 | return value.toLowerCase() 55 | }, 56 | capitalizeFirstLetter(string) { 57 | return string.charAt(0).toUpperCase() + string.slice(1); 58 | } 59 | } 60 | }); -------------------------------------------------------------------------------- /Chapter04/005-extracting-reusable-functionality-into-mixins-in-Vue/005.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 004-005 - Extracting reusable functionality into mixins in Vue 9 | 10 | 11 | 12 | 13 |
14 |
15 |

{{heading}}

16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Chapter04/005-extracting-reusable-functionality-into-mixins-in-Vue/005.js: -------------------------------------------------------------------------------- 1 | const primaryAlert = { 2 | template: ` 3 | `, 6 | methods: { 7 | viewportSizeOnClick(){ 8 | const width = window.innerWidth; 9 | const height = window.innerHeight; 10 | console.log("Viewport width:", width, "px, viewport height:", height, "px"); 11 | } 12 | } 13 | } 14 | const warningAlert = { 15 | template: ` 16 | `, 19 | methods: { 20 | viewportSizeOnClick(){ 21 | const width = window.innerWidth; 22 | const height = window.innerHeight; 23 | console.log("Viewport width:", width, "px, viewport height:", height, "px"); 24 | } 25 | } 26 | } 27 | new Vue({ 28 | el: '#app', 29 | data() { 30 | return { 31 | heading: 'Extracting reusable functionality into mixins in Vue' 32 | } 33 | }, 34 | components: { 35 | primaryAlert: primaryAlert, 36 | warningAlert: warningAlert 37 | } 38 | }) -------------------------------------------------------------------------------- /Chapter04/006-staying-dry-with-mixins/006.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 004-006 - Staying dry with mixins 9 | 10 | 11 | 12 | 13 |
14 |
15 |

{{heading}}

16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Chapter04/006-staying-dry-with-mixins/006.js: -------------------------------------------------------------------------------- 1 | const viewportSize = { 2 | methods: { 3 | viewportSizeOnClick(){ 4 | const width = window.innerWidth; 5 | const height = window.innerHeight; 6 | console.log("Viewport width:", width, "px, viewport height:", height, "px"); 7 | } 8 | } 9 | } 10 | const primaryAlert = { 11 | template: ` 12 | `, 15 | mixins: [viewportSize] 16 | } 17 | const warningAlert = { 18 | template: ` 19 | `, 22 | mixins: [viewportSize] 23 | } 24 | new Vue({ 25 | el: '#app', 26 | data() { 27 | return { 28 | heading: 'Extracting reusable functionality into mixins in Vue' 29 | } 30 | }, 31 | components: { 32 | primaryAlert: primaryAlert, 33 | warningAlert: warningAlert 34 | } 35 | }) -------------------------------------------------------------------------------- /Chapter04/007-updated-version-of-the-app/007.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 004-007 - Updated version of the app 9 | 10 | 11 | 12 | 13 |
14 |
15 |

{{heading}}

16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Chapter04/007-updated-version-of-the-app/007.js: -------------------------------------------------------------------------------- 1 | const viewportSize = { 2 | methods: { 3 | logOutViewportSize(){ 4 | const width = window.innerWidth; 5 | const height = window.innerHeight; 6 | console.log("Viewport width:", width, "px, viewport height:", height, "px"); 7 | }, 8 | alertViewPortSize() { 9 | const width = window.innerWidth; 10 | const height = window.innerHeight; 11 | alert("Viewport width: " + width + " px, viewport height: " + height + " px"); 12 | } 13 | } 14 | } 15 | const primaryAlert = { 16 | template: ` 17 | `, 20 | mixins: [viewportSize] 21 | } 22 | const warningAlert = { 23 | template: ` 24 | `, 27 | mixins: [viewportSize] 28 | } 29 | new Vue({ 30 | el: '#app', 31 | data() { 32 | return { 33 | heading: 'Extracting reusable functionality into mixins in Vue' 34 | } 35 | }, 36 | components: { 37 | primaryAlert: primaryAlert, 38 | warningAlert: warningAlert 39 | } 40 | }) -------------------------------------------------------------------------------- /Chapter04/008-refactoring-our-viewport-size-mixin/008.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 004-008 - Refactoring our viewport size mixin 9 | 10 | 11 | 12 | 13 |
14 |
15 |

{{heading}}

16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Chapter04/008-refactoring-our-viewport-size-mixin/008.js: -------------------------------------------------------------------------------- 1 | const viewportSize = { 2 | data(){ 3 | return { 4 | viewport: { 5 | width: 0, 6 | height: 0 7 | } 8 | } 9 | }, 10 | methods: { 11 | getViewportSize(){ 12 | this.viewport.width = window.innerWidth; 13 | this.viewport.height = window.innerHeight; 14 | }, 15 | logOutViewportSize(){ 16 | console.log("Viewport width:", this.viewport.width, "px, viewport height:", this.viewport.height, "px"); 17 | }, 18 | alertViewPortSize() { 19 | alert("Viewport width: " + this.viewport.width + " px, viewport height: " + this.viewport.height + " px"); 20 | } 21 | }, 22 | created() { 23 | this.listener = window.addEventListener('mousemove', this.getViewportSize); 24 | this.getViewportSize(); 25 | } 26 | } 27 | const primaryAlert = { 28 | template: ` 29 | `, 32 | mixins: [viewportSize] 33 | } 34 | const warningAlert = { 35 | template: ` 36 | `, 39 | mixins: [viewportSize] 40 | } 41 | new Vue({ 42 | el: '#app', 43 | data() { 44 | return { 45 | heading: 'Extracting reusable functionality into mixins in Vue' 46 | } 47 | }, 48 | components: { 49 | primaryAlert: primaryAlert, 50 | warningAlert: warningAlert 51 | } 52 | }) -------------------------------------------------------------------------------- /Chapter05/001-a-simple-custom-directive/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A simple custom directive 6 | 7 | 8 | 9 |
10 |

{{ heading }}

11 |
12 | Just some text here 13 |
14 |
15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Chapter05/001-a-simple-custom-directive/js/index.js: -------------------------------------------------------------------------------- 1 | Vue.directive('customDirective', { 2 | inserted: function(el) { 3 | el.style.cssText = ` 4 | color: blue; 5 | border: 1px solid black; 6 | background: gray; 7 | padding: 20px; 8 | width: 50%; 9 | ` 10 | } 11 | }); 12 | 13 | new Vue({ 14 | el: '#app', 15 | data() { 16 | return { 17 | heading: 'A custom global directive' 18 | } 19 | } 20 | }); -------------------------------------------------------------------------------- /Chapter05/002-simple-custom-local-directive/css/style.css: -------------------------------------------------------------------------------- 1 | article { 2 | font-size: 40px; 3 | padding: 20px; 4 | color: limegreen; 5 | font-family: Arial; 6 | border: 3px solid green; 7 | border-radius: 10px; 8 | } -------------------------------------------------------------------------------- /Chapter05/002-simple-custom-local-directive/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Simple custom local directive 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Chapter05/002-simple-custom-local-directive/js/index.js: -------------------------------------------------------------------------------- 1 | const anotherCustom = { 2 | inserted: function(el) { 3 | el.style.cssText = ` 4 | color: green; 5 | border: 1px solid black; 6 | background: yellow; 7 | padding: 20px; 8 | width: 50%; 9 | ` 10 | } 11 | } 12 | const customArticle = { 13 | template: ` 14 |
15 | Our own custom article component! 16 |
` 17 | } 18 | Vue.component('another-custom-article', { 19 | template: ` 20 |
21 | Another custom article component! 22 | This one has it's own child component too! 23 | Here it is: 24 | 25 |
`, 26 | components: { 27 | 'customArticle': customArticle 28 | }, 29 | directives: { 30 | customDirective: { 31 | inserted: function(el) { 32 | el.style.cssText = ` 33 | color: blue; 34 | border: 1px solid black; 35 | background: gray; 36 | padding: 20px; 37 | width: 50%; 38 | ` 39 | } 40 | } 41 | } 42 | }) 43 | new Vue({ 44 | el: '#app', 45 | components: { 46 | 'customArticle': customArticle, 47 | }, 48 | directives: { 49 | customDirective: { 50 | inserted: function(el) { 51 | el.style.cssText = ` 52 | color: blue; 53 | border: 1px solid black; 54 | background: gray; 55 | padding: 20px; 56 | width: 50%; 57 | ` 58 | } 59 | }, 60 | 'anotherCustom': anotherCustom 61 | } 62 | }) -------------------------------------------------------------------------------- /Chapter05/003-passing-values-to-custom-directives/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Passing values to custom directives 6 | 7 | 8 | 9 |
10 |

{{ heading }}

11 | 14 | 17 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Chapter05/003-passing-values-to-custom-directives/js/index.js: -------------------------------------------------------------------------------- 1 | Vue.directive('buttonize', { 2 | bind(el, binding) { 3 | var exp = binding.expression; 4 | el.style.cssText += ` 5 | padding: 10px 20px; 6 | border: none; 7 | border-radius: 3px; 8 | cursor: pointer 9 | `; 10 | switch(exp) { 11 | case 'tomato': 12 | el.style.cssText += ` 13 | background: tomato; 14 | color: white; 15 | `; 16 | break; 17 | case 'lightgoldenrod': 18 | el.style.cssText += ` 19 | background: darkgoldenrod; 20 | color: lightgoldenrod; 21 | `; 22 | break; 23 | default: 24 | el.style.cssText += ` 25 | background: gray; 26 | color: white; 27 | ` 28 | } 29 | } 30 | }); 31 | 32 | new Vue({ 33 | el: '#app', 34 | data() { 35 | return { 36 | heading: 'A custom global directive' 37 | } 38 | } 39 | }); -------------------------------------------------------------------------------- /Chapter06/001-change-of-background-no-css-transition/css/style.css: -------------------------------------------------------------------------------- 1 | button { 2 | background-color: red; 3 | } 4 | button:hover { 5 | background-color: blue; 6 | } 7 | 8 | /* some additional styling */ 9 | * { 10 | border: none; 11 | color: white; 12 | padding: 10px; 13 | font-size: 18px; 14 | font-weight: 600; 15 | } -------------------------------------------------------------------------------- /Chapter06/001-change-of-background-no-css-transition/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Change of background, no CSS transition 6 | 7 | 8 | 9 |
    10 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Chapter06/002-change-of-background-with-css-transition/css/style.css: -------------------------------------------------------------------------------- 1 | button { 2 | background-color: red; 3 | transition: background-color 4s; 4 | } 5 | button:hover { 6 | background-color: blue; 7 | } 8 | 9 | /* some additional styling */ 10 | * { 11 | border: none; 12 | color: white; 13 | padding: 10px; 14 | font-size: 18px; 15 | font-weight: 600; 16 | } -------------------------------------------------------------------------------- /Chapter06/002-change-of-background-with-css-transition/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Change of background, with CSS transition 6 | 7 | 8 | 9 |
    10 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Chapter06/003-change-of-background-with-css-animation/css/style.css: -------------------------------------------------------------------------------- 1 | button { 2 | background-color: red; 3 | } 4 | 5 | button:hover { 6 | animation: change-color 4s; 7 | } 8 | 9 | @keyframes change-color { 10 | 0% { 11 | background: red; 12 | } 13 | 100% { 14 | background: blue; 15 | } 16 | } 17 | 18 | /* some additional styling */ 19 | * { 20 | border: none; 21 | color: white; 22 | padding: 10px; 23 | font-size: 18px; 24 | font-weight: 600; 25 | } -------------------------------------------------------------------------------- /Chapter06/003-change-of-background-with-css-animation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 163 - change of background, with CSS animation 6 | 7 | 8 | 9 |
    10 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Chapter06/004-change-of-background-with-css-animation-multistep/css/style.css: -------------------------------------------------------------------------------- 1 | button { 2 | background-color: red; 3 | } 4 | 5 | button:hover { 6 | animation: change-color 4s; 7 | } 8 | 9 | @keyframes change-color { 10 | 0% { 11 | background: red; 12 | } 13 | 50% { 14 | background: green; 15 | } 16 | 100% { 17 | background: blue; 18 | } 19 | } 20 | 21 | /* some additional styling */ 22 | * { 23 | border: none; 24 | color: white; 25 | padding: 10px; 26 | font-size: 18px; 27 | font-weight: 600; 28 | } -------------------------------------------------------------------------------- /Chapter06/004-change-of-background-with-css-animation-multistep/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Change of background, with CSS animation 6 | 7 | 8 | 9 |
    10 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Chapter06/005-css-transitions-in-vue/css/style.css: -------------------------------------------------------------------------------- 1 | button { 2 | background-color: red; 3 | transition: background-color 4s; 4 | } 5 | button:hover { 6 | background-color: blue; 7 | } 8 | /* some additional styling */ 9 | * { 10 | border: none; 11 | color: white; 12 | padding: 10px; 13 | font-size: 18px; 14 | font-weight: 600; 15 | } -------------------------------------------------------------------------------- /Chapter06/005-css-transitions-in-vue/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CSS transitions in Vue 6 | 7 | 8 | 9 |
10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Chapter06/005-css-transitions-in-vue/js/index.js: -------------------------------------------------------------------------------- 1 | Vue.component('customComponent', { 2 | template: ` 3 | 4 | ` 5 | }); 6 | new Vue({ 7 | el: '#app' 8 | }); -------------------------------------------------------------------------------- /Chapter06/006-using-transition-element-in-vue/css/style.css: -------------------------------------------------------------------------------- 1 | button { 2 | background-color: red; 3 | transition: background-color 4s; 4 | } 5 | button:hover { 6 | background-color: blue; 7 | } 8 | /* some additional styling */ 9 | * { 10 | border: none; 11 | color: white; 12 | padding: 10px; 13 | font-size: 18px; 14 | font-weight: 600; 15 | } -------------------------------------------------------------------------------- /Chapter06/006-using-transition-element-in-vue/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Using transition element in Vue 6 | 7 | 8 | 9 |
10 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter06/006-using-transition-element-in-vue/js/index.js: -------------------------------------------------------------------------------- 1 | Vue.component('customComponent', { 2 | template: ` 3 | 4 | ` 5 | }); 6 | new Vue({ 7 | el: '#app', 8 | data: { 9 | show: true 10 | } 11 | }); -------------------------------------------------------------------------------- /Chapter06/007-using-transition-element-in-vue-with-animation-hooks-enter/css/style.css: -------------------------------------------------------------------------------- 1 | .v-enter { 2 | opacity: 0; 3 | } 4 | .v-enter-active { 5 | transition: opacity 3s; 6 | } 7 | 8 | button { 9 | background-color: red; 10 | transition: background-color 4s; 11 | } 12 | button:hover { 13 | background-color: blue; 14 | } 15 | /* some additional styling */ 16 | * { 17 | border: none; 18 | color: white; 19 | padding: 10px; 20 | font-size: 18px; 21 | font-weight: 600; 22 | } -------------------------------------------------------------------------------- /Chapter06/007-using-transition-element-in-vue-with-animation-hooks-enter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Using transition element in Vue with animation hooks - setting up the enter transition 6 | 7 | 8 | 9 |
10 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Chapter06/007-using-transition-element-in-vue-with-animation-hooks-enter/js/index.js: -------------------------------------------------------------------------------- 1 | Vue.component('customComponent', { 2 | template: ` 3 | 4 | ` 5 | }); 6 | new Vue({ 7 | el: '#app', 8 | data: { 9 | show: true 10 | } 11 | }); -------------------------------------------------------------------------------- /Chapter06/008-using-transition-element-in-vue-with-animation-hooks-leave/css/style.css: -------------------------------------------------------------------------------- 1 | .v-leave { 2 | opacity: 1; 3 | } 4 | .v-leave-active { 5 | transition: opacity 3s; 6 | } 7 | .v-leave-to { 8 | opacity: 0; 9 | } 10 | 11 | .v-enter-active { 12 | transition: opacity 3s; 13 | } 14 | .v-enter { 15 | opacity: 0; 16 | } 17 | 18 | button { 19 | background-color: red; 20 | transition: background-color 4s; 21 | } 22 | button:hover { 23 | background-color: blue; 24 | } 25 | /* some additional styling */ 26 | * { 27 | border: none; 28 | color: white; 29 | padding: 10px; 30 | font-size: 18px; 31 | font-weight: 600; 32 | } -------------------------------------------------------------------------------- /Chapter06/008-using-transition-element-in-vue-with-animation-hooks-leave/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Using transition element in Vue with animation hooks 6 | 7 | 8 | 9 |
10 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Chapter06/008-using-transition-element-in-vue-with-animation-hooks-leave/js/index.js: -------------------------------------------------------------------------------- 1 | Vue.component('customComponent', { 2 | template: ` 3 | 4 | ` 5 | }); 6 | new Vue({ 7 | el: '#app', 8 | data: { 9 | show: true 10 | } 11 | }); -------------------------------------------------------------------------------- /Chapter06/009-animation-hooks-in-vue-pt2/css/style.css: -------------------------------------------------------------------------------- 1 | .v-enter, .v-leave-to { 2 | opacity: 0; 3 | } 4 | .v-enter-active, .v-leave-active { 5 | transition: opacity 3s; 6 | } 7 | .v-enter-to, .v-leave { 8 | opacity: 1; 9 | } 10 | 11 | /* other styles */ 12 | button { 13 | background-color: red; 14 | transition: background-color 4s; 15 | } 16 | button:hover { 17 | background-color: blue; 18 | } 19 | /* some additional styling */ 20 | * { 21 | border: none; 22 | color: white; 23 | padding: 10px; 24 | font-size: 18px; 25 | font-weight: 600; 26 | } -------------------------------------------------------------------------------- /Chapter06/009-animation-hooks-in-vue-pt2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Animation hooks in Vue, pt2 6 | 7 | 8 | 9 |
10 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Chapter06/009-animation-hooks-in-vue-pt2/js/index.js: -------------------------------------------------------------------------------- 1 | Vue.component('customComponent', { 2 | template: ` 3 | 4 | ` 5 | }); 6 | new Vue({ 7 | el: '#app', 8 | data: { 9 | show: false 10 | } 11 | }); -------------------------------------------------------------------------------- /Chapter06/010-animation-hooks-with-named-transitions/css/style.css: -------------------------------------------------------------------------------- 1 | /* 'named' transition */ 2 | .named-enter, .named-leave-to { 3 | opacity: 0; 4 | } 5 | .named-enter-active, .named-leave-active { 6 | transition: opacity 3s; 7 | } 8 | .named-enter-to, .named-leave { 9 | opacity: 1; 10 | } 11 | 12 | /* other styles */ 13 | button { 14 | background-color: red; 15 | transition: background-color 4s; 16 | } 17 | button:hover { 18 | background-color: blue; 19 | } 20 | /* some additional styling */ 21 | * { 22 | border: none; 23 | color: white; 24 | padding: 10px; 25 | font-size: 18px; 26 | font-weight: 600; 27 | } -------------------------------------------------------------------------------- /Chapter06/010-animation-hooks-with-named-transitions/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Animation hooks with named transitions 6 | 7 | 8 | 9 |
10 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter06/010-animation-hooks-with-named-transitions/js/index.js: -------------------------------------------------------------------------------- 1 | Vue.component('customComponent', { 2 | template: ` 3 | 4 | ` 5 | }); 6 | new Vue({ 7 | el: '#app', 8 | data: { 9 | show: false 10 | } 11 | }); -------------------------------------------------------------------------------- /Chapter06/011-css-animations-in-vue-transitions/css/style.css: -------------------------------------------------------------------------------- 1 | /* 'named' transition is replaced with 'converted' animation */ 2 | .converted-enter-active { 3 | animation: converted .5s; 4 | } 5 | .converted-leave-active { 6 | animation: converted .5s reverse; 7 | } 8 | @keyframes converted { 9 | 0% { 10 | opacity: 0; 11 | } 12 | 35% { 13 | background-color: purple; 14 | } 15 | 65% { 16 | background-color: green; 17 | } 18 | 100% { 19 | opacity: 1; 20 | } 21 | } 22 | /* 23 | .named-enter-to, .named-leave { 24 | opacity: 1; 25 | } 26 | */ 27 | 28 | /* other styles */ 29 | button { 30 | background-color: red; 31 | transition: background-color 4s; 32 | } 33 | button:hover { 34 | background-color: blue; 35 | } 36 | /* some additional styling */ 37 | * { 38 | border: none; 39 | color: white; 40 | padding: 10px; 41 | font-size: 18px; 42 | font-weight: 600; 43 | } 44 | span { 45 | display: inline-block; 46 | } -------------------------------------------------------------------------------- /Chapter06/011-css-animations-in-vue-transitions/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CSS animations in Vue transitions 6 | 7 | 8 | 9 |
10 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Chapter06/011-css-animations-in-vue-transitions/js/index.js: -------------------------------------------------------------------------------- 1 | Vue.component('customComponent', { 2 | template: ` 3 | 4 | ` 5 | }); 6 | new Vue({ 7 | el: '#app', 8 | data: { 9 | show: false 10 | } 11 | }); -------------------------------------------------------------------------------- /Chapter06/012-custom-transition-classes-in-vue/css/style.css: -------------------------------------------------------------------------------- 1 | /* CSS classes used are imported from the Animate CSS library 2 | and can be found in Settings of this pen */ 3 | /* other styles */ 4 | button { 5 | background-color: red; 6 | transition: background-color 4s; 7 | } 8 | button:hover { 9 | background-color: blue; 10 | } 11 | 12 | * { 13 | border: none; 14 | color: white; 15 | padding: 10px; 16 | font-size: 18px; 17 | font-weight: 600; 18 | } 19 | * { overflow: hidden } -------------------------------------------------------------------------------- /Chapter06/012-custom-transition-classes-in-vue/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Custom Transition Classes in Vue 6 | 7 | 8 | 9 | 10 | 11 |
12 | 15 | 19 |
20 | 21 | 22 |
23 |
24 |
25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Chapter06/012-custom-transition-classes-in-vue/js/index.js: -------------------------------------------------------------------------------- 1 | Vue.component('customComponent', { 2 | template: ` 3 | 4 | ` 5 | }); 6 | new Vue({ 7 | el: '#app', 8 | data: { 9 | show: false 10 | } 11 | }); -------------------------------------------------------------------------------- /Chapter06/013-transition-modes-in-vue-2/css/style.css: -------------------------------------------------------------------------------- 1 | /* CSS classes used are imported from the Animate CSS library 2 | and can be found in Settings of this pen */ 3 | /* other styles */ 4 | .smooth-enter, .smooth-leave-to { 5 | opacity: 0; 6 | } 7 | .smooth-enter-active, .smooth-leave-active { 8 | transition: opacity .5s; 9 | } 10 | .smooth-enter-to, .smooth-leave { 11 | opacity: 1; 12 | } 13 | 14 | button { 15 | background-color: red; 16 | transition: background-color 4s; 17 | } 18 | button:hover { 19 | background-color: blue; 20 | } 21 | 22 | * { 23 | border: none; 24 | color: white; 25 | padding: 10px; 26 | font-size: 18px; 27 | font-weight: 600; 28 | } 29 | * { overflow: hidden } -------------------------------------------------------------------------------- /Chapter06/013-transition-modes-in-vue-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Transition modes in Vue 2 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 18 | 23 | 24 | 27 |
28 | 29 | 30 |
31 |
32 |
33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Chapter06/013-transition-modes-in-vue-2/js/index.js: -------------------------------------------------------------------------------- 1 | Vue.component('customComponent', { 2 | template: ` 3 | 4 | ` 5 | }); 6 | new Vue({ 7 | el: '#app', 8 | data: { 9 | show: false 10 | } 11 | }); -------------------------------------------------------------------------------- /Chapter06/014-binding-css-classes/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Binding CSS classes 6 | 7 | 8 | 9 |
10 |

Binding CSS classes

11 |

Click the button below a few times

12 | 13 |
14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Chapter06/014-binding-css-classes/js/index.js: -------------------------------------------------------------------------------- 1 | new Vue({ 2 | el: '#app', 3 | data() { 4 | return { 5 | btnClicked: false, 6 | } 7 | } 8 | }) -------------------------------------------------------------------------------- /Chapter06/015-improving-dynamic-css-classes-example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Improving dynamic CSS classes example 6 | 7 | 8 | 9 |
10 |

Improving dynamic CSS classes example

11 |

Click the button below a few times

12 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter06/015-improving-dynamic-css-classes-example/js/index.js: -------------------------------------------------------------------------------- 1 | new Vue({ 2 | el: '#app', 3 | data() { 4 | return { 5 | btnClicked: false, 6 | btnPrimary: 'btn btn-lg btn-primary', 7 | btnSecondary: 'btn btn-lg btn-secondary' 8 | } 9 | } 10 | }) -------------------------------------------------------------------------------- /Chapter06/016-improving-dynamic-css-classes-example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Improving dynamic CSS classes example 6 | 7 | 8 | 9 | 10 |
11 |

Improving dynamic CSS classes example

12 |

Click the button below a few times

13 | 18 |
19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter06/016-improving-dynamic-css-classes-example/js/index.js: -------------------------------------------------------------------------------- 1 | new Vue({ 2 | el: '#app', 3 | data() { 4 | return { 5 | btnClicked: false, 6 | btnPrimary: 'btn btn-lg btn-primary bounce animated', 7 | btnSecondary: 'btn btn-lg btn-secondary tada animated' 8 | } 9 | } 10 | }) -------------------------------------------------------------------------------- /Chapter06/017-transition-groups-in-vue-2/css/style.css: -------------------------------------------------------------------------------- 1 | button.bare { 2 | font-size: 30px; 3 | background: white; 4 | border: none; 5 | margin: 0 20px; 6 | } 7 | button:focus.bare, button:focus.fa { 8 | outline: 0; 9 | } 10 | button.fa { 11 | cursor: pointer; 12 | color: white; 13 | padding: 20px; 14 | border-radius: 50%; 15 | font-size: 30px; 16 | border: none; 17 | } 18 | .orange { 19 | background: orange; 20 | } 21 | 22 | /* animation hooks */ 23 | .v-enter, 24 | .v-leave-to{ 25 | opacity: 0; 26 | transform: translate(1000px, 500px); 27 | } 28 | .v-enter-active, 29 | .v-leave-active { 30 | transition: opacity 5s, transform 1s 31 | } -------------------------------------------------------------------------------- /Chapter06/017-transition-groups-in-vue-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Transition groups in Vue 2 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 | 15 | 21 | 26 | 27 |
28 |
29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Chapter06/017-transition-groups-in-vue-2/js/index.js: -------------------------------------------------------------------------------- 1 | new Vue({ 2 | el: "#app", 3 | data: { 4 | clapCount: false 5 | }, 6 | methods: { 7 | aClap() { 8 | var target = document.querySelector('.fa-thumbs-o-up'); 9 | if (!target.classList.contains('wobble')) { 10 | target.classList.add('wobble'); 11 | } 12 | setTimeout(function() { 13 | target.classList.remove('wobble')}, 300 14 | ) 15 | if (this.clapCount < 10) { 16 | this.clapCount++ 17 | } else { 18 | target.classList.remove('orange','wobble') 19 | } 20 | } 21 | } 22 | }); -------------------------------------------------------------------------------- /Chapter06/018-transition-groups-with-js-animation-hooks/css/style.css: -------------------------------------------------------------------------------- 1 | button.bare { 2 | font-size: 30px; 3 | background: white; 4 | border: none; 5 | margin: 0 20px; 6 | } 7 | button:focus.bare, button:focus.fa { 8 | outline: 0; 9 | } 10 | button.fa { 11 | cursor: pointer; 12 | color: white; 13 | padding: 20px; 14 | border-radius: 50%; 15 | font-size: 30px; 16 | border: none; 17 | } 18 | .orange { 19 | background: orange; 20 | } 21 | 22 | /* animation hooks 23 | .v-enter, 24 | .v-leave-to{ 25 | opacity: 0; 26 | transform: translate(1000px, 500px); 27 | } 28 | .v-enter-active, 29 | .v-leave-active { 30 | transition: opacity 5s, transform 1s 31 | } 32 | */ -------------------------------------------------------------------------------- /Chapter06/018-transition-groups-with-js-animation-hooks/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Transition groups with JS animation hooks 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 | 23 | 29 | 34 | 35 |
36 |
37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Chapter06/018-transition-groups-with-js-animation-hooks/js/index.js: -------------------------------------------------------------------------------- 1 | new Vue({ 2 | el: "#app", 3 | data: { 4 | clapCount: false 5 | }, 6 | methods: { 7 | beforeEnter: function(el) { 8 | el.style.opacity = 0 9 | }, 10 | enter: function (el, done) { 11 | Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 }) 12 | Velocity(el, { fontSize: '1em' }, { complete: done }) 13 | }, 14 | leave: function (el, done) { 15 | Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 }) 16 | Velocity(el, { rotateZ: '100deg' }, { loop: 2 }) 17 | Velocity(el, { 18 | rotateZ: '45deg', 19 | translateY: '30px', 20 | translateX: '30px', 21 | opacity: 0 22 | }, { complete: done })}, 23 | aClap() { 24 | var target = document.querySelector('.fa-thumbs-o-up'); 25 | if (!target.classList.contains('wobble')) { 26 | target.classList.add('wobble'); 27 | } 28 | setTimeout(function() { 29 | target.classList.remove('wobble')}, 300 30 | ) 31 | if (this.clapCount < 10) { 32 | this.clapCount++ 33 | } else { 34 | target.classList.remove('orange','wobble') 35 | } 36 | } 37 | } 38 | }); -------------------------------------------------------------------------------- /Chapter07/001-a-very-basic-vuex-app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A very basic vuex app 6 | 7 | 8 | 9 | 10 | 11 |
12 |

Fruit to eat: {{count}}

13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter07/001-a-very-basic-vuex-app/js/index.js: -------------------------------------------------------------------------------- 1 | const store = new Vuex.Store({ 2 | state: { 3 | count: 5 4 | }, 5 | getters: { 6 | counter(state) { 7 | return state.count; 8 | } 9 | }, 10 | mutations: { 11 | decrementCounter(state, payload) { 12 | state.count = state.count - payload; 13 | state.count < 0 ? (state.count = 0) : state.count; 14 | }, 15 | resetCounter(state) { 16 | state.count = 5; 17 | } 18 | }, 19 | actions: { 20 | decrement(state, payload) { 21 | state.commit("decrementCounter", payload); 22 | }, 23 | reset(state) { 24 | state.commit("resetCounter"); 25 | } 26 | } 27 | }); 28 | 29 | const app = new Vue({ 30 | el: "#app", 31 | store: store, 32 | computed: { 33 | count() { 34 | return store.getters.counter; 35 | } 36 | }, 37 | methods: { 38 | eatFruit(amount) { 39 | store.dispatch("decrement", amount); 40 | }, 41 | counterReset() { 42 | store.dispatch("reset"); 43 | } 44 | } 45 | }); -------------------------------------------------------------------------------- /Chapter07/002-extending-the-fruit-counter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Extending the fruit counter 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

Fruit to eat: {{ count }}

14 |

Eaten: {{ apples }} apples, {{ pears }} pears

15 | 18 | 21 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Chapter07/002-extending-the-fruit-counter/js/index.js: -------------------------------------------------------------------------------- 1 | const store = new Vuex.Store({ 2 | state: { 3 | count: 5, 4 | apples: 0, 5 | pears: 0 6 | }, 7 | getters: { 8 | counter(state) { 9 | return state.count; 10 | }, 11 | appleCount(state) { 12 | return state.apples; 13 | }, 14 | pearCount(state) { 15 | return state.pears; 16 | } 17 | }, 18 | mutations: { 19 | decrementWithApplesCounter(state, payload) { 20 | state.count = state.count - 1; 21 | state.count < 0 ? (state.count = 0) : (state.count, state.apples += 1); 22 | }, 23 | decrementWithPearsCounter(state, payload) { 24 | state.count = state.count - 1; 25 | state.count < 0 ? (state.count = 0) : (state.count, state.pears += 1); 26 | }, 27 | resetCounter(state) { 28 | state.count = 5; 29 | state.apples = 0; 30 | state.pears = 0; 31 | } 32 | }, 33 | actions: { 34 | decrementWithApples(state, payload) { 35 | setTimeout(() => { 36 | state.commit("decrementWithApplesCounter", payload); 37 | }, 1000) 38 | }, 39 | decrementWithPears(state, payload) { 40 | state.commit("decrementWithPearsCounter", payload); 41 | }, 42 | reset(state) { 43 | state.commit("resetCounter"); 44 | } 45 | } 46 | }); 47 | 48 | const app = new Vue({ 49 | el: "#app", 50 | store: store, 51 | computed: { 52 | count() { 53 | return store.getters.counter; 54 | }, 55 | apples() { 56 | return store.getters.appleCount; 57 | }, 58 | pears() { 59 | return store.getters.pearCount; 60 | } 61 | }, 62 | methods: { 63 | eatApples(payload) { 64 | store.dispatch("decrementWithApples", payload); 65 | }, 66 | eatPears(payload) { 67 | store.dispatch("decrementWithPears", payload); 68 | }, 69 | counterReset() { 70 | store.dispatch("reset"); 71 | } 72 | } 73 | }); -------------------------------------------------------------------------------- /Chapter08/.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_size = 2 6 | indent_style = space 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /Chapter08/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | node: true 6 | }, 7 | parserOptions: { 8 | parser: 'babel-eslint' 9 | }, 10 | extends: [ 11 | // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention 12 | // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules. 13 | 'plugin:vue/essential' 14 | ], 15 | // required to lint *.vue files 16 | plugins: [ 17 | 'vue' 18 | ], 19 | // add your custom rules here 20 | rules: {} 21 | } 22 | -------------------------------------------------------------------------------- /Chapter08/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | 4 | # logs 5 | npm-debug.log 6 | 7 | # Nuxt build 8 | .nuxt 9 | 10 | # Nuxt generate 11 | dist 12 | -------------------------------------------------------------------------------- /Chapter08/README.md: -------------------------------------------------------------------------------- 1 | # chapter8 2 | 3 | > Nuxt.js project 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | $ npm install # Or yarn install 10 | 11 | # serve with hot reload at localhost:3000 12 | $ npm run dev 13 | 14 | # build for production and launch server 15 | $ npm run build 16 | $ npm start 17 | 18 | # generate static project 19 | $ npm run generate 20 | ``` 21 | 22 | For detailed explanation on how things work, checkout the [Nuxt.js docs](https://github.com/nuxt/nuxt.js). 23 | 24 | -------------------------------------------------------------------------------- /Chapter08/assets/README.md: -------------------------------------------------------------------------------- 1 | # ASSETS 2 | 3 | This directory contains your un-compiled assets such as LESS, SASS, or JavaScript. 4 | 5 | More information about the usage of this directory in the documentation: 6 | https://nuxtjs.org/guide/assets#webpacked 7 | 8 | **This directory is not required, you can delete it if you don't want to use it.** 9 | 10 | -------------------------------------------------------------------------------- /Chapter08/components/AppLogo.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 80 | 81 | -------------------------------------------------------------------------------- /Chapter08/components/Navigation.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /Chapter08/components/README.md: -------------------------------------------------------------------------------- 1 | # COMPONENTS 2 | 3 | The components directory contains your Vue.js Components. 4 | Nuxt.js doesn't supercharge these components. 5 | 6 | **This directory is not required, you can delete it if you don't want to use it.** 7 | 8 | -------------------------------------------------------------------------------- /Chapter08/layouts/README.md: -------------------------------------------------------------------------------- 1 | # LAYOUTS 2 | 3 | This directory contains your Application Layouts. 4 | 5 | More information about the usage of this directory in the documentation: 6 | https://nuxtjs.org/guide/views#layouts 7 | 8 | **This directory is not required, you can delete it if you don't want to use it.** 9 | 10 | -------------------------------------------------------------------------------- /Chapter08/layouts/default.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 16 | 17 | -------------------------------------------------------------------------------- /Chapter08/middleware/README.md: -------------------------------------------------------------------------------- 1 | # MIDDLEWARE 2 | 3 | This directory contains your Application Middleware. 4 | The middleware lets you define custom function to be ran before rendering a page or a group of pages (layouts). 5 | 6 | More information about the usage of this directory in the documentation: 7 | https://nuxtjs.org/guide/routing#middleware 8 | 9 | **This directory is not required, you can delete it if you don't want to use it.** 10 | 11 | -------------------------------------------------------------------------------- /Chapter08/nuxt.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | /* 3 | ** Headers of the page 4 | */ 5 | head: { 6 | title: 'chapter8', 7 | meta: [ 8 | { charset: 'utf-8' }, 9 | { name: 'viewport', content: 'width=device-width, initial-scale=1' }, 10 | { hid: 'description', name: 'description', content: 'Nuxt.js project' } 11 | ], 12 | link: [ 13 | { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' } 14 | ] 15 | }, 16 | /* 17 | ** Customize the progress bar color 18 | */ 19 | loading: { color: '#3B8070' }, 20 | /* 21 | ** Build configuration 22 | */ 23 | build: { 24 | /* 25 | ** Run ESLint on save 26 | */ 27 | /* 28 | extend (config, { isDev, isClient }) { 29 | if (isDev && isClient) { 30 | config.module.rules.push({ 31 | enforce: 'pre', 32 | test: /\.(js|vue)$/, 33 | loader: 'eslint-loader', 34 | exclude: /(node_modules)/ 35 | }) 36 | } 37 | } 38 | */ 39 | extend(config) { 40 | if (process.server && process.browser) { 41 | config.module.rules.push({ 42 | enforce: 'pre', 43 | test: /\.(js|vue)$/, 44 | loader: 'eslint-loader', 45 | exclude: /(node_modules)/ 46 | }) 47 | } 48 | } 49 | } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Chapter08/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter8", 3 | "version": "1.0.0", 4 | "description": "Nuxt.js project", 5 | "author": "ImsirovicAjdin <***@live.com>", 6 | "private": true, 7 | "scripts": { 8 | "dev": "nuxt", 9 | "build": "nuxt build", 10 | "start": "nuxt start", 11 | "generate": "nuxt generate", 12 | "lint": "eslint --ext .js,.vue --ignore-path .gitignore .", 13 | "precommit": "npm run lint" 14 | }, 15 | "dependencies": { 16 | "nuxt": "^2.0.0" 17 | }, 18 | "devDependencies": { 19 | "babel-eslint": "^8.2.1", 20 | "eslint": "^4.15.0", 21 | "eslint-friendly-formatter": "^3.0.0", 22 | "eslint-loader": "^1.7.1", 23 | "eslint-plugin-vue": "^4.0.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Chapter08/pages/README.md: -------------------------------------------------------------------------------- 1 | # PAGES 2 | 3 | This directory contains your Application Views and Routes. 4 | The framework reads all the .vue files inside this directory and creates the router of your application. 5 | 6 | More information about the usage of this directory in the documentation: 7 | https://nuxtjs.org/guide/routing 8 | 9 | -------------------------------------------------------------------------------- /Chapter08/pages/contact.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter08/pages/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 27 | 28 | 65 | 66 | -------------------------------------------------------------------------------- /Chapter08/pages/news.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 23 | 24 | -------------------------------------------------------------------------------- /Chapter08/plugins/README.md: -------------------------------------------------------------------------------- 1 | # PLUGINS 2 | 3 | This directory contains your Javascript plugins that you want to run before instantiating the root vue.js application. 4 | 5 | More information about the usage of this directory in the documentation: 6 | https://nuxtjs.org/guide/plugins 7 | 8 | **This directory is not required, you can delete it if you don't want to use it.** 9 | 10 | -------------------------------------------------------------------------------- /Chapter08/static/README.md: -------------------------------------------------------------------------------- 1 | # STATIC 2 | 3 | This directory contains your static files. 4 | Each file inside this directory is mapped to /. 5 | 6 | Example: /static/robots.txt is mapped as /robots.txt. 7 | 8 | More information about the usage of this directory in the documentation: 9 | https://nuxtjs.org/guide/assets#static 10 | 11 | **This directory is not required, you can delete it if you don't want to use it.** 12 | 13 | -------------------------------------------------------------------------------- /Chapter08/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-Quick-Start-Guide/5d1cff154f12dd38b050e10c6c24d3c991b2d2f8/Chapter08/static/favicon.ico -------------------------------------------------------------------------------- /Chapter08/store/README.md: -------------------------------------------------------------------------------- 1 | # STORE 2 | 3 | This directory contains your Vuex Store files. 4 | Vuex Store option is implemented in the Nuxt.js framework. 5 | Creating a index.js file in this directory activate the option in the framework automatically. 6 | 7 | More information about the usage of this directory in the documentation: 8 | https://nuxtjs.org/guide/vuex-store 9 | 10 | **This directory is not required, you can delete it if you don't want to use it.** 11 | 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # Vue.js-Quick-Start-Guide 5 | Vue.js Quick Start Guide, published by Packt 6 | 7 | Vue.js Quick Start Guide 8 | 9 | This is the code repository for [Vue.js Quick Start Guide](https://www.packtpub.com/application-development/vuejs-quick-start-guide?utm_source=github&utm_medium=repository&utm_campaign=9781789344103), published by Packt. 10 | 11 | **Learn how to build amazing and complex reactive web applications easily using Vue.js** 12 | 13 | ## What is this book about? 14 | Vue.js is the latest trending frontend framework. Simplicity, reactivity, and flexibility are some of the key benefits that Vue offers to developers. This book will help you learn everything you need to know to build stunning reactive web apps with Vue.js 2 quickly and easily. 15 | 16 | This book covers the following exciting features: 17 | * Develop apps with Vue.js 18 | * Reuse components using slots 19 | * Use filters, mixins, and global mixins in Vue 20 | * Build custom directives in Vue 21 | * Work with CSS animations 22 | 23 | If you feel this book is for you, get your [copy](https://www.amazon.com/dp/1789344107) today! 24 | 25 | https://www.packtpub.com/ 27 | 28 | 29 | ## Instructions and Navigations 30 | All of the code is organized into folders. For example, Chapter02. 31 | 32 | The code will look like the following: 33 | ``` 34 | div,.thetemplate { 35 | font-size: 30px; 36 | padding: 20px; 37 | color: limegreen; 38 | font-family: Arial; 39 | ``` 40 | 41 | **Following is what you need for this book:** 42 | Copy and paste the Audience section from the EPIC. 43 | 44 | With the following software and hardware list you can run all code files present in the book (Chapter 1-15). 45 | 46 | ### Software and Hardware List 47 | 48 | | Chapter | Software required | OS required | 49 | | -------- | ------------------------------------| -----------------------------------| 50 | | 1-8 | Gitbash for Windows, Nodejs version | Windows | 51 | | | 8.9.0 and up, npm version 6 and up, | | 52 | | | VS Code, ES5/ES6 | | 53 | 54 | 55 | We also provide a PDF file that has color images of the screenshots/diagrams used in this book. [Click here to download it](https://www.packtpub.com/sites/default/files/downloads/9781789344103_ColorImages.pdf). 56 | 57 | ### Related products 58 | * Full-Stack Vue.js 2 and Laravel 5 [[Packt]](https://www.packtpub.com/application-development/full-stack-vuejs-2-and-laravel-5?utm_source=github&utm_medium=repository&utm_campaign=9781788299589) [[Amazon]](https://www.amazon.com/dp/1788299582) 59 | 60 | * Vue.js 2 Design Patterns and Best Practices [[Packt]](https://www.packtpub.com/web-development/vuejs-design-patterns-and-best-practices?utm_source=github&utm_medium=repository&utm_campaign=9781788839792) [[Amazon]](https://www.amazon.com/dp/178883979X) 61 | 62 | ## Get to Know the Author 63 | **Ajdin Imsirovic** 64 | has been working with frontend technologies, as well as web and print design, for almost two decades. He is an accomplished video course creator and the author of Bootstrap 4 Cookbook and Elm Web Development, both by Packt Publishing. In his third book, Vue.js Quick Start Guide, he eases in the newcomers to the Vue ecosystem in a clear and concise manner. 65 | 66 | 67 | ## Other books by the authors 68 | * [Bootstrap 4 Cookbook](https://www.packtpub.com/web-development/bootstrap-4-cookbook?utm_source=github&utm_medium=repository&utm_campaign=9781785889295) 69 | * [Elm Web Development](https://www.packtpub.com/web-development/elm-web-development?utm_source=github&utm_medium=repository&utm_campaign=9781788299053) 70 | 71 | ### Suggestions and Feedback 72 | [Click here](https://docs.google.com/forms/d/e/1FAIpQLSdy7dATC6QmEL81FIUuymZ0Wy9vH1jHkvpY57OiMeKGqib_Ow/viewform) if you have any feedback or suggestions. 73 | ### Download a free PDF 74 | 75 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
76 |

https://packt.link/free-ebook/9781789344103

--------------------------------------------------------------------------------