├── 01 - Your First Vue Application
└── todo
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ └── HelloWorld.vue
│ └── main.js
├── 03 - HTML Primer
└── htmlcssprimer
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ └── HelloWorld.vue
│ └── main.js
├── 04 - JavaScript Primer
└── jsprimer
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ └── HelloWorld.vue
│ ├── main.js
│ └── maths
│ ├── index.js
│ ├── operations.js
│ └── sum.js
├── 05 - SportsStore
└── sportsstore
│ ├── authMiddleware.js
│ ├── babel.config.js
│ ├── data.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ ├── CategoryControls.vue
│ ├── HelloWorld.vue
│ ├── PageControls.vue
│ ├── ProductList.vue
│ └── Store.vue
│ ├── main.js
│ └── store
│ └── index.js
├── 06 - SportsStore - Checkout and Orders
└── sportsstore
│ ├── authMiddleware.js
│ ├── babel.config.js
│ ├── data.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ ├── CartSummary.vue
│ ├── CategoryControls.vue
│ ├── Checkout.vue
│ ├── HelloWorld.vue
│ ├── OrderThanks.vue
│ ├── PageControls.vue
│ ├── ProductList.vue
│ ├── ShoppingCart.vue
│ ├── ShoppingCartLine.vue
│ ├── Store.vue
│ └── ValidationError.vue
│ ├── main.js
│ ├── router
│ └── index.js
│ └── store
│ ├── cart.js
│ ├── index.js
│ └── orders.js
├── 07 - SportsStore - Scaling and Administration
└── sportsstore
│ ├── authMiddleware.js
│ ├── babel.config.js
│ ├── data.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ ├── CartSummary.vue
│ ├── CategoryControls.vue
│ ├── Checkout.vue
│ ├── HelloWorld.vue
│ ├── OrderThanks.vue
│ ├── PageControls.vue
│ ├── ProductList.vue
│ ├── Search.vue
│ ├── ShoppingCart.vue
│ ├── ShoppingCartLine.vue
│ ├── Store.vue
│ ├── ValidationError.vue
│ └── admin
│ │ ├── Admin.vue
│ │ ├── Authentication.vue
│ │ ├── OrderAdmin.vue
│ │ └── ProductAdmin.vue
│ ├── main.js
│ ├── router
│ └── index.js
│ └── store
│ ├── auth.js
│ ├── cart.js
│ ├── index.js
│ └── orders.js
├── 08 - SportsStore - Administration and Deployment
└── sportsstore
│ ├── Dockerfile
│ ├── authMiddleware.js
│ ├── babel.config.js
│ ├── data.js
│ ├── data.json
│ ├── deploy-package.json
│ ├── dist
│ ├── css
│ │ └── chunk-vendors.291cfd91.css
│ ├── favicon.ico
│ ├── fonts
│ │ ├── fontawesome-webfont.674f50d2.eot
│ │ ├── fontawesome-webfont.af7ae505.woff2
│ │ ├── fontawesome-webfont.b06871f2.ttf
│ │ └── fontawesome-webfont.fee66e71.woff
│ ├── img
│ │ └── fontawesome-webfont.912ec66d.svg
│ ├── index.html
│ └── js
│ │ ├── admin.84f71a1c.js
│ │ ├── admin.84f71a1c.js.map
│ │ ├── app.87738c6f.js
│ │ ├── app.87738c6f.js.map
│ │ ├── chunk-vendors.56adf36a.js
│ │ └── chunk-vendors.56adf36a.js.map
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ ├── server.js
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ ├── CartSummary.vue
│ ├── CategoryControls.vue
│ ├── Checkout.vue
│ ├── HelloWorld.vue
│ ├── OrderThanks.vue
│ ├── PageControls.vue
│ ├── ProductList.vue
│ ├── Search.vue
│ ├── ShoppingCart.vue
│ ├── ShoppingCartLine.vue
│ ├── Store.vue
│ ├── ValidationError.vue
│ └── admin
│ │ ├── Admin.vue
│ │ ├── Authentication.vue
│ │ ├── OrderAdmin.vue
│ │ ├── ProductAdmin.vue
│ │ └── ProductEditor.vue
│ ├── main.js
│ ├── router
│ └── index.js
│ └── store
│ ├── auth.js
│ ├── cart.js
│ ├── index.js
│ └── orders.js
├── 09 - Understanding Vue.js
└── nomagic
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ ├── src
│ ├── App.html
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ └── HelloWorld.vue
│ └── main.js
│ └── vue.config.js
├── 10 - Understanding Vue.js Projects
└── projecttools
│ ├── babel.config.js
│ ├── dist
│ ├── css
│ │ └── app.b938236b.css
│ ├── favicon.ico
│ ├── img
│ │ └── logo.82b9c7a5.png
│ ├── index.html
│ └── js
│ │ ├── app.b671844a.js
│ │ ├── app.b671844a.js.map
│ │ ├── chunk-vendors.02da9ab1.js
│ │ └── chunk-vendors.02da9ab1.js.map
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ ├── server.js
│ ├── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ └── HelloWorld.vue
│ ├── main.js
│ ├── router.js
│ ├── store.js
│ └── views
│ │ ├── About.vue
│ │ └── Home.vue
│ └── vue.config.js
├── 11 - Understanding Data Bindings
└── templatesanddata
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ └── HelloWorld.vue
│ └── main.js
├── 12 - Using the Basic Directives
└── templatesanddata
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ └── HelloWorld.vue
│ └── main.js
├── 13 - Using the Repeater Directive
└── templatesanddata
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ └── HelloWorld.vue
│ └── main.js
├── 14 - Handling Events
└── templatesanddata
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ └── HelloWorld.vue
│ └── main.js
├── 15 - Working with Form Elements
└── templatesanddata
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ └── HelloWorld.vue
│ ├── main.js
│ └── validationRules.js
├── 16 - Components
└── templatesanddata
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ ├── Child.vue
│ ├── HelloWorld.vue
│ └── ProductDisplay.vue
│ ├── main.js
│ └── validationRules.js
├── 17 - Understanding the Component Lifecycle
└── lifecycles
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ ├── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ ├── HelloWorld.vue
│ │ └── MessageDisplay.vue
│ └── main.js
│ └── vue.config.js
├── 18 - Loosely-Coupled Components
└── productapp
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ ├── EditorField.vue
│ ├── HelloWorld.vue
│ ├── ProductDisplay.vue
│ └── ProductEditor.vue
│ └── main.js
├── 19 - Using RESTful Web Services
└── productapp
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ ├── restData.js
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ ├── EditorField.vue
│ ├── ErrorDisplay.vue
│ ├── HelloWorld.vue
│ ├── ProductDisplay.vue
│ └── ProductEditor.vue
│ ├── main.js
│ └── restDataSource.js
├── 20 - Using a Data Store
└── productapp
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ ├── restData.js
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ ├── EditorField.vue
│ ├── ErrorDisplay.vue
│ ├── HelloWorld.vue
│ ├── ProductDisplay.vue
│ └── ProductEditor.vue
│ ├── main.js
│ ├── restDataSource.js
│ └── store
│ ├── index.js
│ └── preferences.js
├── 21 - Dynamic Components
└── productapp
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ ├── restData.js
│ ├── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ ├── DataSummary.vue
│ │ ├── EditorField.vue
│ │ ├── ErrorDisplay.vue
│ │ ├── HelloWorld.vue
│ │ ├── LoadingMessage.vue
│ │ ├── ProductDisplay.vue
│ │ └── ProductEditor.vue
│ ├── main.js
│ ├── restDataSource.js
│ └── store
│ │ ├── index.js
│ │ ├── navigation.js
│ │ └── preferences.js
│ └── vue.config.js
├── 22 - URL Routing
└── productapp
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ ├── restData.js
│ ├── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ ├── DataSummary.vue
│ │ ├── EditorField.vue
│ │ ├── ErrorDisplay.vue
│ │ ├── HelloWorld.vue
│ │ ├── LoadingMessage.vue
│ │ ├── ProductDisplay.vue
│ │ └── ProductEditor.vue
│ ├── main.js
│ ├── restDataSource.js
│ ├── router
│ │ └── index.js
│ └── store
│ │ ├── index.js
│ │ ├── navigation.js
│ │ └── preferences.js
│ └── vue.config.js
├── 23 - URL Routing Elements
└── productapp
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ ├── restData.js
│ ├── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ ├── DataSummary.vue
│ │ ├── EditorField.vue
│ │ ├── ErrorDisplay.vue
│ │ ├── HelloWorld.vue
│ │ ├── LoadingMessage.vue
│ │ ├── Preferences.vue
│ │ ├── ProductDisplay.vue
│ │ ├── ProductEditor.vue
│ │ ├── Products.vue
│ │ └── SideBySide.vue
│ ├── main.js
│ ├── restDataSource.js
│ ├── router
│ │ └── index.js
│ └── store
│ │ ├── index.js
│ │ ├── navigation.js
│ │ └── preferences.js
│ └── vue.config.js
├── 24 - Advanced URL Routing
└── productapp
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ ├── restData.js
│ ├── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ ├── DataSummary.vue
│ │ ├── EditorField.vue
│ │ ├── ErrorDisplay.vue
│ │ ├── FilteredData.vue
│ │ ├── HelloWorld.vue
│ │ ├── LoadingMessage.vue
│ │ ├── MessageDisplay.vue
│ │ ├── Preferences.vue
│ │ ├── ProductDisplay.vue
│ │ ├── ProductEditor.vue
│ │ ├── Products.vue
│ │ └── SideBySide.vue
│ ├── main.js
│ ├── restDataSource.js
│ ├── router
│ │ ├── basicRoutes.js
│ │ ├── index.js
│ │ └── sideBySideRoutes.js
│ └── store
│ │ ├── index.js
│ │ ├── navigation.js
│ │ └── preferences.js
│ └── vue.config.js
├── 25 - Transitions
└── transitions
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ ├── HelloWorld.vue
│ ├── ListMaker.vue
│ ├── ListMakerControls.vue
│ ├── Numbers.vue
│ └── SimpleDisplay.vue
│ ├── main.js
│ └── router
│ └── index.js
├── 26 - Extending Vue.js
└── extendingvue
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ └── logo.png
│ ├── components
│ ├── HelloWorld.vue
│ ├── Numbers.vue
│ └── Subtraction.vue
│ ├── directives
│ └── colorize.js
│ ├── main.js
│ ├── mixins
│ └── numbersMixin.js
│ └── plugins
│ └── maths
│ ├── Operation.vue
│ ├── componentFeatures.js
│ ├── directives.js
│ ├── filters.js
│ ├── globals.js
│ └── index.js
├── 9781484238042.jpg
├── Contributing.md
├── LICENSE.txt
├── README.md
└── errata.md
/01 - Your First Vue Application/todo/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/01 - Your First Vue Application/todo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "todo",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "bootstrap": "^4.0.0",
12 | "vue": "^2.5.16"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "^3.0.0-beta.16",
16 | "@vue/cli-plugin-eslint": "^3.0.0-beta.16",
17 | "@vue/cli-service": "^3.0.0-beta.16",
18 | "vue-template-compiler": "^2.5.16"
19 | },
20 | "eslintConfig": {
21 | "root": true,
22 | "env": {
23 | "node": true
24 | },
25 | "extends": [
26 | "plugin:vue/essential",
27 | "eslint:recommended"
28 | ],
29 | "rules": {},
30 | "parserOptions": {
31 | "parser": "babel-eslint"
32 | }
33 | },
34 | "postcss": {
35 | "plugins": {
36 | "autoprefixer": {}
37 | }
38 | },
39 | "browserslist": [
40 | "> 1%",
41 | "last 2 versions",
42 | "not ie <= 8"
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/01 - Your First Vue Application/todo/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/01 - Your First Vue Application/todo/public/favicon.ico
--------------------------------------------------------------------------------
/01 - Your First Vue Application/todo/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | todo
9 |
10 |
11 |
12 | We're sorry but todo doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/01 - Your First Vue Application/todo/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/01 - Your First Vue Application/todo/src/assets/logo.png
--------------------------------------------------------------------------------
/01 - Your First Vue Application/todo/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | Vue.config.productionTip = false
5 |
6 | import "bootstrap/dist/css/bootstrap.min.css";
7 |
8 | new Vue({
9 | render: h => h(App)
10 | }).$mount('#app')
11 |
--------------------------------------------------------------------------------
/03 - HTML Primer/htmlcssprimer/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/03 - HTML Primer/htmlcssprimer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "htmlcssprimer",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "bootstrap": "^4.0.0",
12 | "vue": "^2.5.16"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "^3.0.0-beta.16",
16 | "@vue/cli-plugin-eslint": "^3.0.0-beta.16",
17 | "@vue/cli-service": "^3.0.0-beta.16",
18 | "vue-template-compiler": "^2.5.16"
19 | },
20 | "eslintConfig": {
21 | "root": true,
22 | "env": {
23 | "node": true
24 | },
25 | "extends": [
26 | "plugin:vue/essential",
27 | "eslint:recommended"
28 | ],
29 | "rules": {},
30 | "parserOptions": {
31 | "parser": "babel-eslint"
32 | }
33 | },
34 | "postcss": {
35 | "plugins": {
36 | "autoprefixer": {}
37 | }
38 | },
39 | "browserslist": [
40 | "> 1%",
41 | "last 2 versions",
42 | "not ie <= 8"
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/03 - HTML Primer/htmlcssprimer/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/03 - HTML Primer/htmlcssprimer/public/favicon.ico
--------------------------------------------------------------------------------
/03 - HTML Primer/htmlcssprimer/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | htmlcssprimer
9 |
10 |
11 |
12 | We're sorry but htmlcssprimer doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/03 - HTML Primer/htmlcssprimer/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/03 - HTML Primer/htmlcssprimer/src/assets/logo.png
--------------------------------------------------------------------------------
/03 - HTML Primer/htmlcssprimer/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | Vue.config.productionTip = false
5 |
6 | import "bootstrap/dist/css/bootstrap.min.css";
7 |
8 | new Vue({
9 | render: h => h(App)
10 | }).$mount('#app')
11 |
--------------------------------------------------------------------------------
/04 - JavaScript Primer/jsprimer/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/04 - JavaScript Primer/jsprimer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jsprimer",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "vue": "^2.5.16"
12 | },
13 | "devDependencies": {
14 | "@vue/cli-plugin-babel": "^3.0.0-beta.16",
15 | "@vue/cli-plugin-eslint": "^3.0.0-beta.16",
16 | "@vue/cli-service": "^3.0.0-beta.16",
17 | "vue-template-compiler": "^2.5.16"
18 | },
19 | "eslintConfig": {
20 | "root": true,
21 | "env": {
22 | "node": true
23 | },
24 | "extends": [
25 | "plugin:vue/essential",
26 | "eslint:recommended"
27 | ],
28 | "rules": {
29 | "no-console": "off",
30 | "no-declare": "off",
31 | "no-unused-vars": "off"
32 | },
33 | "parserOptions": {
34 | "parser": "babel-eslint"
35 | }
36 | },
37 | "postcss": {
38 | "plugins": {
39 | "autoprefixer": {}
40 | }
41 | },
42 | "browserslist": [
43 | "> 1%",
44 | "last 2 versions",
45 | "not ie <= 8"
46 | ]
47 | }
48 |
--------------------------------------------------------------------------------
/04 - JavaScript Primer/jsprimer/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/04 - JavaScript Primer/jsprimer/public/favicon.ico
--------------------------------------------------------------------------------
/04 - JavaScript Primer/jsprimer/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | jsprimer
9 |
10 |
11 |
12 | We're sorry but jsprimer doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/04 - JavaScript Primer/jsprimer/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
18 |
19 |
29 |
--------------------------------------------------------------------------------
/04 - JavaScript Primer/jsprimer/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/04 - JavaScript Primer/jsprimer/src/assets/logo.png
--------------------------------------------------------------------------------
/04 - JavaScript Primer/jsprimer/src/main.js:
--------------------------------------------------------------------------------
1 | import { asyncAdd } from "./maths";
2 |
3 | let values = [10, 20, 30, 40, 50];
4 |
5 | async function doTask() {
6 | let total = await asyncAdd(values);
7 | console.log(`Main Total: ${total}`);
8 | }
9 |
10 | doTask();
11 |
--------------------------------------------------------------------------------
/04 - JavaScript Primer/jsprimer/src/maths/index.js:
--------------------------------------------------------------------------------
1 | import addition from "./sum";
2 |
3 | export function mean(values) {
4 | return addition(values)/values.length;
5 | }
6 |
7 | export { addition };
8 | export * from "./operations";
9 |
10 | export function asyncAdd(values) {
11 | return new Promise((callback) => {
12 | setTimeout(() => {
13 | let total = addition(values);
14 | console.log(`Async Total: ${total}`);
15 | callback(total);
16 | }, 500);
17 | });
18 | }
19 |
--------------------------------------------------------------------------------
/04 - JavaScript Primer/jsprimer/src/maths/operations.js:
--------------------------------------------------------------------------------
1 | export function multiply(values) {
2 | return values.reduce((total, val) => total * val, 1);
3 | }
4 |
5 | export function subtract(amount, values) {
6 | return values.reduce((total, val) => total - val, amount);
7 | }
8 |
9 | export function divide(first, second) {
10 | return first / second;
11 | }
12 |
--------------------------------------------------------------------------------
/04 - JavaScript Primer/jsprimer/src/maths/sum.js:
--------------------------------------------------------------------------------
1 | export default function(values) {
2 | return values.reduce((total, val) => total + val, 0);
3 | }
4 |
--------------------------------------------------------------------------------
/05 - SportsStore/sportsstore/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/05 - SportsStore/sportsstore/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sportsstore",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint",
9 | "json": "json-server data.js -p 3500 -m authMiddleware.js"
10 | },
11 | "dependencies": {
12 | "axios": "^0.18.0",
13 | "bootstrap": "^4.0.0",
14 | "font-awesome": "^4.7.0",
15 | "vue": "^2.5.16",
16 | "vue-router": "^3.0.1",
17 | "vuelidate": "^0.7.4",
18 | "vuex": "^3.0.1"
19 | },
20 | "devDependencies": {
21 | "@vue/cli-plugin-babel": "^3.0.0-beta.16",
22 | "@vue/cli-plugin-eslint": "^3.0.0-beta.16",
23 | "@vue/cli-service": "^3.0.0-beta.16",
24 | "faker": "^4.1.0",
25 | "json-server": "^0.12.1",
26 | "jsonwebtoken": "^8.1.1",
27 | "vue-template-compiler": "^2.5.16"
28 | },
29 | "eslintConfig": {
30 | "root": true,
31 | "env": {
32 | "node": true
33 | },
34 | "extends": [
35 | "plugin:vue/essential",
36 | "eslint:recommended"
37 | ],
38 | "rules": {},
39 | "parserOptions": {
40 | "parser": "babel-eslint"
41 | }
42 | },
43 | "postcss": {
44 | "plugins": {
45 | "autoprefixer": {}
46 | }
47 | },
48 | "browserslist": [
49 | "> 1%",
50 | "last 2 versions",
51 | "not ie <= 8"
52 | ]
53 | }
54 |
--------------------------------------------------------------------------------
/05 - SportsStore/sportsstore/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/05 - SportsStore/sportsstore/public/favicon.ico
--------------------------------------------------------------------------------
/05 - SportsStore/sportsstore/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | sportsstore
9 |
10 |
11 |
12 | We're sorry but sportsstore doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/05 - SportsStore/sportsstore/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
20 |
--------------------------------------------------------------------------------
/05 - SportsStore/sportsstore/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/05 - SportsStore/sportsstore/src/assets/logo.png
--------------------------------------------------------------------------------
/05 - SportsStore/sportsstore/src/components/CategoryControls.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 | {{ c }}
9 |
10 |
11 |
12 |
13 |
14 |
27 |
--------------------------------------------------------------------------------
/05 - SportsStore/sportsstore/src/components/PageControls.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 4 per page
6 | 8 per page
7 | 12 per page
8 |
9 |
10 |
11 |
12 |
16 | {{ i }}
17 |
18 |
19 |
20 |
21 |
22 |
23 |
43 |
--------------------------------------------------------------------------------
/05 - SportsStore/sportsstore/src/components/ProductList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{p.name}}
6 |
7 | {{ p.price | currency }}
8 |
9 |
10 |
{{ p.description }}
11 |
12 |
13 |
14 |
15 |
16 |
34 |
--------------------------------------------------------------------------------
/05 - SportsStore/sportsstore/src/components/Store.vue:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
29 |
--------------------------------------------------------------------------------
/05 - SportsStore/sportsstore/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | Vue.config.productionTip = false
5 |
6 | import "bootstrap/dist/css/bootstrap.min.css";
7 | import "font-awesome/css/font-awesome.min.css"
8 |
9 | import store from "./store";
10 |
11 | new Vue({
12 | render: h => h(App),
13 | store
14 | }).$mount('#app')
15 |
--------------------------------------------------------------------------------
/06 - SportsStore - Checkout and Orders/sportsstore/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/06 - SportsStore - Checkout and Orders/sportsstore/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sportsstore",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint",
9 | "json": "json-server data.js -p 3500 -m authMiddleware.js"
10 | },
11 | "dependencies": {
12 | "axios": "^0.18.0",
13 | "bootstrap": "^4.0.0",
14 | "font-awesome": "^4.7.0",
15 | "vue": "^2.5.16",
16 | "vue-router": "^3.0.1",
17 | "vuelidate": "^0.7.4",
18 | "vuex": "^3.0.1"
19 | },
20 | "devDependencies": {
21 | "@vue/cli-plugin-babel": "^3.0.0-beta.16",
22 | "@vue/cli-plugin-eslint": "^3.0.0-beta.16",
23 | "@vue/cli-service": "^3.0.0-beta.16",
24 | "faker": "^4.1.0",
25 | "json-server": "^0.12.1",
26 | "jsonwebtoken": "^8.1.1",
27 | "vue-template-compiler": "^2.5.16"
28 | },
29 | "eslintConfig": {
30 | "root": true,
31 | "env": {
32 | "node": true
33 | },
34 | "extends": [
35 | "plugin:vue/essential",
36 | "eslint:recommended"
37 | ],
38 | "rules": {},
39 | "parserOptions": {
40 | "parser": "babel-eslint"
41 | }
42 | },
43 | "postcss": {
44 | "plugins": {
45 | "autoprefixer": {}
46 | }
47 | },
48 | "browserslist": [
49 | "> 1%",
50 | "last 2 versions",
51 | "not ie <= 8"
52 | ]
53 | }
54 |
--------------------------------------------------------------------------------
/06 - SportsStore - Checkout and Orders/sportsstore/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/06 - SportsStore - Checkout and Orders/sportsstore/public/favicon.ico
--------------------------------------------------------------------------------
/06 - SportsStore - Checkout and Orders/sportsstore/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | sportsstore
9 |
10 |
11 |
12 | We're sorry but sportsstore doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/06 - SportsStore - Checkout and Orders/sportsstore/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
22 |
--------------------------------------------------------------------------------
/06 - SportsStore - Checkout and Orders/sportsstore/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/06 - SportsStore - Checkout and Orders/sportsstore/src/assets/logo.png
--------------------------------------------------------------------------------
/06 - SportsStore - Checkout and Orders/sportsstore/src/components/CartSummary.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Your cart:
5 |
6 | {{ itemCount }} item(s) {{ totalPrice | currency }}
7 |
8 |
9 | (empty)
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
31 |
--------------------------------------------------------------------------------
/06 - SportsStore - Checkout and Orders/sportsstore/src/components/CategoryControls.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 | {{ c }}
9 |
10 |
11 |
12 |
13 |
14 |
27 |
--------------------------------------------------------------------------------
/06 - SportsStore - Checkout and Orders/sportsstore/src/components/OrderThanks.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Thanks!
5 |
Thanks for placing your order, which is #{{orderId}}.
6 |
We'll ship your goods as soon as possible.
7 |
Return to Store
8 |
9 |
10 |
11 |
12 |
21 |
--------------------------------------------------------------------------------
/06 - SportsStore - Checkout and Orders/sportsstore/src/components/ProductList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{p.name}}
6 |
7 | {{ p.price | currency }}
8 |
9 |
10 |
11 | {{ p.description }}
12 |
14 | Add To Cart
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
47 |
--------------------------------------------------------------------------------
/06 - SportsStore - Checkout and Orders/sportsstore/src/components/Store.vue:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
31 |
--------------------------------------------------------------------------------
/06 - SportsStore - Checkout and Orders/sportsstore/src/components/ValidationError.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
36 |
--------------------------------------------------------------------------------
/06 - SportsStore - Checkout and Orders/sportsstore/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | Vue.config.productionTip = false
5 |
6 | import "bootstrap/dist/css/bootstrap.min.css";
7 | import "font-awesome/css/font-awesome.min.css"
8 |
9 | import store from "./store";
10 | import router from "./router";
11 | import Vuelidate from "vuelidate";
12 |
13 | Vue.filter("currency", (value) => new Intl.NumberFormat("en-US",
14 | { style: "currency", currency: "USD" }).format(value));
15 |
16 | Vue.use(Vuelidate);
17 |
18 | new Vue({
19 | render: h => h(App),
20 | store,
21 | router
22 | }).$mount('#app')
23 |
--------------------------------------------------------------------------------
/06 - SportsStore - Checkout and Orders/sportsstore/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import VueRouter from "vue-router";
3 |
4 | import Store from "../components/Store";
5 | import ShoppingCart from "../components/ShoppingCart";
6 | import Checkout from "../components/Checkout";
7 | import OrderThanks from "../components/OrderThanks";
8 |
9 | Vue.use(VueRouter);
10 |
11 | export default new VueRouter({
12 | mode: "history",
13 | routes: [
14 | { path: "/", component: Store },
15 | { path: "/cart", component: ShoppingCart },
16 | { path: "/checkout", component: Checkout},
17 | { path: "/thanks/:id", component: OrderThanks},
18 | { path: "*", redirect: "/"}
19 | ]
20 | })
21 |
--------------------------------------------------------------------------------
/06 - SportsStore - Checkout and Orders/sportsstore/src/store/orders.js:
--------------------------------------------------------------------------------
1 | import Axios from "axios";
2 |
3 | const ORDERS_URL = "http://localhost:3500/orders";
4 |
5 | export default {
6 | actions: {
7 | async storeOrder(context, order) {
8 | order.cartLines = context.rootState.cart.lines;
9 | return (await Axios.post(ORDERS_URL, order)).data.id;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/data.js:
--------------------------------------------------------------------------------
1 | var faker = require("faker");
2 |
3 | var data = [];
4 | var categories = ["Watersports", "Soccer", "Chess", "Running"];
5 |
6 | faker.seed(100);
7 |
8 | for (let i = 1; i <= 500; i++) {
9 | var category = faker.helpers.randomize(categories);
10 | data.push({
11 | id: i,
12 | name: faker.commerce.productName(),
13 | category: category,
14 | description: `${category}: ${faker.lorem.sentence(3)}`,
15 | price: faker.commerce.price()
16 | })
17 | }
18 |
19 | module.exports = function () {
20 | return {
21 | products: data,
22 | categories: categories,
23 | orders: []
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sportsstore",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint",
9 | "json": "json-server data.js -p 3500 -m authMiddleware.js"
10 | },
11 | "dependencies": {
12 | "axios": "^0.18.0",
13 | "bootstrap": "^4.0.0",
14 | "font-awesome": "^4.7.0",
15 | "vue": "^2.5.16",
16 | "vue-router": "^3.0.1",
17 | "vuelidate": "^0.7.4",
18 | "vuex": "^3.0.1"
19 | },
20 | "devDependencies": {
21 | "@vue/cli-plugin-babel": "^3.0.0-beta.16",
22 | "@vue/cli-plugin-eslint": "^3.0.0-beta.16",
23 | "@vue/cli-service": "^3.0.0-beta.16",
24 | "faker": "^4.1.0",
25 | "json-server": "^0.12.1",
26 | "jsonwebtoken": "^8.1.1",
27 | "vue-template-compiler": "^2.5.16"
28 | },
29 | "eslintConfig": {
30 | "root": true,
31 | "env": {
32 | "node": true
33 | },
34 | "extends": [
35 | "plugin:vue/essential",
36 | "eslint:recommended"
37 | ],
38 | "rules": {},
39 | "parserOptions": {
40 | "parser": "babel-eslint"
41 | }
42 | },
43 | "postcss": {
44 | "plugins": {
45 | "autoprefixer": {}
46 | }
47 | },
48 | "browserslist": [
49 | "> 1%",
50 | "last 2 versions",
51 | "not ie <= 8"
52 | ]
53 | }
54 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/07 - SportsStore - Scaling and Administration/sportsstore/public/favicon.ico
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | sportsstore
9 |
10 |
11 |
12 | We're sorry but sportsstore doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
22 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/07 - SportsStore - Scaling and Administration/sportsstore/src/assets/logo.png
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/src/components/CartSummary.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Your cart:
5 |
6 | {{ itemCount }} item(s) {{ totalPrice | currency }}
7 |
8 |
9 | (empty)
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
31 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/src/components/CategoryControls.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 | {{ c }}
9 |
10 |
11 |
12 |
13 |
14 |
27 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/src/components/OrderThanks.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Thanks!
5 |
Thanks for placing your order, which is #{{orderId}}.
6 |
We'll ship your goods as soon as possible.
7 |
Return to Store
8 |
9 |
10 |
11 |
12 |
21 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/src/components/ProductList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{p.name}}
6 |
7 | {{ p.price | currency }}
8 |
9 |
10 |
11 | {{ p.description }}
12 |
14 | Add To Cart
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
47 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/src/components/Search.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Search:
4 |
7 |
9 | Close
10 |
11 |
12 |
13 |
14 |
35 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/src/components/Store.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
14 | Search
15 |
16 |
17 |
21 |
22 |
23 |
24 |
25 |
39 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/src/components/ValidationError.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
36 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/src/components/admin/Admin.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
12 | Products
13 |
14 |
16 | Orders
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/src/components/admin/ProductAdmin.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Product Admin
4 |
5 |
6 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | Vue.config.productionTip = false
5 |
6 | import "bootstrap/dist/css/bootstrap.min.css";
7 | import "font-awesome/css/font-awesome.min.css"
8 |
9 | import store from "./store";
10 | import router from "./router";
11 | import Vuelidate from "vuelidate";
12 |
13 | Vue.filter("currency", (value) => new Intl.NumberFormat("en-US",
14 | { style: "currency", currency: "USD" }).format(value));
15 |
16 | Vue.use(Vuelidate);
17 |
18 | new Vue({
19 | render: h => h(App),
20 | store,
21 | router
22 | }).$mount('#app')
23 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/src/store/auth.js:
--------------------------------------------------------------------------------
1 | import Axios from "axios";
2 |
3 | const loginUrl = "http://localhost:3500/login";
4 |
5 | export default {
6 | state: {
7 | authenticated: false,
8 | jwt: null
9 | },
10 | getters: {
11 | authenticatedAxios(state) {
12 | return Axios.create({
13 | headers: {
14 | "Authorization": `Bearer<${state.jwt}>`
15 | }
16 | });
17 | }
18 | },
19 | mutations: {
20 | setAuthenticated(state, header) {
21 | state.jwt = header;
22 | state.authenticated = true;
23 | },
24 | clearAuthentication(state) {
25 | state.authenticated = false;
26 | state.jwt = null;
27 | }
28 | },
29 | actions: {
30 | async authenticate(context, credentials) {
31 | let response = await Axios.post(loginUrl, credentials);
32 | if (response.data.success == true) {
33 | context.commit("setAuthenticated", response.data.token);
34 | }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/07 - SportsStore - Scaling and Administration/sportsstore/src/store/orders.js:
--------------------------------------------------------------------------------
1 | import Axios from "axios";
2 | import Vue from "vue";
3 |
4 | const ORDERS_URL = "http://localhost:3500/orders";
5 |
6 | export default {
7 | state: {
8 | orders:[]
9 | },
10 | mutations: {
11 | setOrders(state, data) {
12 | state.orders = data;
13 | },
14 | changeOrderShipped(state, order) {
15 | Vue.set(order, "shipped",
16 | order.shipped == null || !order.shipped ? true : false);
17 | }
18 | },
19 | actions: {
20 | async storeOrder(context, order) {
21 | order.cartLines = context.rootState.cart.lines;
22 | return (await Axios.post(ORDERS_URL, order)).data.id;
23 | },
24 | async getOrders(context) {
25 | context.commit("setOrders",
26 | (await context.rootGetters.authenticatedAxios.get(ORDERS_URL)).data);
27 | },
28 | async updateOrder(context, order) {
29 | context.commit("changeOrderShipped", order);
30 | await context.rootGetters.authenticatedAxios
31 | .put(`${ORDERS_URL}/${order.id}`, order);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:8.11.2
2 |
3 | RUN mkdir -p /usr/src/sportsstore
4 |
5 | COPY dist /usr/src/sportsstore/dist
6 |
7 | COPY authMiddleware.js /usr/src/sportsstore/
8 | COPY data.json /usr/src/sportsstore/
9 | COPY server.js /usr/src/sportsstore/server.js
10 | COPY deploy-package.json /usr/src/sportsstore/package.json
11 |
12 | WORKDIR /usr/src/sportsstore
13 |
14 | RUN npm install
15 |
16 | EXPOSE 80
17 |
18 | CMD ["node", "server.js"]
19 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/data.js:
--------------------------------------------------------------------------------
1 | var faker = require("faker");
2 |
3 | var data = [];
4 | var categories = ["Watersports", "Soccer", "Chess", "Running"];
5 |
6 | faker.seed(100);
7 |
8 | for (let i = 1; i <= 500; i++) {
9 | var category = faker.helpers.randomize(categories);
10 | data.push({
11 | id: i,
12 | name: faker.commerce.productName(),
13 | category: category,
14 | description: `${category}: ${faker.lorem.sentence(3)}`,
15 | price: faker.commerce.price()
16 | })
17 | }
18 |
19 | module.exports = function () {
20 | return {
21 | products: data,
22 | categories: categories,
23 | orders: []
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/deploy-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sportsstore",
3 | "version": "1.0.0",
4 | "private": true,
5 |
6 | "dependencies": {
7 | "faker": "^4.1.0",
8 | "json-server": "^0.12.1",
9 | "jsonwebtoken": "^8.1.1",
10 | "express": "4.16.3",
11 | "connect-history-api-fallback": "1.5.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/dist/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/08 - SportsStore - Administration and Deployment/sportsstore/dist/favicon.ico
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/dist/fonts/fontawesome-webfont.674f50d2.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/08 - SportsStore - Administration and Deployment/sportsstore/dist/fonts/fontawesome-webfont.674f50d2.eot
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/dist/fonts/fontawesome-webfont.af7ae505.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/08 - SportsStore - Administration and Deployment/sportsstore/dist/fonts/fontawesome-webfont.af7ae505.woff2
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/dist/fonts/fontawesome-webfont.b06871f2.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/08 - SportsStore - Administration and Deployment/sportsstore/dist/fonts/fontawesome-webfont.b06871f2.ttf
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/dist/fonts/fontawesome-webfont.fee66e71.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/08 - SportsStore - Administration and Deployment/sportsstore/dist/fonts/fontawesome-webfont.fee66e71.woff
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/dist/index.html:
--------------------------------------------------------------------------------
1 | sportsstore We're sorry but sportsstore doesn't work properly without JavaScript enabled. Please enable it to continue.
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sportsstore",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint",
9 | "json": "json-server data.js -p 3500 -m authMiddleware.js"
10 | },
11 | "dependencies": {
12 | "axios": "^0.18.0",
13 | "bootstrap": "^4.0.0",
14 | "font-awesome": "^4.7.0",
15 | "vue": "^2.5.16",
16 | "vue-router": "^3.0.1",
17 | "vuelidate": "^0.7.4",
18 | "vuex": "^3.0.1"
19 | },
20 | "devDependencies": {
21 | "@vue/cli-plugin-babel": "^3.0.0-beta.16",
22 | "@vue/cli-plugin-eslint": "^3.0.0-beta.16",
23 | "@vue/cli-service": "^3.0.0-beta.16",
24 | "connect-history-api-fallback": "^1.5.0",
25 | "express": "^4.16.3",
26 | "faker": "^4.1.0",
27 | "json-server": "^0.12.1",
28 | "jsonwebtoken": "^8.1.1",
29 | "vue-template-compiler": "^2.5.16"
30 | },
31 | "eslintConfig": {
32 | "root": true,
33 | "env": {
34 | "node": true
35 | },
36 | "extends": [
37 | "plugin:vue/essential",
38 | "eslint:recommended"
39 | ],
40 | "rules": {},
41 | "parserOptions": {
42 | "parser": "babel-eslint"
43 | }
44 | },
45 | "postcss": {
46 | "plugins": {
47 | "autoprefixer": {}
48 | }
49 | },
50 | "browserslist": [
51 | "> 1%",
52 | "last 2 versions",
53 | "not ie <= 8"
54 | ]
55 | }
56 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/08 - SportsStore - Administration and Deployment/sportsstore/public/favicon.ico
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | sportsstore
9 |
10 |
11 |
12 | We're sorry but sportsstore doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/server.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const history = require("connect-history-api-fallback");
3 | const jsonServer = require("json-server");
4 | const bodyParser = require('body-parser');
5 | const auth = require("./authMiddleware");
6 | const router = jsonServer.router("data.json");
7 |
8 | const app = express();
9 | app.use(bodyParser.json());
10 | app.use(auth);
11 | app.use("/api", router);
12 | app.use(history());
13 | app.use("/", express.static("./dist"));
14 |
15 | app.listen(80, function () {
16 | console.log("HTTP Server running on port 80");
17 | });
18 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
22 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/08 - SportsStore - Administration and Deployment/sportsstore/src/assets/logo.png
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/src/components/CartSummary.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Your cart:
5 |
6 | {{ itemCount }} item(s) {{ totalPrice | currency }}
7 |
8 |
9 | (empty)
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
31 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/src/components/CategoryControls.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 | {{ c }}
9 |
10 |
11 |
12 |
13 |
14 |
27 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/src/components/OrderThanks.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Thanks!
5 |
Thanks for placing your order, which is #{{orderId}}.
6 |
We'll ship your goods as soon as possible.
7 |
Return to Store
8 |
9 |
10 |
11 |
12 |
21 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/src/components/ProductList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{p.name}}
6 |
7 | {{ p.price | currency }}
8 |
9 |
10 |
11 | {{ p.description }}
12 |
14 | Add To Cart
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
47 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/src/components/Search.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Search:
4 |
7 |
9 | Close
10 |
11 |
12 |
13 |
14 |
35 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/src/components/Store.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
14 | Search
15 |
16 |
17 |
21 |
22 |
23 |
24 |
25 |
39 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/src/components/ValidationError.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
36 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/src/components/admin/Admin.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
12 | Products
13 |
14 |
16 | Orders
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | Vue.config.productionTip = false
5 |
6 | import "bootstrap/dist/css/bootstrap.min.css";
7 | import "font-awesome/css/font-awesome.min.css"
8 |
9 | import store from "./store";
10 | import router from "./router";
11 | import Vuelidate from "vuelidate";
12 |
13 | Vue.filter("currency", (value) => new Intl.NumberFormat("en-US",
14 | { style: "currency", currency: "USD" }).format(value));
15 |
16 | Vue.use(Vuelidate);
17 |
18 | new Vue({
19 | render: h => h(App),
20 | store,
21 | router
22 | }).$mount('#app')
23 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/src/store/auth.js:
--------------------------------------------------------------------------------
1 | import Axios from "axios";
2 |
3 | const loginUrl = "/api/login";
4 |
5 | export default {
6 | state: {
7 | authenticated: false,
8 | jwt: null
9 | },
10 | getters: {
11 | authenticatedAxios(state) {
12 | return Axios.create({
13 | headers: {
14 | "Authorization": `Bearer<${state.jwt}>`
15 | }
16 | });
17 | }
18 | },
19 | mutations: {
20 | setAuthenticated(state, header) {
21 | state.jwt = header;
22 | state.authenticated = true;
23 | },
24 | clearAuthentication(state) {
25 | state.authenticated = false;
26 | state.jwt = null;
27 | }
28 | },
29 | actions: {
30 | async authenticate(context, credentials) {
31 | let response = await Axios.post(loginUrl, credentials);
32 | if (response.data.success == true) {
33 | context.commit("setAuthenticated", response.data.token);
34 | }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/08 - SportsStore - Administration and Deployment/sportsstore/src/store/orders.js:
--------------------------------------------------------------------------------
1 | import Axios from "axios";
2 | import Vue from "vue";
3 |
4 | const ORDERS_URL = "/api/orders";
5 |
6 | export default {
7 | state: {
8 | orders:[]
9 | },
10 | mutations: {
11 | setOrders(state, data) {
12 | state.orders = data;
13 | },
14 | changeOrderShipped(state, order) {
15 | Vue.set(order, "shipped",
16 | order.shipped == null || !order.shipped ? true : false);
17 | }
18 | },
19 | actions: {
20 | async storeOrder(context, order) {
21 | order.cartLines = context.rootState.cart.lines;
22 | return (await Axios.post(ORDERS_URL, order)).data.id;
23 | },
24 | async getOrders(context) {
25 | context.commit("setOrders",
26 | (await context.rootGetters.authenticatedAxios.get(ORDERS_URL)).data);
27 | },
28 | async updateOrder(context, order) {
29 | context.commit("changeOrderShipped", order);
30 | await context.rootGetters.authenticatedAxios
31 | .put(`${ORDERS_URL}/${order.id}`, order);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/09 - Understanding Vue.js/nomagic/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/09 - Understanding Vue.js/nomagic/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nomagic",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "bootstrap": "^4.0.0",
12 | "vue": "^2.5.16"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "^3.0.0-beta.15",
16 | "@vue/cli-plugin-eslint": "^3.0.0-beta.15",
17 | "@vue/cli-service": "^3.0.0-beta.15",
18 | "vue-template-compiler": "^2.5.16"
19 | },
20 | "eslintConfig": {
21 | "root": true,
22 | "env": {
23 | "node": true
24 | },
25 | "extends": [
26 | "plugin:vue/essential",
27 | "eslint:recommended"
28 | ],
29 | "rules": {},
30 | "parserOptions": {
31 | "parser": "babel-eslint"
32 | }
33 | },
34 | "postcss": {
35 | "plugins": {
36 | "autoprefixer": {}
37 | }
38 | },
39 | "browserslist": [
40 | "> 1%",
41 | "last 2 versions",
42 | "not ie <= 8"
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/09 - Understanding Vue.js/nomagic/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/09 - Understanding Vue.js/nomagic/public/favicon.ico
--------------------------------------------------------------------------------
/09 - Understanding Vue.js/nomagic/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | nomagic
9 |
10 |
11 |
12 | We're sorry but nomagic doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/09 - Understanding Vue.js/nomagic/src/App.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ message }}
4 |
5 |
6 | Press Me
7 |
8 |
9 |
--------------------------------------------------------------------------------
/09 - Understanding Vue.js/nomagic/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
--------------------------------------------------------------------------------
/09 - Understanding Vue.js/nomagic/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/09 - Understanding Vue.js/nomagic/src/assets/logo.png
--------------------------------------------------------------------------------
/09 - Understanding Vue.js/nomagic/src/main.js:
--------------------------------------------------------------------------------
1 | require('../node_modules/bootstrap/dist/css/bootstrap.min.css')
2 |
3 | import Vue from "vue";
4 | import MyComponent from "./App";
5 |
6 | new Vue({
7 | el: "#app",
8 | components: { "custom": MyComponent },
9 | template: " "
10 | });
11 |
--------------------------------------------------------------------------------
/09 - Understanding Vue.js/nomagic/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | runtimeCompiler: true
3 | }
4 |
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/dist/css/app.b938236b.css:
--------------------------------------------------------------------------------
1 | #app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:#2c3e50}#nav{padding:30px}#nav a{font-weight:700;color:#2c3e50}#nav a.router-link-exact-active{color:#42b983}h3[data-v-75d15865]{margin:40px 0 0}ul[data-v-75d15865]{list-style-type:none;padding:0}li[data-v-75d15865]{display:inline-block;margin:0 10px}a[data-v-75d15865]{color:#42b983}
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/dist/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/10 - Understanding Vue.js Projects/projecttools/dist/favicon.ico
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/dist/img/logo.82b9c7a5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/10 - Understanding Vue.js Projects/projecttools/dist/img/logo.82b9c7a5.png
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | projecttools
9 |
10 |
11 |
12 |
13 |
14 |
15 | We're sorry but projecttools doesn't work properly without JavaScript enabled. Please enable it to continue.
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "projecttools",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "vue": "^2.5.16",
12 | "vue-router": "^3.0.1",
13 | "vuex": "^3.0.1"
14 | },
15 | "devDependencies": {
16 | "@vue/cli-plugin-babel": "^3.0.0-beta.15",
17 | "@vue/cli-plugin-eslint": "^3.0.0-beta.15",
18 | "@vue/cli-service": "^3.0.0-beta.15",
19 | "connect-history-api-fallback": "^1.5.0",
20 | "express": "^4.16.3",
21 | "vue-template-compiler": "^2.5.16"
22 | },
23 | "eslintConfig": {
24 | "root": true,
25 | "env": {
26 | "node": true
27 | },
28 | "extends": [
29 | "plugin:vue/essential",
30 | "eslint:recommended"
31 | ],
32 | "rules": {
33 | "vue/html-indent": "off",
34 | "vue/v-on-style": [
35 | "warn",
36 | "longform"
37 | ]
38 | },
39 | "parserOptions": {
40 | "parser": "babel-eslint"
41 | }
42 | },
43 | "postcss": {
44 | "plugins": {
45 | "autoprefixer": {}
46 | }
47 | },
48 | "browserslist": [
49 | "> 1%",
50 | "last 2 versions",
51 | "not ie <= 8"
52 | ]
53 | }
54 |
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/10 - Understanding Vue.js Projects/projecttools/public/favicon.ico
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | projecttools
9 |
10 |
11 |
12 | We're sorry but projecttools doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/server.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const history = require("connect-history-api-fallback");
3 | const bodyParser = require('body-parser');
4 |
5 | const app = express();
6 | app.use(bodyParser.json());
7 | app.use(history());
8 | app.use("/", express.static("./dist"));
9 |
10 | app.listen(80, function () {
11 | console.log("HTTP Server running on port 80");
12 | });
13 |
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Button Clicks: {{ counter }}
4 |
Press Me
5 |
6 | Home |
7 | About
8 |
9 |
10 |
11 |
12 |
13 |
29 |
30 |
53 |
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/10 - Understanding Vue.js Projects/projecttools/src/assets/logo.png
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import store from './store'
5 |
6 | Vue.config.productionTip = false
7 |
8 | //let first = "Hello";
9 | //const second = "World";
10 | //console.log(`Message ${first},${second}`);
11 |
12 | new Vue({
13 | router,
14 | store,
15 | render: h => h(App)
16 | }).$mount('#app')
17 |
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/src/router.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Router from 'vue-router'
3 | import Home from './views/Home.vue'
4 | import About from './views/About.vue'
5 |
6 | Vue.use(Router)
7 |
8 | export default new Router({
9 | routes: [
10 | {
11 | path: '/',
12 | name: 'home',
13 | component: Home
14 | },
15 | {
16 | path: '/about',
17 | name: 'about',
18 | component: About
19 | }
20 | ]
21 | })
22 |
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/src/store.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | Vue.use(Vuex)
5 |
6 | export default new Vuex.Store({
7 | state: {
8 |
9 | },
10 | mutations: {
11 |
12 | },
13 | actions: {
14 |
15 | }
16 | })
17 |
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/src/views/About.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
This is an about page
4 |
5 |
6 |
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
19 |
--------------------------------------------------------------------------------
/10 - Understanding Vue.js Projects/projecttools/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | runtimeCompiler: true
3 | }
4 |
--------------------------------------------------------------------------------
/11 - Understanding Data Bindings/templatesanddata/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/11 - Understanding Data Bindings/templatesanddata/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "templatesanddata",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "bootstrap": "^4.0.0",
12 | "vue": "^2.5.16"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "^3.0.0-beta.15",
16 | "@vue/cli-plugin-eslint": "^3.0.0-beta.15",
17 | "@vue/cli-service": "^3.0.0-beta.15",
18 | "vue-template-compiler": "^2.5.16"
19 | },
20 | "eslintConfig": {
21 | "root": true,
22 | "env": {
23 | "node": true
24 | },
25 | "extends": [
26 | "plugin:vue/essential",
27 | "eslint:recommended"
28 | ],
29 | "rules": {
30 | "no-console": "off"
31 | },
32 | "parserOptions": {
33 | "parser": "babel-eslint"
34 | }
35 | },
36 | "postcss": {
37 | "plugins": {
38 | "autoprefixer": {}
39 | }
40 | },
41 | "browserslist": [
42 | "> 1%",
43 | "last 2 versions",
44 | "not ie <= 8"
45 | ]
46 | }
47 |
--------------------------------------------------------------------------------
/11 - Understanding Data Bindings/templatesanddata/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/11 - Understanding Data Bindings/templatesanddata/public/favicon.ico
--------------------------------------------------------------------------------
/11 - Understanding Data Bindings/templatesanddata/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | templatesanddata
9 |
10 |
11 |
12 | We're sorry but templatesanddata doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/11 - Understanding Data Bindings/templatesanddata/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Product: {{ name }}
4 | Price: {{ getTotalPrice(lowTaxRate) | currency }} (Low Rate)
5 | Price: {{ getTotalPrice(highTaxRate) | currency }} (High Rate)
6 |
7 |
8 |
9 |
33 |
--------------------------------------------------------------------------------
/11 - Understanding Data Bindings/templatesanddata/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/11 - Understanding Data Bindings/templatesanddata/src/assets/logo.png
--------------------------------------------------------------------------------
/11 - Understanding Data Bindings/templatesanddata/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import "bootstrap/dist/css/bootstrap.min.css";
5 |
6 | Vue.config.productionTip = false
7 |
8 | new Vue({
9 | render: h => h(App)
10 | }).$mount('#app')
11 |
--------------------------------------------------------------------------------
/12 - Using the Basic Directives/templatesanddata/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/12 - Using the Basic Directives/templatesanddata/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "templatesanddata",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "bootstrap": "^4.0.0",
12 | "vue": "^2.5.16"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "^3.0.0-beta.15",
16 | "@vue/cli-plugin-eslint": "^3.0.0-beta.15",
17 | "@vue/cli-service": "^3.0.0-beta.15",
18 | "vue-template-compiler": "^2.5.16"
19 | },
20 | "eslintConfig": {
21 | "root": true,
22 | "env": {
23 | "node": true
24 | },
25 | "extends": [
26 | "plugin:vue/essential",
27 | "eslint:recommended"
28 | ],
29 | "rules": {
30 | "no-console": "off"
31 | },
32 | "parserOptions": {
33 | "parser": "babel-eslint"
34 | }
35 | },
36 | "postcss": {
37 | "plugins": {
38 | "autoprefixer": {}
39 | }
40 | },
41 | "browserslist": [
42 | "> 1%",
43 | "last 2 versions",
44 | "not ie <= 8"
45 | ]
46 | }
47 |
--------------------------------------------------------------------------------
/12 - Using the Basic Directives/templatesanddata/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/12 - Using the Basic Directives/templatesanddata/public/favicon.ico
--------------------------------------------------------------------------------
/12 - Using the Basic Directives/templatesanddata/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | templatesanddata
9 |
10 |
11 |
12 | We're sorry but templatesanddata doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/12 - Using the Basic Directives/templatesanddata/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Press Me
8 |
9 |
10 |
11 |
12 |
33 |
--------------------------------------------------------------------------------
/12 - Using the Basic Directives/templatesanddata/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/12 - Using the Basic Directives/templatesanddata/src/assets/logo.png
--------------------------------------------------------------------------------
/12 - Using the Basic Directives/templatesanddata/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import "bootstrap/dist/css/bootstrap.min.css";
5 |
6 | Vue.config.productionTip = false
7 |
8 | new Vue({
9 | render: h => h(App)
10 | }).$mount('#app')
11 |
--------------------------------------------------------------------------------
/13 - Using the Repeater Directive/templatesanddata/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/13 - Using the Repeater Directive/templatesanddata/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "templatesanddata",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "bootstrap": "^4.0.0",
12 | "vue": "^2.5.16"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "^3.0.0-beta.15",
16 | "@vue/cli-plugin-eslint": "^3.0.0-beta.15",
17 | "@vue/cli-service": "^3.0.0-beta.15",
18 | "vue-template-compiler": "^2.5.16"
19 | },
20 | "eslintConfig": {
21 | "root": true,
22 | "env": {
23 | "node": true
24 | },
25 | "extends": [
26 | "plugin:vue/essential",
27 | "eslint:recommended"
28 | ],
29 | "rules": {
30 | "no-console": "off"
31 | },
32 | "parserOptions": {
33 | "parser": "babel-eslint"
34 | }
35 | },
36 | "postcss": {
37 | "plugins": {
38 | "autoprefixer": {}
39 | }
40 | },
41 | "browserslist": [
42 | "> 1%",
43 | "last 2 versions",
44 | "not ie <= 8"
45 | ]
46 | }
47 |
--------------------------------------------------------------------------------
/13 - Using the Repeater Directive/templatesanddata/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/13 - Using the Repeater Directive/templatesanddata/public/favicon.ico
--------------------------------------------------------------------------------
/13 - Using the Repeater Directive/templatesanddata/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | templatesanddata
9 |
10 |
11 |
12 | We're sorry but templatesanddata doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/13 - Using the Repeater Directive/templatesanddata/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/13 - Using the Repeater Directive/templatesanddata/src/assets/logo.png
--------------------------------------------------------------------------------
/13 - Using the Repeater Directive/templatesanddata/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import "bootstrap/dist/css/bootstrap.min.css";
5 |
6 | Vue.config.productionTip = false
7 |
8 | new Vue({
9 | render: h => h(App)
10 | }).$mount('#app')
11 |
--------------------------------------------------------------------------------
/14 - Handling Events/templatesanddata/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/14 - Handling Events/templatesanddata/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "templatesanddata",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "bootstrap": "^4.0.0",
12 | "vue": "^2.5.16"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "^3.0.0-beta.15",
16 | "@vue/cli-plugin-eslint": "^3.0.0-beta.15",
17 | "@vue/cli-service": "^3.0.0-beta.15",
18 | "vue-template-compiler": "^2.5.16"
19 | },
20 | "eslintConfig": {
21 | "root": true,
22 | "env": {
23 | "node": true
24 | },
25 | "extends": [
26 | "plugin:vue/essential",
27 | "eslint:recommended"
28 | ],
29 | "rules": {
30 | "no-console": "off"
31 | },
32 | "parserOptions": {
33 | "parser": "babel-eslint"
34 | }
35 | },
36 | "postcss": {
37 | "plugins": {
38 | "autoprefixer": {}
39 | }
40 | },
41 | "browserslist": [
42 | "> 1%",
43 | "last 2 versions",
44 | "not ie <= 8"
45 | ]
46 | }
47 |
--------------------------------------------------------------------------------
/14 - Handling Events/templatesanddata/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/14 - Handling Events/templatesanddata/public/favicon.ico
--------------------------------------------------------------------------------
/14 - Handling Events/templatesanddata/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | templatesanddata
9 |
10 |
11 |
12 | We're sorry but templatesanddata doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/14 - Handling Events/templatesanddata/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{message}}
5 |
6 |
8 |
9 |
10 |
11 |
26 |
--------------------------------------------------------------------------------
/14 - Handling Events/templatesanddata/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/14 - Handling Events/templatesanddata/src/assets/logo.png
--------------------------------------------------------------------------------
/14 - Handling Events/templatesanddata/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import "bootstrap/dist/css/bootstrap.min.css";
5 |
6 | Vue.config.productionTip = false
7 |
8 | new Vue({
9 | render: h => h(App)
10 | }).$mount('#app')
11 |
--------------------------------------------------------------------------------
/15 - Working with Form Elements/templatesanddata/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/15 - Working with Form Elements/templatesanddata/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "templatesanddata",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "bootstrap": "^4.0.0",
12 | "vue": "^2.5.16"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "^3.0.0-beta.15",
16 | "@vue/cli-plugin-eslint": "^3.0.0-beta.15",
17 | "@vue/cli-service": "^3.0.0-beta.15",
18 | "vue-template-compiler": "^2.5.16"
19 | },
20 | "eslintConfig": {
21 | "root": true,
22 | "env": {
23 | "node": true
24 | },
25 | "extends": [
26 | "plugin:vue/essential",
27 | "eslint:recommended"
28 | ],
29 | "rules": {
30 | "no-console": "off"
31 | },
32 | "parserOptions": {
33 | "parser": "babel-eslint"
34 | }
35 | },
36 | "postcss": {
37 | "plugins": {
38 | "autoprefixer": {}
39 | }
40 | },
41 | "browserslist": [
42 | "> 1%",
43 | "last 2 versions",
44 | "not ie <= 8"
45 | ]
46 | }
47 |
--------------------------------------------------------------------------------
/15 - Working with Form Elements/templatesanddata/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/15 - Working with Form Elements/templatesanddata/public/favicon.ico
--------------------------------------------------------------------------------
/15 - Working with Form Elements/templatesanddata/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | templatesanddata
9 |
10 |
11 |
12 | We're sorry but templatesanddata doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/15 - Working with Form Elements/templatesanddata/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/15 - Working with Form Elements/templatesanddata/src/assets/logo.png
--------------------------------------------------------------------------------
/15 - Working with Form Elements/templatesanddata/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import "bootstrap/dist/css/bootstrap.min.css";
5 |
6 | Vue.config.productionTip = false
7 |
8 | new Vue({
9 | render: h => h(App)
10 | }).$mount('#app')
11 |
--------------------------------------------------------------------------------
/15 - Working with Form Elements/templatesanddata/src/validationRules.js:
--------------------------------------------------------------------------------
1 | function required(name) {
2 | return {
3 | validator: (value) => value != "" && value !== undefined && value !== null,
4 | message: `A value is required for ${name}`
5 | }
6 | }
7 |
8 | function minLength(name, minlength) {
9 | return {
10 | validator: (value) => String(value).length >= minlength,
11 | message: `At least ${minlength} characters are required for ${name}`
12 | }
13 | }
14 |
15 | function alpha(name) {
16 | return {
17 | validator: (value) => /^[a-zA-Z]*$/.test(value),
18 | message: `${name} can only contain letters`
19 | }
20 | }
21 |
22 | function numeric(name) {
23 | return {
24 | validator: (value) => /^[0-9]*$/.test(value),
25 | message: `${name} can only contain digits`
26 | }
27 | }
28 |
29 | function range(name, min, max) {
30 | return {
31 | validator: (value) => value >= min && value <= max,
32 | message: `${name} must be between ${min} and ${max}`
33 | }
34 | }
35 |
36 | export default {
37 | name: [minLength("Name", 3)],
38 | category: [required("Category"), alpha("Category")],
39 | price: [numeric("Price"), range("Price", 1, 1000)]
40 | }
41 |
--------------------------------------------------------------------------------
/16 - Components/templatesanddata/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/16 - Components/templatesanddata/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "templatesanddata",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "bootstrap": "^4.0.0",
12 | "vue": "^2.5.16"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "^3.0.0-beta.15",
16 | "@vue/cli-plugin-eslint": "^3.0.0-beta.15",
17 | "@vue/cli-service": "^3.0.0-beta.15",
18 | "vue-template-compiler": "^2.5.16"
19 | },
20 | "eslintConfig": {
21 | "root": true,
22 | "env": {
23 | "node": true
24 | },
25 | "extends": [
26 | "plugin:vue/essential",
27 | "eslint:recommended"
28 | ],
29 | "rules": {
30 | "no-console": "off"
31 | },
32 | "parserOptions": {
33 | "parser": "babel-eslint"
34 | }
35 | },
36 | "postcss": {
37 | "plugins": {
38 | "autoprefixer": {}
39 | }
40 | },
41 | "browserslist": [
42 | "> 1%",
43 | "last 2 versions",
44 | "not ie <= 8"
45 | ]
46 | }
47 |
--------------------------------------------------------------------------------
/16 - Components/templatesanddata/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/16 - Components/templatesanddata/public/favicon.ico
--------------------------------------------------------------------------------
/16 - Components/templatesanddata/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | templatesanddata
9 |
10 |
11 |
12 | We're sorry but templatesanddata doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/16 - Components/templatesanddata/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/16 - Components/templatesanddata/src/assets/logo.png
--------------------------------------------------------------------------------
/16 - Components/templatesanddata/src/components/Child.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Use the form fields to edit the data
5 |
6 |
7 | Name
8 |
9 |
10 |
11 | Category
12 |
13 |
14 |
15 | Price
16 |
17 |
18 |
19 |
20 | Submit
21 |
22 |
23 |
24 |
25 |
26 |
41 |
--------------------------------------------------------------------------------
/16 - Components/templatesanddata/src/components/ProductDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ prop }}: {{ product[prop] }}
6 |
7 |
8 |
9 |
10 |
11 |
16 |
--------------------------------------------------------------------------------
/16 - Components/templatesanddata/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import "bootstrap/dist/css/bootstrap.min.css";
5 |
6 | Vue.config.productionTip = false
7 |
8 | new Vue({
9 | render: h => h(App)
10 | }).$mount('#app')
11 |
--------------------------------------------------------------------------------
/16 - Components/templatesanddata/src/validationRules.js:
--------------------------------------------------------------------------------
1 | function required(name) {
2 | return {
3 | validator: (value) => value != "" && value !== undefined && value !== null,
4 | message: `A value is required for ${name}`
5 | }
6 | }
7 |
8 | function minLength(name, minlength) {
9 | return {
10 | validator: (value) => String(value).length >= minlength,
11 | message: `At least ${minlength} characters are required for ${name}`
12 | }
13 | }
14 |
15 | function alpha(name) {
16 | return {
17 | validator: (value) => /^[a-zA-Z]*$/.test(value),
18 | message: `${name} can only contain letters`
19 | }
20 | }
21 |
22 | function numeric(name) {
23 | return {
24 | validator: (value) => /^[0-9]*$/.test(value),
25 | message: `${name} can only contain digits`
26 | }
27 | }
28 |
29 | function range(name, min, max) {
30 | return {
31 | validator: (value) => value >= min && value <= max,
32 | message: `${name} must be between ${min} and ${max}`
33 | }
34 | }
35 |
36 | export default {
37 | name: [minLength("Name", 3)],
38 | category: [required("Category"), alpha("Category")],
39 | price: [numeric("Price"), range("Price", 1, 1000)]
40 | }
41 |
--------------------------------------------------------------------------------
/17 - Understanding the Component Lifecycle/lifecycles/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/17 - Understanding the Component Lifecycle/lifecycles/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lifecycles",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "bootstrap": "^4.0.0",
12 | "vue": "^2.5.16"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "^3.0.0-rc.3",
16 | "@vue/cli-plugin-eslint": "^3.0.0-rc.3",
17 | "@vue/cli-service": "^3.0.0-rc.3",
18 | "vue-template-compiler": "^2.5.16"
19 | },
20 | "eslintConfig": {
21 | "root": true,
22 | "env": {
23 | "node": true
24 | },
25 | "extends": [
26 | "plugin:vue/essential",
27 | "eslint:recommended"
28 | ],
29 | "rules": {
30 | "no-console": "off"
31 | },
32 | "parserOptions": {
33 | "parser": "babel-eslint"
34 | }
35 | },
36 | "postcss": {
37 | "plugins": {
38 | "autoprefixer": {}
39 | }
40 | },
41 | "browserslist": [
42 | "> 1%",
43 | "last 2 versions",
44 | "not ie <= 8"
45 | ]
46 | }
47 |
--------------------------------------------------------------------------------
/17 - Understanding the Component Lifecycle/lifecycles/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/17 - Understanding the Component Lifecycle/lifecycles/public/favicon.ico
--------------------------------------------------------------------------------
/17 - Understanding the Component Lifecycle/lifecycles/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | lifecycles
9 |
10 |
11 |
12 | We're sorry but lifecycles doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/17 - Understanding the Component Lifecycle/lifecycles/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | An Error Has Occurred
4 |
5 | Error : "{{ error.error }}" ({{ error.source }})
6 |
7 |
8 |
9 |
10 |
11 | Checkbox
12 |
13 | Checked Value: {{ checked }}
14 |
15 |
16 |
17 |
18 |
19 |
20 |
45 |
--------------------------------------------------------------------------------
/17 - Understanding the Component Lifecycle/lifecycles/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/17 - Understanding the Component Lifecycle/lifecycles/src/assets/logo.png
--------------------------------------------------------------------------------
/17 - Understanding the Component Lifecycle/lifecycles/src/components/MessageDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Counter Value: {{ counter }}
5 |
6 |
7 | Increment
8 |
9 |
10 | Generate Error
11 |
12 |
13 |
14 |
15 |
51 |
--------------------------------------------------------------------------------
/17 - Understanding the Component Lifecycle/lifecycles/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App'
3 |
4 | import "bootstrap/dist/css/bootstrap.min.css";
5 |
6 | Vue.config.productionTip = false
7 |
8 | new Vue({
9 | el: '#app',
10 | components: { App },
11 | template: ' '
12 | })
13 |
--------------------------------------------------------------------------------
/17 - Understanding the Component Lifecycle/lifecycles/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | runtimeCompiler: true
3 | }
4 |
--------------------------------------------------------------------------------
/18 - Loosely-Coupled Components/productapp/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/18 - Loosely-Coupled Components/productapp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "productapp",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "bootstrap": "^4.0.0",
12 | "vue": "^2.5.16"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "^3.0.0-rc.3",
16 | "@vue/cli-plugin-eslint": "^3.0.0-rc.3",
17 | "@vue/cli-service": "^3.0.0-rc.3",
18 | "vue-template-compiler": "^2.5.16"
19 | },
20 | "eslintConfig": {
21 | "root": true,
22 | "env": {
23 | "node": true
24 | },
25 | "extends": [
26 | "plugin:vue/essential",
27 | "eslint:recommended"
28 | ],
29 | "rules": {
30 | "no-console": "off",
31 | "no-unused-vars": "off"
32 | },
33 | "parserOptions": {
34 | "parser": "babel-eslint"
35 | }
36 | },
37 | "postcss": {
38 | "plugins": {
39 | "autoprefixer": {}
40 | }
41 | },
42 | "browserslist": [
43 | "> 1%",
44 | "last 2 versions",
45 | "not ie <= 8"
46 | ]
47 | }
48 |
--------------------------------------------------------------------------------
/18 - Loosely-Coupled Components/productapp/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/18 - Loosely-Coupled Components/productapp/public/favicon.ico
--------------------------------------------------------------------------------
/18 - Loosely-Coupled Components/productapp/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | productapp
9 |
10 |
11 |
12 | We're sorry but productapp doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/18 - Loosely-Coupled Components/productapp/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/18 - Loosely-Coupled Components/productapp/src/assets/logo.png
--------------------------------------------------------------------------------
/18 - Loosely-Coupled Components/productapp/src/components/EditorField.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ formattedLabel }}
5 |
7 |
8 |
9 |
10 |
11 |
42 |
--------------------------------------------------------------------------------
/18 - Loosely-Coupled Components/productapp/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
5 |
6 | Vue.config.productionTip = false
7 |
8 | new Vue({
9 | render: h => h(App),
10 | provide: function () {
11 | return {
12 | eventBus: new Vue()
13 | }
14 | }
15 | }).$mount('#app')
16 |
--------------------------------------------------------------------------------
/19 - Using RESTful Web Services/productapp/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/19 - Using RESTful Web Services/productapp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "productapp",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint",
9 | "json": "json-server restData.js -p 3500"
10 | },
11 | "dependencies": {
12 | "axios": "^0.18.0",
13 | "bootstrap": "^4.0.0",
14 | "json-server": "^0.12.1",
15 | "vue": "^2.5.16"
16 | },
17 | "devDependencies": {
18 | "@vue/cli-plugin-babel": "^3.0.0-rc.3",
19 | "@vue/cli-plugin-eslint": "^3.0.0-rc.3",
20 | "@vue/cli-service": "^3.0.0-rc.3",
21 | "vue-template-compiler": "^2.5.16"
22 | },
23 | "eslintConfig": {
24 | "root": true,
25 | "env": {
26 | "node": true
27 | },
28 | "extends": [
29 | "plugin:vue/essential",
30 | "eslint:recommended"
31 | ],
32 | "rules": {
33 | "no-console": "off",
34 | "no-unused-vars": "off"
35 | },
36 | "parserOptions": {
37 | "parser": "babel-eslint"
38 | }
39 | },
40 | "postcss": {
41 | "plugins": {
42 | "autoprefixer": {}
43 | }
44 | },
45 | "browserslist": [
46 | "> 1%",
47 | "last 2 versions",
48 | "not ie <= 8"
49 | ]
50 | }
51 |
--------------------------------------------------------------------------------
/19 - Using RESTful Web Services/productapp/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/19 - Using RESTful Web Services/productapp/public/favicon.ico
--------------------------------------------------------------------------------
/19 - Using RESTful Web Services/productapp/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | productapp
9 |
10 |
11 |
12 | We're sorry but productapp doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/19 - Using RESTful Web Services/productapp/restData.js:
--------------------------------------------------------------------------------
1 | module.exports = function () {
2 | var data = {
3 | products: [
4 | { id: 1, name: "Kayak", category: "Watersports", price: 275 },
5 | { id: 2, name: "Lifejacket", category: "Watersports", price: 48.95 },
6 | { id: 3, name: "Soccer Ball", category: "Soccer", price: 19.50 },
7 | { id: 4, name: "Corner Flags", category: "Soccer", price: 34.95 },
8 | { id: 5, name: "Stadium", category: "Soccer", price: 79500 },
9 | { id: 6, name: "Thinking Cap", category: "Chess", price: 16 },
10 | { id: 7, name: "Unsteady Chair", category: "Chess", price: 29.95 },
11 | { id: 8, name: "Human Chess Board", category: "Chess", price: 75 },
12 | { id: 9, name: "Bling Bling King", category: "Chess", price: 1200 }
13 | ]
14 | }
15 | return data
16 | }
17 |
--------------------------------------------------------------------------------
/19 - Using RESTful Web Services/productapp/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
23 |
--------------------------------------------------------------------------------
/19 - Using RESTful Web Services/productapp/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/19 - Using RESTful Web Services/productapp/src/assets/logo.png
--------------------------------------------------------------------------------
/19 - Using RESTful Web Services/productapp/src/components/EditorField.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ formattedLabel }}
5 |
7 |
8 |
9 |
10 |
11 |
42 |
--------------------------------------------------------------------------------
/19 - Using RESTful Web Services/productapp/src/components/ErrorDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | An Error Has Occurred
4 |
{{ message }}
5 |
OK
6 |
7 |
8 |
9 |
30 |
--------------------------------------------------------------------------------
/19 - Using RESTful Web Services/productapp/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
5 | import { RestDataSource } from "./restDataSource";
6 |
7 | Vue.config.productionTip = false
8 |
9 | new Vue({
10 | render: h => h(App),
11 | data: {
12 | eventBus: new Vue()
13 | },
14 | provide: function () {
15 | return {
16 | eventBus: this.eventBus,
17 | restDataSource: new RestDataSource(this.eventBus)
18 | }
19 | }
20 | }).$mount('#app')
21 |
--------------------------------------------------------------------------------
/19 - Using RESTful Web Services/productapp/src/restDataSource.js:
--------------------------------------------------------------------------------
1 | import Axios from "axios";
2 |
3 | const baseUrl = "http://localhost:3500/products/";
4 |
5 | export class RestDataSource {
6 |
7 | constructor(bus) {
8 | this.eventBus = bus;
9 | }
10 |
11 | async getProducts() {
12 | return (await this.sendRequest("GET", baseUrl)).data;
13 | }
14 |
15 | async saveProduct(product) {
16 | await this.sendRequest("POST", baseUrl, product);
17 | }
18 |
19 | async updateProduct(product) {
20 | await this.sendRequest("PUT", `${baseUrl}${product.id}`, product);
21 | }
22 |
23 | async deleteProduct(product) {
24 | await this.sendRequest("DELETE", `${baseUrl}${product.id}`, product);
25 | }
26 |
27 | async sendRequest(httpMethod, url, product) {
28 | try {
29 | return await Axios.request({
30 | method: httpMethod,
31 | url: url,
32 | data: product
33 | });
34 | } catch (err) {
35 | if (err.response) {
36 | this.eventBus.$emit("httpError",
37 | `${err.response.statusText} - ${err.response.status}`);
38 | } else {
39 | this.eventBus.$emit("httpError", "HTTP Error");
40 | }
41 | throw err;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/20 - Using a Data Store/productapp/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/20 - Using a Data Store/productapp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "productapp",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint",
9 | "json": "json-server restData.js -p 3500"
10 | },
11 | "dependencies": {
12 | "axios": "^0.18.0",
13 | "bootstrap": "^4.0.0",
14 | "json-server": "^0.12.1",
15 | "vue": "^2.5.16",
16 | "vuex": "^3.0.1"
17 | },
18 | "devDependencies": {
19 | "@vue/cli-plugin-babel": "^3.0.0-rc.3",
20 | "@vue/cli-plugin-eslint": "^3.0.0-rc.3",
21 | "@vue/cli-service": "^3.0.0-rc.3",
22 | "vue-template-compiler": "^2.5.16"
23 | },
24 | "eslintConfig": {
25 | "root": true,
26 | "env": {
27 | "node": true
28 | },
29 | "extends": [
30 | "plugin:vue/essential",
31 | "eslint:recommended"
32 | ],
33 | "rules": {
34 | "no-console": "off",
35 | "no-unused-vars": "off"
36 | },
37 | "parserOptions": {
38 | "parser": "babel-eslint"
39 | }
40 | },
41 | "postcss": {
42 | "plugins": {
43 | "autoprefixer": {}
44 | }
45 | },
46 | "browserslist": [
47 | "> 1%",
48 | "last 2 versions",
49 | "not ie <= 8"
50 | ]
51 | }
52 |
--------------------------------------------------------------------------------
/20 - Using a Data Store/productapp/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/20 - Using a Data Store/productapp/public/favicon.ico
--------------------------------------------------------------------------------
/20 - Using a Data Store/productapp/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | productapp
9 |
10 |
11 |
12 | We're sorry but productapp doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/20 - Using a Data Store/productapp/restData.js:
--------------------------------------------------------------------------------
1 | module.exports = function () {
2 | var data = {
3 | products: [
4 | { id: 1, name: "Kayak", category: "Watersports", price: 275 },
5 | { id: 2, name: "Lifejacket", category: "Watersports", price: 48.95 },
6 | { id: 3, name: "Soccer Ball", category: "Soccer", price: 19.50 },
7 | { id: 4, name: "Corner Flags", category: "Soccer", price: 34.95 },
8 | { id: 5, name: "Stadium", category: "Soccer", price: 79500 },
9 | { id: 6, name: "Thinking Cap", category: "Chess", price: 16 },
10 | { id: 7, name: "Unsteady Chair", category: "Chess", price: 29.95 },
11 | { id: 8, name: "Human Chess Board", category: "Chess", price: 75 },
12 | { id: 9, name: "Bling Bling King", category: "Chess", price: 1200 }
13 | ]
14 | }
15 | return data
16 | }
17 |
--------------------------------------------------------------------------------
/20 - Using a Data Store/productapp/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
23 |
--------------------------------------------------------------------------------
/20 - Using a Data Store/productapp/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/20 - Using a Data Store/productapp/src/assets/logo.png
--------------------------------------------------------------------------------
/20 - Using a Data Store/productapp/src/components/EditorField.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ formattedLabel }}
5 |
7 |
8 |
9 |
10 |
11 |
42 |
--------------------------------------------------------------------------------
/20 - Using a Data Store/productapp/src/components/ErrorDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | An Error Has Occurred
4 |
{{ message }}
5 |
OK
6 |
7 |
8 |
9 |
30 |
--------------------------------------------------------------------------------
/20 - Using a Data Store/productapp/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
5 | import { RestDataSource } from "./restDataSource";
6 | import store from "./store";
7 |
8 | Vue.config.productionTip = false
9 |
10 | new Vue({
11 | render: h => h(App),
12 | data: {
13 | eventBus: new Vue()
14 | },
15 | store,
16 | provide: function () {
17 | return {
18 | eventBus: this.eventBus,
19 | restDataSource: new RestDataSource(this.eventBus)
20 | }
21 | }
22 | }).$mount('#app')
23 |
--------------------------------------------------------------------------------
/20 - Using a Data Store/productapp/src/restDataSource.js:
--------------------------------------------------------------------------------
1 | import Axios from "axios";
2 |
3 | const baseUrl = "http://localhost:3500/products/";
4 |
5 | export class RestDataSource {
6 |
7 | constructor(bus) {
8 | this.eventBus = bus;
9 | }
10 |
11 | async getProducts() {
12 | return (await this.sendRequest("GET", baseUrl)).data;
13 | }
14 |
15 | async saveProduct(product) {
16 | await this.sendRequest("POST", baseUrl, product);
17 | }
18 |
19 | async updateProduct(product) {
20 | await this.sendRequest("PUT", `${baseUrl}${product.id}`, product);
21 | }
22 |
23 | async deleteProduct(product) {
24 | await this.sendRequest("DELETE", `${baseUrl}${product.id}`, product);
25 | }
26 |
27 | async sendRequest(httpMethod, url, product) {
28 | try {
29 | return await Axios.request({
30 | method: httpMethod,
31 | url: url,
32 | data: product
33 | });
34 | } catch (err) {
35 | if (err.response) {
36 | this.eventBus.$emit("httpError",
37 | `${err.response.statusText} - ${err.response.status}`);
38 | } else {
39 | this.eventBus.$emit("httpError", "HTTP Error");
40 | }
41 | throw err;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/20 - Using a Data Store/productapp/src/store/preferences.js:
--------------------------------------------------------------------------------
1 | export default {
2 | namespaced: true,
3 | state: {
4 | stripedTable: true,
5 | primaryEditButton: false,
6 | dangerDeleteButton: false
7 | },
8 | getters: {
9 | editClass(state) {
10 | return state.primaryEditButton ? "btn-primary" : "btn-secondary";
11 | },
12 | deleteClass(state) {
13 | return state.dangerDeleteButton ? "btn-danger" : "btn-secondary";
14 | },
15 | tableClass(state, payload, rootState) {
16 | return rootState.products.length > 0
17 | && rootState.products[0].price > 500 ? "table-striped" : ""
18 | }
19 | },
20 | mutations: {
21 | setEditButtonColor(currentState, primary) {
22 | currentState.primaryEditButton = primary;
23 | },
24 | setDeleteButtonColor(currentState, danger) {
25 | currentState.dangerDeleteButton = danger;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/21 - Dynamic Components/productapp/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/21 - Dynamic Components/productapp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "productapp",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint",
9 | "json": "json-server restData.js -p 3500"
10 | },
11 | "dependencies": {
12 | "axios": "^0.18.0",
13 | "bootstrap": "^4.0.0",
14 | "json-server": "^0.12.1",
15 | "vue": "^2.5.16",
16 | "vuex": "^3.0.1"
17 | },
18 | "devDependencies": {
19 | "@vue/cli-plugin-babel": "^3.0.0-rc.3",
20 | "@vue/cli-plugin-eslint": "^3.0.0-rc.3",
21 | "@vue/cli-service": "^3.0.0-rc.3",
22 | "vue-template-compiler": "^2.5.16"
23 | },
24 | "eslintConfig": {
25 | "root": true,
26 | "env": {
27 | "node": true
28 | },
29 | "extends": [
30 | "plugin:vue/essential",
31 | "eslint:recommended"
32 | ],
33 | "rules": {
34 | "no-console": "off",
35 | "no-unused-vars": "off"
36 | },
37 | "parserOptions": {
38 | "parser": "babel-eslint"
39 | }
40 | },
41 | "postcss": {
42 | "plugins": {
43 | "autoprefixer": {}
44 | }
45 | },
46 | "browserslist": [
47 | "> 1%",
48 | "last 2 versions",
49 | "not ie <= 8"
50 | ]
51 | }
52 |
--------------------------------------------------------------------------------
/21 - Dynamic Components/productapp/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/21 - Dynamic Components/productapp/public/favicon.ico
--------------------------------------------------------------------------------
/21 - Dynamic Components/productapp/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | productapp
9 |
10 |
11 |
12 | We're sorry but productapp doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/21 - Dynamic Components/productapp/restData.js:
--------------------------------------------------------------------------------
1 | module.exports = function () {
2 | var data = {
3 | products: [
4 | { id: 1, name: "Kayak", category: "Watersports", price: 275 },
5 | { id: 2, name: "Lifejacket", category: "Watersports", price: 48.95 },
6 | { id: 3, name: "Soccer Ball", category: "Soccer", price: 19.50 },
7 | { id: 4, name: "Corner Flags", category: "Soccer", price: 34.95 },
8 | { id: 5, name: "Stadium", category: "Soccer", price: 79500 },
9 | { id: 6, name: "Thinking Cap", category: "Chess", price: 16 },
10 | { id: 7, name: "Unsteady Chair", category: "Chess", price: 29.95 },
11 | { id: 8, name: "Human Chess Board", category: "Chess", price: 75 },
12 | { id: 9, name: "Bling Bling King", category: "Chess", price: 1200 }
13 | ]
14 | }
15 | return data
16 | }
17 |
--------------------------------------------------------------------------------
/21 - Dynamic Components/productapp/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/21 - Dynamic Components/productapp/src/assets/logo.png
--------------------------------------------------------------------------------
/21 - Dynamic Components/productapp/src/components/EditorField.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ formattedLabel }}
5 |
7 |
8 |
9 |
10 |
11 |
42 |
--------------------------------------------------------------------------------
/21 - Dynamic Components/productapp/src/components/ErrorDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | An Error Has Occurred
4 |
{{ message }}
5 |
OK
6 |
7 |
8 |
9 |
30 |
--------------------------------------------------------------------------------
/21 - Dynamic Components/productapp/src/components/LoadingMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Lazily Loading Component...
4 |
5 |
6 |
--------------------------------------------------------------------------------
/21 - Dynamic Components/productapp/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
5 | import { RestDataSource } from "./restDataSource";
6 | import store from "./store";
7 |
8 | Vue.config.productionTip = false
9 |
10 | new Vue({
11 | render: h => h(App),
12 | data: {
13 | eventBus: new Vue()
14 | },
15 | store,
16 | provide: function () {
17 | return {
18 | eventBus: this.eventBus,
19 | restDataSource: new RestDataSource(this.eventBus)
20 | }
21 | }
22 | }).$mount('#app')
23 |
--------------------------------------------------------------------------------
/21 - Dynamic Components/productapp/src/restDataSource.js:
--------------------------------------------------------------------------------
1 | import Axios from "axios";
2 |
3 | const baseUrl = "http://localhost:3500/products/";
4 |
5 | export class RestDataSource {
6 |
7 | constructor(bus) {
8 | this.eventBus = bus;
9 | }
10 |
11 | async getProducts() {
12 | return (await this.sendRequest("GET", baseUrl)).data;
13 | }
14 |
15 | async saveProduct(product) {
16 | await this.sendRequest("POST", baseUrl, product);
17 | }
18 |
19 | async updateProduct(product) {
20 | await this.sendRequest("PUT", `${baseUrl}${product.id}`, product);
21 | }
22 |
23 | async deleteProduct(product) {
24 | await this.sendRequest("DELETE", `${baseUrl}${product.id}`, product);
25 | }
26 |
27 | async sendRequest(httpMethod, url, product) {
28 | try {
29 | return await Axios.request({
30 | method: httpMethod,
31 | url: url,
32 | data: product
33 | });
34 | } catch (err) {
35 | if (err.response) {
36 | this.eventBus.$emit("httpError",
37 | `${err.response.statusText} - ${err.response.status}`);
38 | } else {
39 | this.eventBus.$emit("httpError", "HTTP Error");
40 | }
41 | throw err;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/21 - Dynamic Components/productapp/src/store/navigation.js:
--------------------------------------------------------------------------------
1 | export default {
2 | namespaced: true,
3 | state: {
4 | selected: "table"
5 | }
6 | ,
7 | mutations: {
8 | selectComponent(currentState, selection) {
9 | currentState.selected = selection;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/21 - Dynamic Components/productapp/src/store/preferences.js:
--------------------------------------------------------------------------------
1 | export default {
2 | namespaced: true,
3 | state: {
4 | stripedTable: true,
5 | primaryEditButton: false,
6 | dangerDeleteButton: false
7 | },
8 | getters: {
9 | editClass(state) {
10 | return state.primaryEditButton ? "btn-primary" : "btn-secondary";
11 | },
12 | deleteClass(state) {
13 | return state.dangerDeleteButton ? "btn-danger" : "btn-secondary";
14 | },
15 | tableClass(state, payload, rootState) {
16 | return rootState.products.length > 0
17 | && rootState.products[0].price > 500 ? "table-striped" : ""
18 | }
19 | },
20 | mutations: {
21 | setEditButtonColor(currentState, primary) {
22 | currentState.primaryEditButton = primary;
23 | },
24 | setDeleteButtonColor(currentState, danger) {
25 | currentState.dangerDeleteButton = danger;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/21 - Dynamic Components/productapp/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | chainWebpack: config => {
3 | config.plugins.delete('prefetch');
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "productapp",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint",
9 | "json": "json-server restData.js -p 3500"
10 | },
11 | "dependencies": {
12 | "axios": "^0.18.0",
13 | "bootstrap": "^4.0.0",
14 | "json-server": "^0.12.1",
15 | "vue": "^2.5.16",
16 | "vue-router": "^3.0.1",
17 | "vuex": "^3.0.1"
18 | },
19 | "devDependencies": {
20 | "@vue/cli-plugin-babel": "^3.0.0-rc.3",
21 | "@vue/cli-plugin-eslint": "^3.0.0-rc.3",
22 | "@vue/cli-service": "^3.0.0-rc.3",
23 | "vue-template-compiler": "^2.5.16"
24 | },
25 | "eslintConfig": {
26 | "root": true,
27 | "env": {
28 | "node": true
29 | },
30 | "extends": [
31 | "plugin:vue/essential",
32 | "eslint:recommended"
33 | ],
34 | "rules": {
35 | "no-console": "off",
36 | "no-unused-vars": "off"
37 | },
38 | "parserOptions": {
39 | "parser": "babel-eslint"
40 | }
41 | },
42 | "postcss": {
43 | "plugins": {
44 | "autoprefixer": {}
45 | }
46 | },
47 | "browserslist": [
48 | "> 1%",
49 | "last 2 versions",
50 | "not ie <= 8"
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/22 - URL Routing/productapp/public/favicon.ico
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | productapp
9 |
10 |
11 |
12 | We're sorry but productapp doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/restData.js:
--------------------------------------------------------------------------------
1 | module.exports = function () {
2 | var data = {
3 | products: [
4 | { id: 1, name: "Kayak", category: "Watersports", price: 275 },
5 | { id: 2, name: "Lifejacket", category: "Watersports", price: 48.95 },
6 | { id: 3, name: "Soccer Ball", category: "Soccer", price: 19.50 },
7 | { id: 4, name: "Corner Flags", category: "Soccer", price: 34.95 },
8 | { id: 5, name: "Stadium", category: "Soccer", price: 79500 },
9 | { id: 6, name: "Thinking Cap", category: "Chess", price: 16 },
10 | { id: 7, name: "Unsteady Chair", category: "Chess", price: 29.95 },
11 | { id: 8, name: "Human Chess Board", category: "Chess", price: 75 },
12 | { id: 9, name: "Bling Bling King", category: "Chess", price: 1200 }
13 | ]
14 | }
15 | return data
16 | }
17 |
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
34 |
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/22 - URL Routing/productapp/src/assets/logo.png
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/src/components/EditorField.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ formattedLabel }}
5 |
7 |
8 |
9 |
10 |
11 |
42 |
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/src/components/ErrorDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | An Error Has Occurred
4 |
{{ message }}
5 |
OK
6 |
7 |
8 |
9 |
30 |
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/src/components/LoadingMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Lazily Loading Component...
4 |
5 |
6 |
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
5 | import { RestDataSource } from "./restDataSource";
6 | import store from "./store";
7 | import router from "./router";
8 |
9 | Vue.config.productionTip = false
10 |
11 | new Vue({
12 | render: h => h(App),
13 | data: {
14 | eventBus: new Vue()
15 | },
16 | store,
17 | router,
18 | provide: function () {
19 | return {
20 | eventBus: this.eventBus,
21 | restDataSource: new RestDataSource(this.eventBus)
22 | }
23 | }
24 | }).$mount('#app')
25 |
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/src/restDataSource.js:
--------------------------------------------------------------------------------
1 | import Axios from "axios";
2 |
3 | const baseUrl = "http://localhost:3500/products/";
4 |
5 | export class RestDataSource {
6 |
7 | constructor(bus) {
8 | this.eventBus = bus;
9 | }
10 |
11 | async getProducts() {
12 | return (await this.sendRequest("GET", baseUrl)).data;
13 | }
14 |
15 | async saveProduct(product) {
16 | await this.sendRequest("POST", baseUrl, product);
17 | }
18 |
19 | async updateProduct(product) {
20 | await this.sendRequest("PUT", `${baseUrl}${product.id}`, product);
21 | }
22 |
23 | async deleteProduct(product) {
24 | await this.sendRequest("DELETE", `${baseUrl}${product.id}`, product);
25 | }
26 |
27 | async sendRequest(httpMethod, url, product) {
28 | try {
29 | return await Axios.request({
30 | method: httpMethod,
31 | url: url,
32 | data: product
33 | });
34 | } catch (err) {
35 | if (err.response) {
36 | this.eventBus.$emit("httpError",
37 | `${err.response.statusText} - ${err.response.status}`);
38 | } else {
39 | this.eventBus.$emit("httpError", "HTTP Error");
40 | }
41 | throw err;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import VueRouter from "vue-router";
3 |
4 | import ProductDisplay from "../components/ProductDisplay";
5 | import ProductEditor from "../components/ProductEditor";
6 |
7 | Vue.use(VueRouter);
8 |
9 | export default new VueRouter({
10 | mode: "history",
11 | routes: [
12 | { name: "table", path: "/", component: ProductDisplay, alias: "/list" },
13 | { name: "editor", path: "/:op(create|edit)/:id(\\d+)?",
14 | component: ProductEditor },
15 | { path: "*", redirect: "/" }
16 | ]
17 | })
18 |
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/src/store/navigation.js:
--------------------------------------------------------------------------------
1 | export default {
2 | namespaced: true,
3 | state: {
4 | selected: "table"
5 | }
6 | ,
7 | mutations: {
8 | selectComponent(currentState, selection) {
9 | currentState.selected = selection;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/src/store/preferences.js:
--------------------------------------------------------------------------------
1 | export default {
2 | namespaced: true,
3 | state: {
4 | stripedTable: true,
5 | primaryEditButton: false,
6 | dangerDeleteButton: false
7 | },
8 | getters: {
9 | editClass(state) {
10 | return state.primaryEditButton ? "btn-primary" : "btn-secondary";
11 | },
12 | deleteClass(state) {
13 | return state.dangerDeleteButton ? "btn-danger" : "btn-secondary";
14 | },
15 | tableClass(state, payload, rootState) {
16 | return rootState.products.length > 0
17 | && rootState.products[0].price > 500 ? "table-striped" : ""
18 | }
19 | },
20 | mutations: {
21 | setEditButtonColor(currentState, primary) {
22 | currentState.primaryEditButton = primary;
23 | },
24 | setDeleteButtonColor(currentState, danger) {
25 | currentState.dangerDeleteButton = danger;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/22 - URL Routing/productapp/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | chainWebpack: config => {
3 | config.plugins.delete('prefetch');
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "productapp",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint",
9 | "json": "json-server restData.js -p 3500"
10 | },
11 | "dependencies": {
12 | "axios": "^0.18.0",
13 | "bootstrap": "^4.0.0",
14 | "json-server": "^0.12.1",
15 | "vue": "^2.5.16",
16 | "vue-router": "^3.0.1",
17 | "vuex": "^3.0.1"
18 | },
19 | "devDependencies": {
20 | "@vue/cli-plugin-babel": "^3.0.0-rc.3",
21 | "@vue/cli-plugin-eslint": "^3.0.0-rc.3",
22 | "@vue/cli-service": "^3.0.0-rc.3",
23 | "vue-template-compiler": "^2.5.16"
24 | },
25 | "eslintConfig": {
26 | "root": true,
27 | "env": {
28 | "node": true
29 | },
30 | "extends": [
31 | "plugin:vue/essential",
32 | "eslint:recommended"
33 | ],
34 | "rules": {
35 | "no-console": "off",
36 | "no-unused-vars": "off"
37 | },
38 | "parserOptions": {
39 | "parser": "babel-eslint"
40 | }
41 | },
42 | "postcss": {
43 | "plugins": {
44 | "autoprefixer": {}
45 | }
46 | },
47 | "browserslist": [
48 | "> 1%",
49 | "last 2 versions",
50 | "not ie <= 8"
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/23 - URL Routing Elements/productapp/public/favicon.ico
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | productapp
9 |
10 |
11 |
12 | We're sorry but productapp doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/restData.js:
--------------------------------------------------------------------------------
1 | module.exports = function () {
2 | var data = {
3 | products: [
4 | { id: 1, name: "Kayak", category: "Watersports", price: 275 },
5 | { id: 2, name: "Lifejacket", category: "Watersports", price: 48.95 },
6 | { id: 3, name: "Soccer Ball", category: "Soccer", price: 19.50 },
7 | { id: 4, name: "Corner Flags", category: "Soccer", price: 34.95 },
8 | { id: 5, name: "Stadium", category: "Soccer", price: 79500 },
9 | { id: 6, name: "Thinking Cap", category: "Chess", price: 16 },
10 | { id: 7, name: "Unsteady Chair", category: "Chess", price: 29.95 },
11 | { id: 8, name: "Human Chess Board", category: "Chess", price: 75 },
12 | { id: 9, name: "Bling Bling King", category: "Chess", price: 1200 }
13 | ]
14 | }
15 | return data
16 | }
17 |
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
8 | Products
9 |
10 |
12 | Preferences
13 |
14 |
16 | Table Left
17 |
18 |
20 | Table Right
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
42 |
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/23 - URL Routing Elements/productapp/src/assets/logo.png
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/src/components/EditorField.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ formattedLabel }}
5 |
7 |
8 |
9 |
10 |
11 |
42 |
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/src/components/ErrorDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | An Error Has Occurred
4 |
{{ message }}
5 |
OK
6 |
7 |
8 |
9 |
30 |
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/src/components/LoadingMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Lazily Loading Component...
4 |
5 |
6 |
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/src/components/Preferences.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Preferences
4 |
5 |
7 | Primary Color for Edit Buttons
8 |
9 |
10 |
12 | Danger Color for Delete Buttons
13 |
14 |
15 |
16 |
17 |
38 |
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/src/components/Products.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/src/components/SideBySide.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Left View
6 |
7 |
8 |
9 |
Right View
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
5 | import { RestDataSource } from "./restDataSource";
6 | import store from "./store";
7 | import router from "./router";
8 |
9 | Vue.config.productionTip = false
10 |
11 | new Vue({
12 | render: h => h(App),
13 | data: {
14 | eventBus: new Vue()
15 | },
16 | store,
17 | router,
18 | provide: function () {
19 | return {
20 | eventBus: this.eventBus,
21 | restDataSource: new RestDataSource(this.eventBus)
22 | }
23 | }
24 | }).$mount('#app')
25 |
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/src/restDataSource.js:
--------------------------------------------------------------------------------
1 | import Axios from "axios";
2 |
3 | const baseUrl = "http://localhost:3500/products/";
4 |
5 | export class RestDataSource {
6 |
7 | constructor(bus) {
8 | this.eventBus = bus;
9 | }
10 |
11 | async getProducts() {
12 | return (await this.sendRequest("GET", baseUrl)).data;
13 | }
14 |
15 | async saveProduct(product) {
16 | await this.sendRequest("POST", baseUrl, product);
17 | }
18 |
19 | async updateProduct(product) {
20 | await this.sendRequest("PUT", `${baseUrl}${product.id}`, product);
21 | }
22 |
23 | async deleteProduct(product) {
24 | await this.sendRequest("DELETE", `${baseUrl}${product.id}`, product);
25 | }
26 |
27 | async sendRequest(httpMethod, url, product) {
28 | try {
29 | return await Axios.request({
30 | method: httpMethod,
31 | url: url,
32 | data: product
33 | });
34 | } catch (err) {
35 | if (err.response) {
36 | this.eventBus.$emit("httpError",
37 | `${err.response.statusText} - ${err.response.status}`);
38 | } else {
39 | this.eventBus.$emit("httpError", "HTTP Error");
40 | }
41 | throw err;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/src/store/navigation.js:
--------------------------------------------------------------------------------
1 | export default {
2 | namespaced: true,
3 | state: {
4 | selected: "table"
5 | }
6 | ,
7 | mutations: {
8 | selectComponent(currentState, selection) {
9 | currentState.selected = selection;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/src/store/preferences.js:
--------------------------------------------------------------------------------
1 | export default {
2 | namespaced: true,
3 | state: {
4 | stripedTable: true,
5 | primaryEditButton: false,
6 | dangerDeleteButton: false
7 | },
8 | getters: {
9 | editClass(state) {
10 | return state.primaryEditButton ? "btn-primary" : "btn-secondary";
11 | },
12 | deleteClass(state) {
13 | return state.dangerDeleteButton ? "btn-danger" : "btn-secondary";
14 | },
15 | tableClass(state, payload, rootState) {
16 | return rootState.products.length > 0
17 | && rootState.products[0].price > 500 ? "table-striped" : ""
18 | }
19 | },
20 | mutations: {
21 | setEditButtonColor(currentState, primary) {
22 | currentState.primaryEditButton = primary;
23 | },
24 | setDeleteButtonColor(currentState, danger) {
25 | currentState.dangerDeleteButton = danger;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/23 - URL Routing Elements/productapp/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | chainWebpack: config => {
3 | config.plugins.delete('prefetch');
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "productapp",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint",
9 | "json": "json-server restData.js -p 3500"
10 | },
11 | "dependencies": {
12 | "axios": "^0.18.0",
13 | "bootstrap": "^4.0.0",
14 | "json-server": "^0.12.1",
15 | "vue": "^2.5.16",
16 | "vue-router": "^3.0.1",
17 | "vuex": "^3.0.1"
18 | },
19 | "devDependencies": {
20 | "@vue/cli-plugin-babel": "^3.0.0-rc.3",
21 | "@vue/cli-plugin-eslint": "^3.0.0-rc.3",
22 | "@vue/cli-service": "^3.0.0-rc.3",
23 | "vue-template-compiler": "^2.5.16"
24 | },
25 | "eslintConfig": {
26 | "root": true,
27 | "env": {
28 | "node": true
29 | },
30 | "extends": [
31 | "plugin:vue/essential",
32 | "eslint:recommended"
33 | ],
34 | "rules": {
35 | "no-console": "off",
36 | "no-unused-vars": "off"
37 | },
38 | "parserOptions": {
39 | "parser": "babel-eslint"
40 | }
41 | },
42 | "postcss": {
43 | "plugins": {
44 | "autoprefixer": {}
45 | }
46 | },
47 | "browserslist": [
48 | "> 1%",
49 | "last 2 versions",
50 | "not ie <= 8"
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/24 - Advanced URL Routing/productapp/public/favicon.ico
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | productapp
9 |
10 |
11 |
12 | We're sorry but productapp doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/restData.js:
--------------------------------------------------------------------------------
1 | module.exports = function () {
2 | var data = {
3 | products: [
4 | { id: 1, name: "Kayak", category: "Watersports", price: 275 },
5 | { id: 2, name: "Lifejacket", category: "Watersports", price: 48.95 },
6 | { id: 3, name: "Soccer Ball", category: "Soccer", price: 19.50 },
7 | { id: 4, name: "Corner Flags", category: "Soccer", price: 34.95 },
8 | { id: 5, name: "Stadium", category: "Soccer", price: 79500 },
9 | { id: 6, name: "Thinking Cap", category: "Chess", price: 16 },
10 | { id: 7, name: "Unsteady Chair", category: "Chess", price: 29.95 },
11 | { id: 8, name: "Human Chess Board", category: "Chess", price: 75 },
12 | { id: 9, name: "Bling Bling King", category: "Chess", price: 1200 }
13 | ]
14 | }
15 | return data
16 | }
17 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/24 - Advanced URL Routing/productapp/src/assets/logo.png
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/src/components/EditorField.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ formattedLabel }}
5 |
7 |
8 |
9 |
10 |
11 |
42 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/src/components/ErrorDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | An Error Has Occurred
4 |
{{ message }}
5 |
OK
6 |
7 |
8 |
9 |
30 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/src/components/LoadingMessage.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Lazily Loading Component...
4 |
5 |
6 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/src/components/MessageDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | Message: {{ message }}
4 |
5 |
6 |
7 |
12 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/src/components/Products.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/src/components/SideBySide.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Left View
6 |
7 |
8 |
9 |
Right View
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
5 | import { RestDataSource } from "./restDataSource";
6 | import store from "./store";
7 | import router from "./router";
8 |
9 | Vue.config.productionTip = false
10 |
11 | new Vue({
12 | render: h => h(App),
13 | data: {
14 | eventBus: new Vue()
15 | },
16 | store,
17 | router,
18 | provide: function () {
19 | return {
20 | eventBus: this.eventBus,
21 | restDataSource: new RestDataSource(this.eventBus)
22 | }
23 | }
24 | }).$mount('#app')
25 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/src/restDataSource.js:
--------------------------------------------------------------------------------
1 | import Axios from "axios";
2 |
3 | const baseUrl = "http://localhost:3500/products/";
4 |
5 | export class RestDataSource {
6 |
7 | constructor(bus) {
8 | this.eventBus = bus;
9 | }
10 |
11 | async getProducts() {
12 | return (await this.sendRequest("GET", baseUrl)).data;
13 | }
14 |
15 | async saveProduct(product) {
16 | await this.sendRequest("POST", baseUrl, product);
17 | }
18 |
19 | async updateProduct(product) {
20 | await this.sendRequest("PUT", `${baseUrl}${product.id}`, product);
21 | }
22 |
23 | async deleteProduct(product) {
24 | await this.sendRequest("DELETE", `${baseUrl}${product.id}`, product);
25 | }
26 |
27 | async sendRequest(httpMethod, url, product) {
28 | try {
29 | return await Axios.request({
30 | method: httpMethod,
31 | url: url,
32 | data: product
33 | });
34 | } catch (err) {
35 | if (err.response) {
36 | this.eventBus.$emit("httpError",
37 | `${err.response.statusText} - ${err.response.status}`);
38 | } else {
39 | this.eventBus.$emit("httpError", "HTTP Error");
40 | }
41 | throw err;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/src/router/basicRoutes.js:
--------------------------------------------------------------------------------
1 | import ProductDisplay from "../components/ProductDisplay";
2 | import ProductEditor from "../components/ProductEditor";
3 | import Preferences from "../components/Preferences";
4 | import Products from "../components/Products";
5 | import MessageDisplay from "../components/MessageDisplay";
6 |
7 | const FilteredData = () => import("../components/FilteredData");
8 |
9 | import dataStore from "../store";
10 |
11 | export default [
12 |
13 | { path: "/preferences", component: Preferences },
14 | {
15 | path: "/products", component: Products,
16 | children: [{ name: "table", path: "list", component: ProductDisplay },
17 | {
18 | name: "editor", path: ":op(create|edit)/:id(\\d+)?",
19 | component: ProductEditor
20 | },
21 | { path: "", redirect: "list" }]
22 | },
23 | { path: "/edit/:id", redirect: to => `/products/edit/${to.params.id}` },
24 | { path: "/filter/:category", component: FilteredData,
25 | beforeEnter: (to, from, next) => {
26 | dataStore.commit("setComponentLoading", true);
27 | next();
28 | }
29 | },
30 | { path: "/hello", component: MessageDisplay, props: { message: "Hello, Adam"}},
31 | { path: "/hello/:text", component: MessageDisplay,
32 | props: (route) => ({ message: `Hello, ${route.params.text}`})},
33 | { path: "/message/:message", component: MessageDisplay, props: true},
34 | ]
35 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import VueRouter from "vue-router";
3 |
4 | import BasicRoutes from "./basicRoutes";
5 | import SideBySideRoutes from "./sideBySideRoutes";
6 |
7 | Vue.use(VueRouter);
8 |
9 | const router = new VueRouter({
10 | mode: "history",
11 | routes: [
12 | ...BasicRoutes,
13 | SideBySideRoutes,
14 | { path: "*", redirect: "/products" }
15 | ]
16 | });
17 |
18 | export default router;
19 |
20 | router.beforeEach((to, from, next) => {
21 | if (to.path == "/preferences" && from.path.startsWith("/named")) {
22 | next(false);
23 | } else {
24 | next();
25 | }
26 | });
27 |
28 | router.beforeResolve((to, from, next) => {
29 | if (to.path == "/named/tableright") {
30 | next({ name: "editor", params: { op: "edit", id: 1} });
31 | } else {
32 | next();
33 | }
34 | })
35 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/src/router/sideBySideRoutes.js:
--------------------------------------------------------------------------------
1 | import ProductDisplay from "../components/ProductDisplay";
2 | import ProductEditor from "../components/ProductEditor";
3 | import SideBySide from "../components/SideBySide";
4 |
5 | export default {
6 |
7 | path: "/named", component: SideBySide,
8 | children: [
9 | {
10 | path: "tableleft",
11 | components: { left: ProductDisplay, right: ProductEditor }
12 | },
13 | {
14 | path: "tableright",
15 | components: { left: ProductEditor, right: ProductDisplay },
16 | beforeEnter: (to, from, next) => {
17 | next("/products/list");
18 | }
19 | }
20 | ],
21 | beforeEnter: (to, from, next) => {
22 | if (to.path == "/named/tableleft") {
23 | next("/preferences");
24 | } else {
25 | next();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/src/store/navigation.js:
--------------------------------------------------------------------------------
1 | export default {
2 | namespaced: true,
3 | state: {
4 | selected: "table"
5 | }
6 | ,
7 | mutations: {
8 | selectComponent(currentState, selection) {
9 | currentState.selected = selection;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/src/store/preferences.js:
--------------------------------------------------------------------------------
1 | export default {
2 | namespaced: true,
3 | state: {
4 | stripedTable: true,
5 | primaryEditButton: false,
6 | dangerDeleteButton: false
7 | },
8 | getters: {
9 | editClass(state) {
10 | return state.primaryEditButton ? "btn-primary" : "btn-secondary";
11 | },
12 | deleteClass(state) {
13 | return state.dangerDeleteButton ? "btn-danger" : "btn-secondary";
14 | },
15 | tableClass(state, payload, rootState) {
16 | return rootState.products.length > 0
17 | && rootState.products[0].price > 500 ? "table-striped" : ""
18 | }
19 | },
20 | mutations: {
21 | setEditButtonColor(currentState, primary) {
22 | currentState.primaryEditButton = primary;
23 | },
24 | setDeleteButtonColor(currentState, danger) {
25 | currentState.dangerDeleteButton = danger;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/24 - Advanced URL Routing/productapp/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | chainWebpack: config => {
3 | config.plugins.delete('prefetch');
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/25 - Transitions/transitions/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/25 - Transitions/transitions/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "transitions",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "animate.css": "^3.6.1",
12 | "bootstrap": "^4.0.0",
13 | "popmotion": "^8.1.24",
14 | "vue": "^2.5.16",
15 | "vue-router": "^3.0.1"
16 | },
17 | "devDependencies": {
18 | "@vue/cli-plugin-babel": "^3.0.0-beta.15",
19 | "@vue/cli-plugin-eslint": "^3.0.0-beta.15",
20 | "@vue/cli-service": "^3.0.0-beta.15",
21 | "vue-template-compiler": "^2.5.16"
22 | },
23 | "eslintConfig": {
24 | "root": true,
25 | "env": {
26 | "node": true
27 | },
28 | "extends": [
29 | "plugin:vue/essential",
30 | "eslint:recommended"
31 | ],
32 | "rules": {},
33 | "parserOptions": {
34 | "parser": "babel-eslint"
35 | }
36 | },
37 | "postcss": {
38 | "plugins": {
39 | "autoprefixer": {}
40 | }
41 | },
42 | "browserslist": [
43 | "> 1%",
44 | "last 2 versions",
45 | "not ie <= 8"
46 | ]
47 | }
48 |
--------------------------------------------------------------------------------
/25 - Transitions/transitions/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/25 - Transitions/transitions/public/favicon.ico
--------------------------------------------------------------------------------
/25 - Transitions/transitions/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | transitions
9 |
10 |
11 |
12 | We're sorry but transitions doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/25 - Transitions/transitions/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
8 | Simple Display
9 |
10 |
12 | List Maker
13 |
14 |
16 | Numbers
17 |
18 |
19 |
20 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
--------------------------------------------------------------------------------
/25 - Transitions/transitions/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/25 - Transitions/transitions/src/assets/logo.png
--------------------------------------------------------------------------------
/25 - Transitions/transitions/src/components/SimpleDisplay.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Display
4 |
5 |
7 |
9 | Hello, Adam
10 |
11 |
13 | Goodbye, Adam
14 |
15 |
16 |
17 |
18 |
19 | Toggle Visibility
20 |
21 |
22 |
23 |
24 |
25 |
41 |
--------------------------------------------------------------------------------
/25 - Transitions/transitions/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | import "bootstrap/dist/css/bootstrap.min.css";
5 | import "animate.css/animate.min.css";
6 | import "popmotion/dist/popmotion.global.min.js";
7 | import router from "./router";
8 |
9 | Vue.config.productionTip = false
10 |
11 | new Vue({
12 | router,
13 | render: h => h(App)
14 | }).$mount('#app')
15 |
--------------------------------------------------------------------------------
/25 - Transitions/transitions/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue"
2 | import Router from "vue-router"
3 |
4 | import SimpleDisplay from "../components/SimpleDisplay";
5 | import ListMaker from "../components/ListMaker";
6 | import Numbers from "../components/Numbers";
7 |
8 | Vue.use(Router)
9 |
10 | export default new Router({
11 | mode: "history",
12 | routes: [
13 | { path: "/display", component: SimpleDisplay },
14 | { path: "/list", component: ListMaker },
15 | { path: "/numbers", component: Numbers },
16 | { path: "*", redirect: "/display" }
17 | ]
18 | })
19 |
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "extendingvue",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "bootstrap": "^4.0.0",
12 | "vue": "^2.5.16"
13 | },
14 | "devDependencies": {
15 | "@vue/cli-plugin-babel": "^3.0.0-beta.15",
16 | "@vue/cli-plugin-eslint": "^3.0.0-beta.15",
17 | "@vue/cli-service": "^3.0.0-beta.15",
18 | "vue-template-compiler": "^2.5.16"
19 | },
20 | "eslintConfig": {
21 | "root": true,
22 | "env": {
23 | "node": true
24 | },
25 | "extends": [
26 | "plugin:vue/essential",
27 | "eslint:recommended"
28 | ],
29 | "rules": {},
30 | "parserOptions": {
31 | "parser": "babel-eslint"
32 | }
33 | },
34 | "postcss": {
35 | "plugins": {
36 | "autoprefixer": {}
37 | }
38 | },
39 | "browserslist": [
40 | "> 1%",
41 | "last 2 versions",
42 | "not ie <= 8"
43 | ]
44 | }
45 |
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/26 - Extending Vue.js/extendingvue/public/favicon.ico
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | extendingvue
9 |
10 |
11 |
12 | We're sorry but extendingvue doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
20 |
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/26 - Extending Vue.js/extendingvue/src/assets/logo.png
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/src/components/Numbers.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Numbers
4 |
5 |
6 |
7 |
8 |
10 |
11 |
+
12 |
13 |
15 |
16 |
17 | = {{ total | currency }}
18 |
19 |
20 |
21 |
22 |
23 |
24 |
38 |
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/src/components/Subtraction.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Subtraction
4 |
5 |
6 |
7 |
8 |
9 |
10 |
-
11 |
12 |
13 |
14 |
= {{ total }}
15 |
16 |
17 |
18 |
19 |
20 |
34 |
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/src/directives/colorize.js:
--------------------------------------------------------------------------------
1 | export default function (el, binding) {
2 | if (binding.value) {
3 | el.classList.add("bg-danger", "text-white");
4 | } else {
5 | el.classList.remove("bg-danger", "text-white");
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import "bootstrap/dist/css/bootstrap.min.css";
4 |
5 | Vue.config.productionTip = false
6 |
7 | import MathsPlugin from "./plugins/maths";
8 | Vue.use(MathsPlugin);
9 |
10 | new Vue({
11 | render: h => h(App)
12 | }).$mount('#app')
13 |
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/src/mixins/numbersMixin.js:
--------------------------------------------------------------------------------
1 | import Colorize from "../directives/colorize";
2 |
3 | export default {
4 | data: function () {
5 | return {
6 | first: 50,
7 | second: 20
8 | }
9 | },
10 | computed: {
11 | total() {
12 | return 0;
13 | }
14 | },
15 | directives: { Colorize },
16 | }
17 |
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/src/plugins/maths/componentFeatures.js:
--------------------------------------------------------------------------------
1 | export default {
2 | $calc: {
3 | add(first, second) {
4 | return first + second;
5 | },
6 | subtract(first, second) {
7 | return first - second;
8 | },
9 | multiply(first, second) {
10 | return first * second;
11 | },
12 | divide(first, second) {
13 | return first / second;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/src/plugins/maths/directives.js:
--------------------------------------------------------------------------------
1 | export default {
2 |
3 | borderize: function (el, binding) {
4 | if (binding.value) {
5 | el.classList.add("border", "border-dark");
6 | } else {
7 | el.classList.remove("border", "border-dark");
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/src/plugins/maths/filters.js:
--------------------------------------------------------------------------------
1 | export default {
2 |
3 | currency: function (value) {
4 | return new Intl.NumberFormat("en-US",
5 | { style: "currency", currency: "USD" }).format(value);
6 | },
7 |
8 | noDecimal: function (value) {
9 | return Number(value).toFixed(0);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/src/plugins/maths/globals.js:
--------------------------------------------------------------------------------
1 | export default {
2 | sumValues(...vals) {
3 | return vals.reduce((val, total) => total += val, 0);
4 | },
5 |
6 | getSymbol(operation) {
7 | switch (operation.toLowerCase()) {
8 | case "add": return "+";
9 | case "subtract": return "-";
10 | case "multiply": return "*";
11 | default: return "/";
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/26 - Extending Vue.js/extendingvue/src/plugins/maths/index.js:
--------------------------------------------------------------------------------
1 | import filters from "./filters";
2 | import directives from "./directives";
3 | import globals from "./globals";
4 | import componentFeatures from "./componentFeatures";
5 | import Operation from "./Operation";
6 |
7 | export default {
8 | install: function (Vue) {
9 |
10 | Vue.filter("currency", filters.currency);
11 | Vue.filter("noDecimal", filters.noDecimal);
12 | Vue.directive("borderize", directives.borderize);
13 | Vue.component("maths", Operation);
14 |
15 |
16 | Vue.sumValues = globals.sumValues;
17 | Vue.getSymbol = globals.getSymbol;
18 |
19 | Vue.prototype.$calc = componentFeatures.$calc;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/9781484238042.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/pro-vue-js-2/7e60f217bf6beb7a62aa7887882d0e7d1857908a/9781484238042.jpg
--------------------------------------------------------------------------------
/Contributing.md:
--------------------------------------------------------------------------------
1 | # Contributing to Apress Source Code
2 |
3 | Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers.
4 |
5 | ## How to Contribute
6 |
7 | 1. Make sure you have a GitHub account.
8 | 2. Fork the repository for the relevant book.
9 | 3. Create a new branch on which to make your change, e.g.
10 | `git checkout -b my_code_contribution`
11 | 4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted.
12 | 5. Submit a pull request.
13 |
14 | Thank you for your contribution!
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Freeware License, some rights reserved
2 |
3 | Copyright (c) 2018 Adam Freeman
4 |
5 | Permission is hereby granted, free of charge, to anyone obtaining a copy
6 | of this software and associated documentation files (the "Software"),
7 | to work with the Software within the limits of freeware distribution and fair use.
8 | This includes the rights to use, copy, and modify the Software for personal use.
9 | Users are also allowed and encouraged to submit corrections and modifications
10 | to the Software for the benefit of other users.
11 |
12 | It is not allowed to reuse, modify, or redistribute the Software for
13 | commercial use in any way, or for a user’s educational materials such as books
14 | or blog articles without prior permission from the copyright holder.
15 |
16 | The above copyright notice and this permission notice need to be included
17 | in all copies or substantial portions of the software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | SOFTWARE.
26 |
27 |
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Apress Source Code
2 |
3 | This repository accompanies [*Pro Vue.js 2*](https://www.apress.com/9781484238042) by Adam Freeman (Apress, 2018).
4 |
5 | [comment]: #cover
6 | 
7 |
8 | Download the files as a zip using the green button, or clone the repository to your machine using Git.
9 |
10 | ## Releases
11 |
12 | Release v1.0 corresponds to the code in the published book, without corrections or updates.
13 |
14 | ## Contributions
15 |
16 | See the file Contributing.md for more information on how you can contribute to this repository.
--------------------------------------------------------------------------------