├── .gitignore ├── Chapter02 ├── callback-1.js ├── command-1.js ├── decorator-1.vue ├── decorator-2.vue ├── dependency-injection-1.js ├── dependency-injection-2.js ├── dependency-injection-3.js ├── dependency-injection-4.js ├── dependency-injection-5.js ├── dependency-injection-6.js ├── dependency-injection-7.js ├── observer-1.js ├── promises-1.js ├── proxy-1.js ├── singleton-class.js ├── singleton-invoker.js └── singleton-json.js ├── Chapter03 ├── .gitignore ├── .vscode │ └── extensions.json ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── public │ ├── css │ │ ├── all.css │ │ ├── all.min.css │ │ ├── brands.css │ │ ├── brands.min.css │ │ ├── fontawesome.css │ │ ├── fontawesome.min.css │ │ ├── regular.css │ │ ├── regular.min.css │ │ ├── solid.css │ │ ├── solid.min.css │ │ ├── svg-with-js.css │ │ ├── svg-with-js.min.css │ │ ├── v4-font-face.css │ │ ├── v4-font-face.min.css │ │ ├── v4-shims.css │ │ ├── v4-shims.min.css │ │ ├── v5-font-face.css │ │ ├── v5-font-face.min.css │ │ └── w3.css │ ├── vite.svg │ └── webfonts │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff2 │ │ ├── fa-v4compatibility.ttf │ │ └── fa-v4compatibility.woff2 ├── src │ ├── App.vue │ ├── assets │ │ └── vue.svg │ ├── components │ │ └── ToDos.vue │ ├── main.js │ └── style.css └── vite.config.js ├── Chapter04 ├── modal-plugin-example │ ├── README.md │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── css │ │ │ ├── all.css │ │ │ ├── all.min.css │ │ │ ├── brands.css │ │ │ ├── brands.min.css │ │ │ ├── fontawesome.css │ │ │ ├── fontawesome.min.css │ │ │ ├── regular.css │ │ │ ├── regular.min.css │ │ │ ├── solid.css │ │ │ ├── solid.min.css │ │ │ ├── svg-with-js.css │ │ │ ├── svg-with-js.min.css │ │ │ ├── v4-font-face.css │ │ │ ├── v4-font-face.min.css │ │ │ ├── v4-shims.css │ │ │ ├── v4-shims.min.css │ │ │ ├── v5-font-face.css │ │ │ ├── v5-font-face.min.css │ │ │ └── w3.css │ │ ├── vite.svg │ │ └── webfonts │ │ │ ├── fa-brands-400.ttf │ │ │ ├── fa-brands-400.woff2 │ │ │ ├── fa-regular-400.ttf │ │ │ ├── fa-regular-400.woff2 │ │ │ ├── fa-solid-900.ttf │ │ │ ├── fa-solid-900.woff2 │ │ │ ├── fa-v4compatibility.ttf │ │ │ └── fa-v4compatibility.woff2 │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── vue.svg │ │ ├── main.js │ │ ├── plugins │ │ │ └── modals │ │ │ │ ├── Modal.vue │ │ │ │ └── index.js │ │ └── style.css │ └── vite.config.js └── todo-list-example │ ├── README.md │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── css │ │ ├── all.css │ │ ├── all.min.css │ │ ├── brands.css │ │ ├── brands.min.css │ │ ├── fontawesome.css │ │ ├── fontawesome.min.css │ │ ├── regular.css │ │ ├── regular.min.css │ │ ├── solid.css │ │ ├── solid.min.css │ │ ├── svg-with-js.css │ │ ├── svg-with-js.min.css │ │ ├── v4-font-face.css │ │ ├── v4-font-face.min.css │ │ ├── v4-shims.css │ │ ├── v4-shims.min.css │ │ ├── v5-font-face.css │ │ ├── v5-font-face.min.css │ │ └── w3.css │ ├── vite.svg │ └── webfonts │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff2 │ │ ├── fa-v4compatibility.ttf │ │ └── fa-v4compatibility.woff2 │ ├── src │ ├── App.vue │ ├── assets │ │ └── styles.css │ ├── components │ │ ├── ToDoFilter.vue │ │ ├── ToDoItemForm.vue │ │ ├── ToDoList.vue │ │ ├── ToDoProject.vue │ │ ├── ToDoSummary.vue │ │ └── headers │ │ │ └── MainHeader.vue │ ├── main.js │ ├── plugins │ │ └── modals │ │ │ ├── Modal.vue │ │ │ └── index.js │ └── services │ │ └── todo.js │ └── vite.config.js ├── Chapter05 ├── Nested routes │ ├── .gitignore │ ├── .vscode │ │ └── extensions.json │ ├── README.md │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── main.css │ │ ├── main.js │ │ ├── router │ │ │ └── index.js │ │ ├── services │ │ │ ├── ARG_localities.json │ │ │ ├── USA_localities.json │ │ │ ├── countries.json │ │ │ ├── locationService.js │ │ │ └── states.json │ │ └── views │ │ │ ├── City.vue │ │ │ ├── Directory.vue │ │ │ ├── Home.vue │ │ │ └── State.vue │ └── vite.config.js ├── OTP example │ └── SignInOTP.vue └── to-do SPA │ ├── README.md │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── css │ │ ├── all.css │ │ ├── all.min.css │ │ ├── brands.css │ │ ├── brands.min.css │ │ ├── fontawesome.css │ │ ├── fontawesome.min.css │ │ ├── regular.css │ │ ├── regular.min.css │ │ ├── solid.css │ │ ├── solid.min.css │ │ ├── svg-with-js.css │ │ ├── svg-with-js.min.css │ │ ├── v4-font-face.css │ │ ├── v4-font-face.min.css │ │ ├── v4-shims.css │ │ ├── v4-shims.min.css │ │ ├── v5-font-face.css │ │ ├── v5-font-face.min.css │ │ └── w3.css │ ├── vite.svg │ └── webfonts │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff2 │ │ ├── fa-v4compatibility.ttf │ │ └── fa-v4compatibility.woff2 │ ├── src │ ├── App.vue │ ├── assets │ │ └── styles.css │ ├── components │ │ ├── Sidebar │ │ │ └── Sidebar.vue │ │ └── ToDos │ │ │ ├── ToDoFilter.vue │ │ │ ├── ToDoItemForm.vue │ │ │ ├── ToDoList.vue │ │ │ └── ToDoSummary.vue │ ├── main.js │ ├── plugins │ │ └── modals │ │ │ ├── Modal.vue │ │ │ └── index.js │ ├── router │ │ └── index.js │ ├── services │ │ ├── eventBus.js │ │ └── todo.js │ └── views │ │ ├── Landing.vue │ │ └── ToDoProject.vue │ └── vite.config.js ├── Chapter06 ├── .gitignore ├── .hintrc ├── manual-upscale-spa │ ├── .vscode │ │ └── extensions.json │ ├── README.md │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── images │ │ │ └── chapter_6_icon.png │ │ ├── manifest.json │ │ ├── service_worker.js │ │ └── vite.svg │ ├── src │ │ ├── App.vue │ │ ├── main.js │ │ └── style.css │ └── vite.config.js └── vite-pwa-plugin │ ├── README.md │ ├── dev-dist │ ├── registerSW.js │ ├── sw.js │ ├── workbox-148cb7e5.js │ └── workbox-3625d7b0.js │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── images │ │ ├── chapter_6_icon.png │ │ └── chapter_6_icon_192x192.png │ ├── robots.txt │ └── vite.svg │ ├── src │ ├── App.vue │ ├── main.js │ └── style.css │ └── vite.config.js ├── Chapter07 ├── .gitignore ├── .vscode │ └── extensions.json ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── public │ └── favicon.ico ├── src │ ├── App.vue │ ├── assets │ │ └── main.css │ ├── components │ │ ├── basic │ │ │ ├── Child.vue │ │ │ └── ParentBasic.vue │ │ ├── bus │ │ │ ├── Child.vue │ │ │ └── ParentBus.vue │ │ ├── pinia │ │ │ ├── ChildPinia.vue │ │ │ └── ParentPinia.vue │ │ ├── session_storage │ │ │ ├── ChildSession.vue │ │ │ └── ParentSession.vue │ │ └── simple │ │ │ ├── ChildSimple.vue │ │ │ └── ParentSimple.vue │ ├── main.js │ ├── services │ │ ├── MessageBus.js │ │ ├── SimpleState.js │ │ └── sessionStorage.js │ └── stores │ │ └── counter.js └── vite.config.js ├── Chapter08 ├── client │ ├── README.md │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ │ └── vite.svg │ ├── src │ │ ├── App.vue │ │ ├── components │ │ │ ├── DbNotes.vue │ │ │ └── NetworkCommunication.vue │ │ ├── main.js │ │ ├── services │ │ │ └── WebWorker.js │ │ ├── style.css │ │ └── webworker │ │ │ ├── index.js │ │ │ └── services │ │ │ ├── dbService.js │ │ │ ├── network.js │ │ │ └── test.js │ └── vite.config.js └── server │ ├── index.js │ ├── package-lock.json │ └── package.json ├── Chapter09 ├── .gitignore ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── public │ └── vite.svg ├── src │ ├── App.vue │ ├── assets │ │ └── vue.svg │ ├── components │ │ ├── FibonacciInput.vue │ │ └── FibonacciOutput.vue │ ├── main.js │ ├── services │ │ └── Fibonacci.js │ ├── style.css │ └── tests │ │ ├── Fibonacci.test.js │ │ ├── FibonacciInput.test.js │ │ └── FibonacciOutput.test.js └── vite.config.js ├── Chapter10 ├── apache │ └── .htaccess └── nginx │ └── default.server ├── Chapter11 ├── .gitignore ├── .vscode │ └── extensions.json ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── public │ └── vite.svg ├── src │ ├── App.vue │ ├── components │ │ ├── InfiniteScroller.vue │ │ ├── Spinner.vue │ │ └── Toggle.vue │ ├── main.js │ └── style.css └── vite.config.js ├── README.md └── basic site ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── public ├── css │ ├── all.css │ ├── all.min.css │ ├── brands.css │ ├── brands.min.css │ ├── fontawesome.css │ ├── fontawesome.min.css │ ├── regular.css │ ├── regular.min.css │ ├── solid.css │ ├── solid.min.css │ ├── svg-with-js.css │ ├── svg-with-js.min.css │ ├── v4-font-face.css │ ├── v4-font-face.min.css │ ├── v4-shims.css │ ├── v4-shims.min.css │ ├── v5-font-face.css │ ├── v5-font-face.min.css │ └── w3.css ├── vite.svg └── webfonts │ ├── fa-brands-400.ttf │ ├── fa-brands-400.woff2 │ ├── fa-regular-400.ttf │ ├── fa-regular-400.woff2 │ ├── fa-solid-900.ttf │ ├── fa-solid-900.woff2 │ ├── fa-v4compatibility.ttf │ └── fa-v4compatibility.woff2 ├── src ├── App.vue ├── assets │ └── vue.svg ├── components │ └── HelloWorld.vue ├── main.js └── style.css └── vite.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | "basic site" 3 | "chapter 1" 4 | "chapter 2" -------------------------------------------------------------------------------- /Chapter02/callback-1.js: -------------------------------------------------------------------------------- 1 | /** 2 | The implementation of a Fibonacci calculation following the 3 | callback pattern, synchronous and asynchronous 4 | */ 5 | 6 | function FibonacciSync(n, callback) { 7 | if (n < 2) { 8 | callback(n) 9 | } else { 10 | let pre_1 = 0, pre_2 = 1, value; 11 | for (let i = 1; i < n; i++) { 12 | value = pre_1 + pre_2; 13 | pre_1 = pre_2; 14 | pre_2 = value; 15 | } 16 | callback(value); 17 | } 18 | } 19 | 20 | function FibonacciAsync(n, callback) { 21 | setImmediate(() => { 22 | if (n < 2) { 23 | callback(n) 24 | } else { 25 | let pre_1 = 0, pre_2 = 1, value; 26 | for (let i = 1; i < n; i++) { 27 | value = pre_1 + pre_2; 28 | pre_1 = pre_2; 29 | pre_2 = value; 30 | } 31 | callback(value); 32 | } 33 | }) 34 | } 35 | 36 | function FibonacciPromise(n) { 37 | return new Promise((resolve, reject) => { 38 | if (n < 0) { 39 | reject() 40 | } else { 41 | switch (n) { 42 | case 0: 43 | case 1: 44 | resolve(n); 45 | case 2: 46 | resolve(1); 47 | default: 48 | let pre_1 = 1, pre_2 = 1, value; 49 | for (let i = 2; i < n; i++) { 50 | value = pre_1 + pre_2; 51 | pre_1 = pre_2; 52 | pre_2 = value; 53 | } 54 | resolve(value); 55 | } 56 | } 57 | }) 58 | } 59 | 60 | console.log("Before") 61 | FibonacciPromise(9).then(value=>console.log(value), ()=>{console.log("Not defined for negative numbers")}) 62 | console.log("After") 63 | -------------------------------------------------------------------------------- /Chapter02/command-1.js: -------------------------------------------------------------------------------- 1 | /** 2 | A code segment the implements a command pattern 3 | */ 4 | 5 | class CommandInvoker{ 6 | 7 | addCommand(command_data){ 8 | // .. queue implementation here 9 | } 10 | 11 | runCommand(command_data){ 12 | 13 | switch(command_data.action){ 14 | case "eat": 15 | // .. 16 | break; 17 | 18 | case "code": 19 | // .. 20 | break; 21 | 22 | case "repeat": 23 | // .. 24 | break; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Chapter02/decorator-1.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter02/decorator-2.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter02/dependency-injection-1.js: -------------------------------------------------------------------------------- 1 | // Without dependency injection 2 | 3 | import dbManager from "dbManager" 4 | 5 | const projects={ 6 | getAllProjects(){ 7 | return dbManager.getAll("projects") 8 | } 9 | } 10 | 11 | export default projects; -------------------------------------------------------------------------------- /Chapter02/dependency-injection-2.js: -------------------------------------------------------------------------------- 1 | // With dependency injection 2 | 3 | const projects={ 4 | getAllProjects(dbManager){ 5 | return dbManager.getAll("projects") 6 | } 7 | } 8 | 9 | export default projects; -------------------------------------------------------------------------------- /Chapter02/dependency-injection-3.js: -------------------------------------------------------------------------------- 1 | // With dependency injection by property 2 | 3 | const projects={ 4 | dbManager, 5 | getAllProjects(){ 6 | return this.dbManager.getAll("projects") 7 | } 8 | } 9 | 10 | export default projects; -------------------------------------------------------------------------------- /Chapter02/dependency-injection-4.js: -------------------------------------------------------------------------------- 1 | /** 2 | An example of a module that uses the example 3 | implementation from dependency-injection-3.js 4 | */ 5 | 6 | import projects from "projects.js" 7 | import dbManager from "dbManager.js" 8 | 9 | projects.dbManager=dbManager; 10 | projects.getAllProjects(); -------------------------------------------------------------------------------- /Chapter02/dependency-injection-5.js: -------------------------------------------------------------------------------- 1 | /** 2 | An example of a class that requires the dependency 3 | in the constructor 4 | */ 5 | 6 | class Projects { 7 | constructor(dbManager=null){ 8 | if(!dbManager){ 9 | throw "Dependency missing" 10 | }else{ 11 | this.dbManager=dbManager; 12 | } 13 | } 14 | } 15 | 16 | // Then the instantiation would be as follows 17 | 18 | try{ 19 | const projects=new Projects(dbManager) 20 | }catch{ 21 | // Error handler here 22 | } -------------------------------------------------------------------------------- /Chapter02/dependency-injection-6.js: -------------------------------------------------------------------------------- 1 | /** 2 | A singleton provider of dependencies 3 | */ 4 | 5 | const dependencyService={ 6 | dependencies:{}, 7 | provide(name, dependency){ 8 | this.dependencies[name]=dependency; 9 | return this; 10 | }, 11 | inject(name){ 12 | return this.dependencies[name]??null; 13 | } 14 | } 15 | 16 | export default dependencyService; -------------------------------------------------------------------------------- /Chapter02/dependency-injection-7.js: -------------------------------------------------------------------------------- 1 | /** 2 | A parent module that implements all the dependencies 3 | for the application 4 | */ 5 | 6 | import dependencyService from "./dependency-injection-6"; 7 | import myDependency1 from "myFile1" 8 | import myDependency2 from "myFile2" 9 | import dbManager from "dbManager" 10 | 11 | dependencyService 12 | .provide("dependency1", myDependency1) 13 | .provide("dependency2", myDependency2) 14 | .provide("dbManager", dbManager) 15 | 16 | // Then, to use the service 17 | const dbManager=dependencyService.inject("dbManager") -------------------------------------------------------------------------------- /Chapter02/observer-1.js: -------------------------------------------------------------------------------- 1 | /** 2 | A naive implementation of a simple event dispatcher 3 | to implement an observer pattern 4 | */ 5 | 6 | class ObserverPattern{ 7 | constructor(){ 8 | this.events={} 9 | } 10 | on(event_name, fn=()=>{}){ 11 | if(!this.events[event_name]){ 12 | this.events[event_name]=[] 13 | } 14 | this.events[event_name].push(fn) 15 | } 16 | emit(event_name, data){ 17 | if(!this.events[event_name]){ 18 | return 19 | } 20 | for(let i=0, l=this.events[event_name].length; i-1){ 27 | this.events[event_name].slice(i, 1); 28 | } 29 | } 30 | } 31 | 32 | export default ObserverPattern; -------------------------------------------------------------------------------- /Chapter02/promises-1.js: -------------------------------------------------------------------------------- 1 | /** 2 | A syntax example of a promised function with async/await 3 | */ 4 | 5 | async function myProcessFunction() { //1 6 | 7 | try { //2 8 | 9 | let a = await MyFuncA(), //3 10 | b = await MyFuncB(), 11 | c = await MyFuncC() 12 | 13 | console.log(a + b + c) //4 14 | 15 | } catch { 16 | 17 | console.log("Error") 18 | 19 | } 20 | 21 | } 22 | 23 | // Invoke the function normally 24 | 25 | MyProcessFunction() //5 -------------------------------------------------------------------------------- /Chapter02/proxy-1.js: -------------------------------------------------------------------------------- 1 | /** 2 | A naive partial implementation of a reactive object, 3 | implementing the Observer and Proxy pattern 4 | */ 5 | 6 | let temperature={ 7 | celsius:0, 8 | fahrenheit: 32 9 | }, 10 | handler={ 11 | set(target, key, value){ 12 | target[key]=value; 13 | switch(key){ 14 | case "celsius": 15 | target.fahrenheit=calculateFahrenheit(value); 16 | break; 17 | case "fahrenheit": 18 | target.celsius=calculateCelsius(value); 19 | } 20 | }, 21 | get(target, key){ 22 | return target[key]; 23 | } 24 | }, 25 | degrees=new Proxy(temperature, handler) 26 | 27 | // Auxiliar functions 28 | function calculateCelsius(fahrenheit){ 29 | return (fahrenheit - 32) / 1.8 30 | } 31 | 32 | function calculateFahrenheit(celsius){ 33 | return (celsius * 1.8) + 32 34 | } 35 | 36 | degrees.celsius=25 37 | console.log(degrees) -------------------------------------------------------------------------------- /Chapter02/singleton-class.js: -------------------------------------------------------------------------------- 1 | class myClass{ 2 | 3 | constructor(){ 4 | if(myClass._instance){ 5 | return myClass._instance; 6 | }else{ 7 | myClass._instance=this; 8 | } 9 | return this; 10 | } 11 | 12 | myFunction(){ 13 | console.log("Singleton alive and well") 14 | } 15 | } 16 | 17 | export default new myClass() -------------------------------------------------------------------------------- /Chapter02/singleton-invoker.js: -------------------------------------------------------------------------------- 1 | import my_method1_singleton from "./singleton-json"; 2 | import my_method2_singleton from "./singleton-class"; 3 | 4 | console.log("Look mom, no instantiation!") 5 | 6 | my_method1_singleton.myFunction() 7 | my_method2_singleton.myFunction() 8 | 9 | -------------------------------------------------------------------------------- /Chapter02/singleton-json.js: -------------------------------------------------------------------------------- 1 | const my_singleton={ 2 | myFunction(){ 3 | console.log("Singleton alive and well") 4 | } 5 | } 6 | 7 | export default my_singleton; -------------------------------------------------------------------------------- /Chapter03/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /Chapter03/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar"] 3 | } 4 | -------------------------------------------------------------------------------- /Chapter03/README.md: -------------------------------------------------------------------------------- 1 | # Vue 3 + Vite 2 | 3 | This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 ` 16 | 17 | 18 | -------------------------------------------------------------------------------- /Chapter03/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter-3", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "vue": "^3.2.37" 13 | }, 14 | "devDependencies": { 15 | "@vitejs/plugin-vue": "^3.0.3", 16 | "vite": "^3.0.7" 17 | } 18 | } -------------------------------------------------------------------------------- /Chapter03/public/css/regular.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :root, :host { 7 | --fa-font-regular: normal 400 1em/1 "Font Awesome 6 Free"; } 8 | 9 | @font-face { 10 | font-family: "Font Awesome 6 Free"; 11 | font-style: normal; 12 | font-weight: 400; 13 | font-display: block; 14 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); } 15 | 16 | .far, 17 | .fa-regular { 18 | font-family: "Font Awesome 6 Free"; 19 | font-weight: 400; } 20 | -------------------------------------------------------------------------------- /Chapter03/public/css/regular.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :host,:root{--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}.fa-regular,.far{font-family:"Font Awesome 6 Free";font-weight:400} -------------------------------------------------------------------------------- /Chapter03/public/css/solid.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :root, :host { 7 | --fa-font-solid: normal 900 1em/1 "Font Awesome 6 Free"; } 8 | 9 | @font-face { 10 | font-family: "Font Awesome 6 Free"; 11 | font-style: normal; 12 | font-weight: 900; 13 | font-display: block; 14 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 15 | 16 | .fas, 17 | .fa-solid { 18 | font-family: "Font Awesome 6 Free"; 19 | font-weight: 900; } 20 | -------------------------------------------------------------------------------- /Chapter03/public/css/solid.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :host,:root{--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-family:"Font Awesome 6 Free";font-weight:900} -------------------------------------------------------------------------------- /Chapter03/public/css/v4-font-face.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face { 7 | font-family: "FontAwesome"; 8 | font-display: block; 9 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 10 | 11 | @font-face { 12 | font-family: "FontAwesome"; 13 | font-display: block; 14 | src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); } 15 | 16 | @font-face { 17 | font-family: "FontAwesome"; 18 | font-display: block; 19 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); 20 | unicode-range: U+F003,U+F006,U+F014,U+F016-F017,U+F01A-F01B,U+F01D,U+F022,U+F03E,U+F044,U+F046,U+F05C-F05D,U+F06E,U+F070,U+F087-F088,U+F08A,U+F094,U+F096-F097,U+F09D,U+F0A0,U+F0A2,U+F0A4-F0A7,U+F0C5,U+F0C7,U+F0E5-F0E6,U+F0EB,U+F0F6-F0F8,U+F10C,U+F114-F115,U+F118-F11A,U+F11C-F11D,U+F133,U+F147,U+F14E,U+F150-F152,U+F185-F186,U+F18E,U+F190-F192,U+F196,U+F1C1-F1C9,U+F1D9,U+F1DB,U+F1E3,U+F1EA,U+F1F7,U+F1F9,U+F20A,U+F247-F248,U+F24A,U+F24D,U+F255-F25B,U+F25D,U+F271-F274,U+F278,U+F27B,U+F28C,U+F28E,U+F29C,U+F2B5,U+F2B7,U+F2BA,U+F2BC,U+F2BE,U+F2C0-F2C1,U+F2C3,U+F2D0,U+F2D2,U+F2D4,U+F2DC; } 21 | 22 | @font-face { 23 | font-family: "FontAwesome"; 24 | font-display: block; 25 | src: url("../webfonts/fa-v4compatibility.woff2") format("woff2"), url("../webfonts/fa-v4compatibility.ttf") format("truetype"); 26 | unicode-range: U+F041,U+F047,U+F065-F066,U+F07D-F07E,U+F080,U+F08B,U+F08E,U+F090,U+F09A,U+F0AC,U+F0AE,U+F0B2,U+F0D0,U+F0D6,U+F0E4,U+F0EC,U+F10A-F10B,U+F123,U+F13E,U+F148-F149,U+F14C,U+F156,U+F15E,U+F160-F161,U+F163,U+F175-F178,U+F195,U+F1F8,U+F219,U+F27A; } 27 | -------------------------------------------------------------------------------- /Chapter03/public/css/v4-font-face.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2"),url(../webfonts/fa-v4compatibility.ttf) format("truetype");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a} -------------------------------------------------------------------------------- /Chapter03/public/css/v5-font-face.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face { 7 | font-family: "Font Awesome 5 Brands"; 8 | font-display: block; 9 | font-weight: 400; 10 | src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); } 11 | 12 | @font-face { 13 | font-family: "Font Awesome 5 Free"; 14 | font-display: block; 15 | font-weight: 900; 16 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 17 | 18 | @font-face { 19 | font-family: "Font Awesome 5 Free"; 20 | font-display: block; 21 | font-weight: 400; 22 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); } 23 | -------------------------------------------------------------------------------- /Chapter03/public/css/v5-font-face.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")} -------------------------------------------------------------------------------- /Chapter03/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter03/public/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter03/public/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /Chapter03/public/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter03/public/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /Chapter03/public/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter03/public/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /Chapter03/public/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter03/public/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /Chapter03/public/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter03/public/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /Chapter03/public/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter03/public/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /Chapter03/public/webfonts/fa-v4compatibility.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter03/public/webfonts/fa-v4compatibility.ttf -------------------------------------------------------------------------------- /Chapter03/public/webfonts/fa-v4compatibility.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter03/public/webfonts/fa-v4compatibility.woff2 -------------------------------------------------------------------------------- /Chapter03/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 20 | -------------------------------------------------------------------------------- /Chapter03/src/assets/vue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter03/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from "vue" 2 | import "./style.css" 3 | import App from "./App.vue" 4 | 5 | createApp(App).mount("#app") 6 | -------------------------------------------------------------------------------- /Chapter03/src/style.css: -------------------------------------------------------------------------------- 1 | .flex-container{ 2 | display: flex; 3 | } -------------------------------------------------------------------------------- /Chapter03/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite" 2 | import vue from "@vitejs/plugin-vue" 3 | import path from "path" 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [vue()], 8 | resolve:{ 9 | alias:{ 10 | "@components": path.resolve(__dirname, "src", "components") 11 | } 12 | } 13 | }) 14 | -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/README.md: -------------------------------------------------------------------------------- 1 | # Single Modal Plugin 2 | 3 | ## Created by Pablo D. Garaguso (2022) 4 | 5 | This example plugin shows the use of reactive, api declaration for dependency 6 | injection with provide/inject, the use of promises, and the registration of 7 | global components into the Vue 3 application. 8 | 9 | ### Usage in main.js (Vue 3 application instanciation): 10 | 11 | ``` 12 | import Modals from "/modals/index.js" 13 | ... 14 | App.use("$modals",Modals) 15 | ``` 16 | 17 | ### In a component: 18 | 19 | ``` 20 | [script setup] 21 | 22 | import {inject} from "vue" 23 | const $modals=inject("$modals") 24 | $modals.show("modalName").then(...) 25 | 26 | [template] 27 | 28 | 29 | ... 30 | 31 | ``` -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + Vue 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter-4", 3 | "private": true, 4 | "version": "1.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "vue": "^3.2.37" 13 | }, 14 | "devDependencies": { 15 | "@vitejs/plugin-vue": "^3.0.3", 16 | "vite": "^3.0.7" 17 | } 18 | } -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/css/regular.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :root, :host { 7 | --fa-font-regular: normal 400 1em/1 "Font Awesome 6 Free"; } 8 | 9 | @font-face { 10 | font-family: "Font Awesome 6 Free"; 11 | font-style: normal; 12 | font-weight: 400; 13 | font-display: block; 14 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); } 15 | 16 | .far, 17 | .fa-regular { 18 | font-family: "Font Awesome 6 Free"; 19 | font-weight: 400; } 20 | -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/css/regular.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :host,:root{--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}.fa-regular,.far{font-family:"Font Awesome 6 Free";font-weight:400} -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/css/solid.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :root, :host { 7 | --fa-font-solid: normal 900 1em/1 "Font Awesome 6 Free"; } 8 | 9 | @font-face { 10 | font-family: "Font Awesome 6 Free"; 11 | font-style: normal; 12 | font-weight: 900; 13 | font-display: block; 14 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 15 | 16 | .fas, 17 | .fa-solid { 18 | font-family: "Font Awesome 6 Free"; 19 | font-weight: 900; } 20 | -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/css/solid.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :host,:root{--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-family:"Font Awesome 6 Free";font-weight:900} -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/css/v4-font-face.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face { 7 | font-family: "FontAwesome"; 8 | font-display: block; 9 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 10 | 11 | @font-face { 12 | font-family: "FontAwesome"; 13 | font-display: block; 14 | src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); } 15 | 16 | @font-face { 17 | font-family: "FontAwesome"; 18 | font-display: block; 19 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); 20 | unicode-range: U+F003,U+F006,U+F014,U+F016-F017,U+F01A-F01B,U+F01D,U+F022,U+F03E,U+F044,U+F046,U+F05C-F05D,U+F06E,U+F070,U+F087-F088,U+F08A,U+F094,U+F096-F097,U+F09D,U+F0A0,U+F0A2,U+F0A4-F0A7,U+F0C5,U+F0C7,U+F0E5-F0E6,U+F0EB,U+F0F6-F0F8,U+F10C,U+F114-F115,U+F118-F11A,U+F11C-F11D,U+F133,U+F147,U+F14E,U+F150-F152,U+F185-F186,U+F18E,U+F190-F192,U+F196,U+F1C1-F1C9,U+F1D9,U+F1DB,U+F1E3,U+F1EA,U+F1F7,U+F1F9,U+F20A,U+F247-F248,U+F24A,U+F24D,U+F255-F25B,U+F25D,U+F271-F274,U+F278,U+F27B,U+F28C,U+F28E,U+F29C,U+F2B5,U+F2B7,U+F2BA,U+F2BC,U+F2BE,U+F2C0-F2C1,U+F2C3,U+F2D0,U+F2D2,U+F2D4,U+F2DC; } 21 | 22 | @font-face { 23 | font-family: "FontAwesome"; 24 | font-display: block; 25 | src: url("../webfonts/fa-v4compatibility.woff2") format("woff2"), url("../webfonts/fa-v4compatibility.ttf") format("truetype"); 26 | unicode-range: U+F041,U+F047,U+F065-F066,U+F07D-F07E,U+F080,U+F08B,U+F08E,U+F090,U+F09A,U+F0AC,U+F0AE,U+F0B2,U+F0D0,U+F0D6,U+F0E4,U+F0EC,U+F10A-F10B,U+F123,U+F13E,U+F148-F149,U+F14C,U+F156,U+F15E,U+F160-F161,U+F163,U+F175-F178,U+F195,U+F1F8,U+F219,U+F27A; } 27 | -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/css/v4-font-face.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2"),url(../webfonts/fa-v4compatibility.ttf) format("truetype");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a} -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/css/v5-font-face.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face { 7 | font-family: "Font Awesome 5 Brands"; 8 | font-display: block; 9 | font-weight: 400; 10 | src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); } 11 | 12 | @font-face { 13 | font-family: "Font Awesome 5 Free"; 14 | font-display: block; 15 | font-weight: 900; 16 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 17 | 18 | @font-face { 19 | font-family: "Font Awesome 5 Free"; 20 | font-display: block; 21 | font-weight: 400; 22 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); } 23 | -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/css/v5-font-face.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")} -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/modal-plugin-example/public/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/modal-plugin-example/public/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/modal-plugin-example/public/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/modal-plugin-example/public/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/modal-plugin-example/public/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/modal-plugin-example/public/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/webfonts/fa-v4compatibility.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/modal-plugin-example/public/webfonts/fa-v4compatibility.ttf -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/public/webfonts/fa-v4compatibility.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/modal-plugin-example/public/webfonts/fa-v4compatibility.woff2 -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/src/App.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 30 | 31 | 38 | -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/src/assets/vue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from "vue" 2 | import "./style.css" 3 | import App from "./App.vue" 4 | import Modals from "./plugins/modals" 5 | 6 | createApp(App) 7 | .use(Modals) 8 | .mount("#app") 9 | -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/src/plugins/modals/Modal.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 38 | 39 | -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/src/style.css: -------------------------------------------------------------------------------- 1 | .flex-container{ 2 | display: flex; 3 | } -------------------------------------------------------------------------------- /Chapter04/modal-plugin-example/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite" 2 | import vue from "@vitejs/plugin-vue" 3 | import path from "path" 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [vue()], 8 | resolve:{ 9 | alias:{ 10 | "@components": path.resolve(__dirname, "src", "components") 11 | } 12 | } 13 | }) 14 | -------------------------------------------------------------------------------- /Chapter04/todo-list-example/README.md: -------------------------------------------------------------------------------- 1 | # To-Do List Application - Chapter 4 2 | 3 | ## Created by Pablo D. Garaguso (2022) 4 | 5 | This application builds on the concepts seen from chapters 1 to 4. 6 | 7 | To install dependencies run: 8 | 9 | `npm install` 10 | 11 | To run the application in developer mode, run: 12 | 13 | `npm run serve` 14 | 15 | Follow the instructions on the terminal to open the website in your browser. -------------------------------------------------------------------------------- /Chapter04/todo-list-example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Chapter 4: To-Do list 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Chapter04/todo-list-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter-4-todo", 3 | "private": true, 4 | "version": "1.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "vue": "^3.2.37" 13 | }, 14 | "devDependencies": { 15 | "@vitejs/plugin-vue": "^3.0.3", 16 | "vite": "^3.0.7" 17 | } 18 | } -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/css/regular.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :root, :host { 7 | --fa-font-regular: normal 400 1em/1 "Font Awesome 6 Free"; } 8 | 9 | @font-face { 10 | font-family: "Font Awesome 6 Free"; 11 | font-style: normal; 12 | font-weight: 400; 13 | font-display: block; 14 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); } 15 | 16 | .far, 17 | .fa-regular { 18 | font-family: "Font Awesome 6 Free"; 19 | font-weight: 400; } 20 | -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/css/regular.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :host,:root{--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}.fa-regular,.far{font-family:"Font Awesome 6 Free";font-weight:400} -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/css/solid.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :root, :host { 7 | --fa-font-solid: normal 900 1em/1 "Font Awesome 6 Free"; } 8 | 9 | @font-face { 10 | font-family: "Font Awesome 6 Free"; 11 | font-style: normal; 12 | font-weight: 900; 13 | font-display: block; 14 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 15 | 16 | .fas, 17 | .fa-solid { 18 | font-family: "Font Awesome 6 Free"; 19 | font-weight: 900; } 20 | -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/css/solid.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :host,:root{--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-family:"Font Awesome 6 Free";font-weight:900} -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/css/v4-font-face.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face { 7 | font-family: "FontAwesome"; 8 | font-display: block; 9 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 10 | 11 | @font-face { 12 | font-family: "FontAwesome"; 13 | font-display: block; 14 | src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); } 15 | 16 | @font-face { 17 | font-family: "FontAwesome"; 18 | font-display: block; 19 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); 20 | unicode-range: U+F003,U+F006,U+F014,U+F016-F017,U+F01A-F01B,U+F01D,U+F022,U+F03E,U+F044,U+F046,U+F05C-F05D,U+F06E,U+F070,U+F087-F088,U+F08A,U+F094,U+F096-F097,U+F09D,U+F0A0,U+F0A2,U+F0A4-F0A7,U+F0C5,U+F0C7,U+F0E5-F0E6,U+F0EB,U+F0F6-F0F8,U+F10C,U+F114-F115,U+F118-F11A,U+F11C-F11D,U+F133,U+F147,U+F14E,U+F150-F152,U+F185-F186,U+F18E,U+F190-F192,U+F196,U+F1C1-F1C9,U+F1D9,U+F1DB,U+F1E3,U+F1EA,U+F1F7,U+F1F9,U+F20A,U+F247-F248,U+F24A,U+F24D,U+F255-F25B,U+F25D,U+F271-F274,U+F278,U+F27B,U+F28C,U+F28E,U+F29C,U+F2B5,U+F2B7,U+F2BA,U+F2BC,U+F2BE,U+F2C0-F2C1,U+F2C3,U+F2D0,U+F2D2,U+F2D4,U+F2DC; } 21 | 22 | @font-face { 23 | font-family: "FontAwesome"; 24 | font-display: block; 25 | src: url("../webfonts/fa-v4compatibility.woff2") format("woff2"), url("../webfonts/fa-v4compatibility.ttf") format("truetype"); 26 | unicode-range: U+F041,U+F047,U+F065-F066,U+F07D-F07E,U+F080,U+F08B,U+F08E,U+F090,U+F09A,U+F0AC,U+F0AE,U+F0B2,U+F0D0,U+F0D6,U+F0E4,U+F0EC,U+F10A-F10B,U+F123,U+F13E,U+F148-F149,U+F14C,U+F156,U+F15E,U+F160-F161,U+F163,U+F175-F178,U+F195,U+F1F8,U+F219,U+F27A; } 27 | -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/css/v4-font-face.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2"),url(../webfonts/fa-v4compatibility.ttf) format("truetype");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a} -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/css/v5-font-face.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face { 7 | font-family: "Font Awesome 5 Brands"; 8 | font-display: block; 9 | font-weight: 400; 10 | src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); } 11 | 12 | @font-face { 13 | font-family: "Font Awesome 5 Free"; 14 | font-display: block; 15 | font-weight: 900; 16 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 17 | 18 | @font-face { 19 | font-family: "Font Awesome 5 Free"; 20 | font-display: block; 21 | font-weight: 400; 22 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); } 23 | -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/css/v5-font-face.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")} -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/todo-list-example/public/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/todo-list-example/public/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/todo-list-example/public/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/todo-list-example/public/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/todo-list-example/public/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/todo-list-example/public/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/webfonts/fa-v4compatibility.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/todo-list-example/public/webfonts/fa-v4compatibility.ttf -------------------------------------------------------------------------------- /Chapter04/todo-list-example/public/webfonts/fa-v4compatibility.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter04/todo-list-example/public/webfonts/fa-v4compatibility.woff2 -------------------------------------------------------------------------------- /Chapter04/todo-list-example/src/App.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 14 | 15 | 22 | -------------------------------------------------------------------------------- /Chapter04/todo-list-example/src/assets/styles.css: -------------------------------------------------------------------------------- 1 | body{ 2 | font-family:"Ubuntu","Segoe UI", Tahoma, Geneva, Verdana, sans-serif; 3 | font-size: 15px; 4 | } 5 | 6 | .flex-container{ 7 | display: flex; 8 | } 9 | 10 | .flex-grow{ 11 | flex-grow: 1; 12 | } 13 | 14 | .flex-gap{ 15 | gap: 1rem; 16 | } 17 | 18 | .clickable{ 19 | cursor: pointer; 20 | } 21 | 22 | button{ 23 | cursor: pointer; 24 | } -------------------------------------------------------------------------------- /Chapter04/todo-list-example/src/components/ToDoFilter.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 37 | 38 | -------------------------------------------------------------------------------- /Chapter04/todo-list-example/src/components/ToDoItemForm.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 37 | 38 | -------------------------------------------------------------------------------- /Chapter04/todo-list-example/src/components/ToDoSummary.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 37 | 38 | -------------------------------------------------------------------------------- /Chapter04/todo-list-example/src/components/headers/MainHeader.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter04/todo-list-example/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from "vue" 2 | import App from "./App.vue" 3 | import Modals from "./plugins/modals" 4 | import styles from "./assets/styles.css" 5 | 6 | createApp(App) 7 | .use(Modals) 8 | .mount("#app") 9 | -------------------------------------------------------------------------------- /Chapter04/todo-list-example/src/plugins/modals/Modal.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 42 | 43 | -------------------------------------------------------------------------------- /Chapter04/todo-list-example/src/services/todo.js: -------------------------------------------------------------------------------- 1 | const service = { 2 | getDefault() { 3 | return { 4 | id: Date.now().toString(16) +"_"+ Math.ceil(Math.random()*1000).toString(16), 5 | text: "", 6 | status: "not_started" 7 | } 8 | }, 9 | getStatusList() { 10 | return [ 11 | { id: "not_started", label: "Not started" }, 12 | { id: "in_progress", label: "In progress" }, 13 | { id: "completed", label: "Completed" } 14 | ] 15 | }, 16 | validateTodo(item){ 17 | return item.text.length>0; 18 | }, 19 | makeCopy(item){ 20 | return JSON.parse(JSON.stringify(item)) 21 | }, 22 | toggleStatus(status){ 23 | switch(status){ 24 | case "not_started": 25 | return "in_progress" 26 | case "in_progress": 27 | return "completed" 28 | case "completed": 29 | return "not_started" 30 | } 31 | } 32 | } 33 | 34 | export default service; -------------------------------------------------------------------------------- /Chapter04/todo-list-example/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite" 2 | import vue from "@vitejs/plugin-vue" 3 | import path from "path" 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [vue()], 8 | resolve:{ 9 | alias:{ 10 | "@components": path.resolve(__dirname, "src", "components") 11 | } 12 | } 13 | }) 14 | -------------------------------------------------------------------------------- /Chapter05/Nested routes/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | -------------------------------------------------------------------------------- /Chapter05/Nested routes/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"] 3 | } 4 | -------------------------------------------------------------------------------- /Chapter05/Nested routes/README.md: -------------------------------------------------------------------------------- 1 | # nested-routes 2 | 3 | An example of using nested routes with views, to display information and drill down details. Part of Chapter 5 or Vue 3 Design Patterns by Pablo D. Garaguso 4 | 5 | ## Recommended IDE Setup 6 | 7 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). 8 | 9 | ## Customize configuration 10 | 11 | See [Vite Configuration Reference](https://vitejs.dev/config/). 12 | 13 | ## Project Setup 14 | 15 | ```sh 16 | npm install 17 | ``` 18 | 19 | ### Compile and Hot-Reload for Development 20 | 21 | ```sh 22 | npm run dev 23 | ``` 24 | 25 | ### Compile and Minify for Production 26 | 27 | ```sh 28 | npm run build 29 | ``` 30 | -------------------------------------------------------------------------------- /Chapter05/Nested routes/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Chapter05/Nested routes/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nested-routes", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "preview": "vite preview" 8 | }, 9 | "dependencies": { 10 | "vue": "^3.2.41", 11 | "vue-router": "^4.1.5" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-vue": "^3.1.2", 15 | "vite": "^3.1.8" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chapter05/Nested routes/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter05/Nested routes/public/favicon.ico -------------------------------------------------------------------------------- /Chapter05/Nested routes/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 18 | -------------------------------------------------------------------------------- /Chapter05/Nested routes/src/assets/main.css: -------------------------------------------------------------------------------- 1 | *{ 2 | box-sizing: border-box; 3 | margin:0; 4 | padding: 0; 5 | font-size: 1rem; 6 | } 7 | html, body{ 8 | min-height: 100vh; 9 | } 10 | 11 | a{ 12 | display: inline-block; 13 | text-decoration: none; 14 | padding-top:4px; 15 | padding-bottom:4px; 16 | } 17 | 18 | a:hover, .selected{ 19 | cursor: pointer; 20 | color: red; 21 | } -------------------------------------------------------------------------------- /Chapter05/Nested routes/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from "vue" 2 | import App from "./App.vue" 3 | import router from "./router" 4 | 5 | import "./assets/main.css" 6 | 7 | const app = createApp(App) 8 | 9 | app.use(router) 10 | 11 | app.mount("#app") 12 | -------------------------------------------------------------------------------- /Chapter05/Nested routes/src/router/index.js: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHashHistory } from "vue-router" 2 | import HomeView from "../views/Home.vue" 3 | 4 | const router = createRouter({ 5 | history: createWebHashHistory(), 6 | routes: [ 7 | { 8 | path: "/", 9 | name: "home", 10 | component: HomeView 11 | }, 12 | { 13 | path: "/directory", 14 | name: "directory", 15 | component: () => import("../views/Directory.vue"), 16 | children:[ 17 | { 18 | path: ":country", 19 | name: "states", 20 | props: true, 21 | component: ()=>import("../views/State.vue"), 22 | children:[ 23 | { 24 | path: ":state", 25 | name: "cities", 26 | props: true, 27 | component: ()=>import("../views/City.vue") 28 | } 29 | ] 30 | } 31 | ] 32 | 33 | } 34 | ] 35 | }) 36 | 37 | export default router 38 | -------------------------------------------------------------------------------- /Chapter05/Nested routes/src/services/countries.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "United States of America", 4 | "code": "USA" 5 | }, 6 | { 7 | "name": "Argentina", 8 | "code": "ARG" 9 | } 10 | ] -------------------------------------------------------------------------------- /Chapter05/Nested routes/src/services/locationService.js: -------------------------------------------------------------------------------- 1 | import countries from "./countries.json" 2 | import states from "./states.json" 3 | import USA_cities from "./USA_localities.json" 4 | import ARG_cities from "./ARG_localities.json" 5 | 6 | const LOCALITIES={ 7 | "USA": USA_cities, 8 | "ARG": ARG_cities 9 | } 10 | 11 | const service={ 12 | getCountries(){ 13 | return countries.sort(); 14 | }, 15 | getStatesByCountry(country_code){ 16 | return states[country_code].sort() 17 | }, 18 | getCitiesByCountryAndState(country_code, state_name){ 19 | let cities=LOCALITIES[country_code].filter(item=>{ 20 | return state_name==item.state 21 | }) 22 | return cities.sort(); 23 | } 24 | } 25 | 26 | export default service; -------------------------------------------------------------------------------- /Chapter05/Nested routes/src/services/states.json: -------------------------------------------------------------------------------- 1 | { 2 | "USA": [ 3 | "Alabama", 4 | "Alaska", 5 | "Arizona", 6 | "Arkansas", 7 | "California", 8 | "Colorado", 9 | "Connecticut", 10 | "Delaware", 11 | "Florida", 12 | "Georgia", 13 | "Hawaii", 14 | "Idaho", 15 | "Illinois", 16 | "Indiana", 17 | "Iowa", 18 | "Kansas", 19 | "Kentucky", 20 | "Louisiana", 21 | "Maine", 22 | "Maryland", 23 | "Massachusetts", 24 | "Michigan", 25 | "Minnesota", 26 | "Mississippi", 27 | "Missouri", 28 | "Montana", 29 | "Nebraska", 30 | "Nevada", 31 | "New Hampshire", 32 | "New Jersey", 33 | "New Mexico", 34 | "New York", 35 | "North Carolina", 36 | "North Dakota", 37 | "Ohio", 38 | "Oklahoma", 39 | "Oregon", 40 | "Pennsylvania", 41 | "Rhode Island", 42 | "South Carolina", 43 | "South Dakota", 44 | "Tennessee", 45 | "Texas", 46 | "Utah", 47 | "Vermont", 48 | "Virginia", 49 | "Washington", 50 | "West Virginia", 51 | "Wisconsin", 52 | "Wyoming" 53 | ], 54 | "ARG": [ 55 | "Misiones", 56 | "San Luis", 57 | "San Juan", 58 | "Entre Ríos", 59 | "Santa Cruz", 60 | "Río Negro", 61 | "Chubut", 62 | "Córdoba", 63 | "Mendoza", 64 | "La Rioja", 65 | "Catamarca", 66 | "La Pampa", 67 | "Santiago del Estero", 68 | "Corrientes", 69 | "Santa Fe", 70 | "Tucumán", 71 | "Neuquén", 72 | "Salta", 73 | "Chaco", 74 | "Formosa", 75 | "Jujuy", 76 | "Ciudad Autónoma de Buenos Aires", 77 | "Buenos Aires", 78 | "Tierra del Fuego, Antártida e Islas del Atlántico Sur" 79 | ] 80 | } -------------------------------------------------------------------------------- /Chapter05/Nested routes/src/views/City.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 40 | 41 | -------------------------------------------------------------------------------- /Chapter05/Nested routes/src/views/Directory.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 23 | 24 | -------------------------------------------------------------------------------- /Chapter05/Nested routes/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /Chapter05/Nested routes/src/views/State.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 28 | 29 | -------------------------------------------------------------------------------- /Chapter05/Nested routes/vite.config.js: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from "node:url" 2 | 3 | import { defineConfig } from "vite" 4 | import vue from "@vitejs/plugin-vue" 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [vue()], 9 | resolve: { 10 | alias: { 11 | "@": fileURLToPath(new URL("./src", import.meta.url)) 12 | } 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/README.md: -------------------------------------------------------------------------------- 1 | # To-Do List Single Page Application - Chapter 5 2 | 3 | ## Created by Pablo D. Garaguso (2022) 4 | 5 | This application builds on the concepts seen from chapters 1 to 5. 6 | 7 | To install dependencies run: 8 | 9 | `npm install` 10 | 11 | To run the application in developer mode, run: 12 | 13 | `npm run serve` 14 | 15 | Follow the instructions on the terminal to open the website in your browser. -------------------------------------------------------------------------------- /Chapter05/to-do SPA/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Chapter 5 - ToDo lists with routing, by P.D.G. 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter-5-todo", 3 | "private": true, 4 | "version": "1.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "mitt": "^3.0.0", 13 | "vue": "^3.2.37", 14 | "vue-router": "^4.1.5" 15 | }, 16 | "devDependencies": { 17 | "@vitejs/plugin-vue": "^3.0.3", 18 | "vite": "^3.0.7" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/css/regular.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :root, :host { 7 | --fa-font-regular: normal 400 1em/1 "Font Awesome 6 Free"; } 8 | 9 | @font-face { 10 | font-family: "Font Awesome 6 Free"; 11 | font-style: normal; 12 | font-weight: 400; 13 | font-display: block; 14 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); } 15 | 16 | .far, 17 | .fa-regular { 18 | font-family: "Font Awesome 6 Free"; 19 | font-weight: 400; } 20 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/css/regular.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :host,:root{--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}.fa-regular,.far{font-family:"Font Awesome 6 Free";font-weight:400} -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/css/solid.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :root, :host { 7 | --fa-font-solid: normal 900 1em/1 "Font Awesome 6 Free"; } 8 | 9 | @font-face { 10 | font-family: "Font Awesome 6 Free"; 11 | font-style: normal; 12 | font-weight: 900; 13 | font-display: block; 14 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 15 | 16 | .fas, 17 | .fa-solid { 18 | font-family: "Font Awesome 6 Free"; 19 | font-weight: 900; } 20 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/css/solid.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :host,:root{--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-family:"Font Awesome 6 Free";font-weight:900} -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/css/v4-font-face.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face { 7 | font-family: "FontAwesome"; 8 | font-display: block; 9 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 10 | 11 | @font-face { 12 | font-family: "FontAwesome"; 13 | font-display: block; 14 | src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); } 15 | 16 | @font-face { 17 | font-family: "FontAwesome"; 18 | font-display: block; 19 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); 20 | unicode-range: U+F003,U+F006,U+F014,U+F016-F017,U+F01A-F01B,U+F01D,U+F022,U+F03E,U+F044,U+F046,U+F05C-F05D,U+F06E,U+F070,U+F087-F088,U+F08A,U+F094,U+F096-F097,U+F09D,U+F0A0,U+F0A2,U+F0A4-F0A7,U+F0C5,U+F0C7,U+F0E5-F0E6,U+F0EB,U+F0F6-F0F8,U+F10C,U+F114-F115,U+F118-F11A,U+F11C-F11D,U+F133,U+F147,U+F14E,U+F150-F152,U+F185-F186,U+F18E,U+F190-F192,U+F196,U+F1C1-F1C9,U+F1D9,U+F1DB,U+F1E3,U+F1EA,U+F1F7,U+F1F9,U+F20A,U+F247-F248,U+F24A,U+F24D,U+F255-F25B,U+F25D,U+F271-F274,U+F278,U+F27B,U+F28C,U+F28E,U+F29C,U+F2B5,U+F2B7,U+F2BA,U+F2BC,U+F2BE,U+F2C0-F2C1,U+F2C3,U+F2D0,U+F2D2,U+F2D4,U+F2DC; } 21 | 22 | @font-face { 23 | font-family: "FontAwesome"; 24 | font-display: block; 25 | src: url("../webfonts/fa-v4compatibility.woff2") format("woff2"), url("../webfonts/fa-v4compatibility.ttf") format("truetype"); 26 | unicode-range: U+F041,U+F047,U+F065-F066,U+F07D-F07E,U+F080,U+F08B,U+F08E,U+F090,U+F09A,U+F0AC,U+F0AE,U+F0B2,U+F0D0,U+F0D6,U+F0E4,U+F0EC,U+F10A-F10B,U+F123,U+F13E,U+F148-F149,U+F14C,U+F156,U+F15E,U+F160-F161,U+F163,U+F175-F178,U+F195,U+F1F8,U+F219,U+F27A; } 27 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/css/v4-font-face.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2"),url(../webfonts/fa-v4compatibility.ttf) format("truetype");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a} -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/css/v5-font-face.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face { 7 | font-family: "Font Awesome 5 Brands"; 8 | font-display: block; 9 | font-weight: 400; 10 | src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); } 11 | 12 | @font-face { 13 | font-family: "Font Awesome 5 Free"; 14 | font-display: block; 15 | font-weight: 900; 16 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 17 | 18 | @font-face { 19 | font-family: "Font Awesome 5 Free"; 20 | font-display: block; 21 | font-weight: 400; 22 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); } 23 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/css/v5-font-face.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")} -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter05/to-do SPA/public/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter05/to-do SPA/public/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter05/to-do SPA/public/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter05/to-do SPA/public/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter05/to-do SPA/public/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter05/to-do SPA/public/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/webfonts/fa-v4compatibility.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter05/to-do SPA/public/webfonts/fa-v4compatibility.ttf -------------------------------------------------------------------------------- /Chapter05/to-do SPA/public/webfonts/fa-v4compatibility.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter05/to-do SPA/public/webfonts/fa-v4compatibility.woff2 -------------------------------------------------------------------------------- /Chapter05/to-do SPA/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 13 | 14 | 28 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/src/assets/styles.css: -------------------------------------------------------------------------------- 1 | *{ 2 | box-sizing: border-box; 3 | } 4 | 5 | html, body{ 6 | margin:0; 7 | padding: 0; 8 | } 9 | body{ 10 | font-family:"Ubuntu","Segoe UI", Tahoma, Geneva, Verdana, sans-serif; 11 | font-size: 15px; 12 | } 13 | 14 | .flex-container{ 15 | display: flex; 16 | } 17 | 18 | .flex-grow{ 19 | flex-grow: 1; 20 | } 21 | 22 | .flex-gap{ 23 | gap: 1rem; 24 | } 25 | 26 | .clickable{ 27 | cursor: pointer; 28 | } 29 | 30 | 31 | button{ 32 | cursor: pointer; 33 | } 34 | 35 | .strong{ 36 | font-weight: 900; 37 | } -------------------------------------------------------------------------------- /Chapter05/to-do SPA/src/components/Sidebar/Sidebar.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 49 | 50 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/src/components/ToDos/ToDoFilter.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 37 | 38 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/src/components/ToDos/ToDoItemForm.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 37 | 38 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/src/components/ToDos/ToDoSummary.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 37 | 38 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from "vue" 2 | import router from "./router" 3 | import App from "./App.vue" 4 | import Modals from "./plugins/modals" 5 | import styles from "./assets/styles.css" 6 | 7 | createApp(App) 8 | .use(router) 9 | .use(Modals) 10 | .mount("#app") 11 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/src/plugins/modals/Modal.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 42 | 43 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/src/router/index.js: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHashHistory } from "vue-router" 2 | import Landing from "../views/Landing.vue" 3 | 4 | const 5 | routes = [ 6 | { 7 | path: "/", 8 | name: "landing", 9 | component: Landing 10 | }, 11 | { 12 | path: "/project/:id", 13 | name: "project", 14 | component: () => import("../views/ToDoProject.vue"), 15 | props: true 16 | } 17 | ], 18 | router = createRouter({ 19 | history: createWebHashHistory(), 20 | routes, 21 | scrollBehavior(to, from, savedPosition) { 22 | // always scroll to top 23 | return { top: 0 } 24 | } 25 | }) 26 | 27 | export default router; -------------------------------------------------------------------------------- /Chapter05/to-do SPA/src/services/eventBus.js: -------------------------------------------------------------------------------- 1 | import mitt from "mitt" 2 | 3 | const eventBus = new mitt() 4 | 5 | export default eventBus -------------------------------------------------------------------------------- /Chapter05/to-do SPA/src/views/Landing.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 46 | 47 | -------------------------------------------------------------------------------- /Chapter05/to-do SPA/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite" 2 | import vue from "@vitejs/plugin-vue" 3 | import path from "path" 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [vue()], 8 | resolve:{ 9 | alias:{ 10 | "@components": path.resolve(__dirname, "src", "components") 11 | } 12 | } 13 | }) 14 | -------------------------------------------------------------------------------- /Chapter06/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /Chapter06/.hintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "development" 4 | ], 5 | "browserslist": [ 6 | "defaults", 7 | "not ie 11", 8 | "not and_ff <= 110", 9 | "not firefox <= 111", 10 | "not ios_saf <= 14.8", 11 | "not opera <= 95" 12 | ] 13 | } -------------------------------------------------------------------------------- /Chapter06/manual-upscale-spa/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar"] 3 | } 4 | -------------------------------------------------------------------------------- /Chapter06/manual-upscale-spa/README.md: -------------------------------------------------------------------------------- 1 | # Chapter 6 2 | 3 | This example code provides the bare minimum code and configuration to create a working Progressive Web Application. Use this code as companion for Chapter 6. 4 | 5 | ## Installation 6 | 7 | Download the code, and install dependencies from the terminal in the root directory with the command: 8 | 9 | `npm install` 10 | 11 | Run the application with: 12 | 13 | `npm run dev` 14 | 15 | The application can be built for production with the following command: 16 | 17 | `npm run build` 18 | 19 | ## Recommended IDE Setup 20 | 21 | - [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) 22 | 23 | *** 24 | 25 | By **Pablo David Garaguso** -------------------------------------------------------------------------------- /Chapter06/manual-upscale-spa/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Vue 3 Design Patterns - Chapter 6 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /Chapter06/manual-upscale-spa/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter-6", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview", 10 | "dev-host": "vite --host" 11 | }, 12 | "dependencies": { 13 | "vue": "^3.2.41" 14 | }, 15 | "devDependencies": { 16 | "@vitejs/plugin-vue": "^3.2.0", 17 | "vite": "^3.2.3" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chapter06/manual-upscale-spa/public/images/chapter_6_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter06/manual-upscale-spa/public/images/chapter_6_icon.png -------------------------------------------------------------------------------- /Chapter06/manual-upscale-spa/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name":"PWA Example", 3 | "name": "Chapter 6 - Progressive Web Application Example", 4 | "start_url":"/", 5 | "display": "standalone", 6 | "theme_color":"#2979FF", 7 | "background_color":"#000000", 8 | "orientation": "portrait", 9 | "icons":[ 10 | { 11 | "src":"/images/chapter_6_icon.png", 12 | "sizes":"512x512", 13 | "type":"image/png" 14 | } 15 | ], 16 | "prefer_related_applications": false 17 | } -------------------------------------------------------------------------------- /Chapter06/manual-upscale-spa/public/service_worker.js: -------------------------------------------------------------------------------- 1 | // Service Worker v1.0 2 | 3 | const CACHE_NAME="MyCache" 4 | 5 | self.addEventListener("install", event => { 6 | console.log("Service worker installed"); 7 | }); 8 | 9 | self.addEventListener("activate", event => { 10 | console.log("Service worker activated"); 11 | }); 12 | 13 | // Set strategy, cache first, then network 14 | self.addEventListener("fetch", event=>{ 15 | 16 | // Intercepts the event to respond 17 | event.respondWith((async ()=>{ 18 | 19 | 20 | // Try to find the request in the cache 21 | const found=await caches.match(event.request); 22 | console.log(found) 23 | if(found){ 24 | return found; 25 | }else{ 26 | // Not cached yet, request from the network 27 | const response=await fetch(event.request); 28 | 29 | // Open the cache 30 | const cache=await caches.open(CACHE_NAME); 31 | 32 | // Place the network response in the cache 33 | cache.put(event.request, response.clone()); 34 | 35 | // Return the response 36 | return response; 37 | } 38 | })()) 39 | }) -------------------------------------------------------------------------------- /Chapter06/manual-upscale-spa/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter06/manual-upscale-spa/src/App.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | 63 | 64 | 69 | -------------------------------------------------------------------------------- /Chapter06/manual-upscale-spa/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import './style.css' 3 | import App from './App.vue' 4 | 5 | // Check if browser supports service workers 6 | if(navigator.serviceWorker){ 7 | navigator.serviceWorker.register("/service_worker.js"); 8 | } 9 | 10 | createApp(App).mount('#app') 11 | -------------------------------------------------------------------------------- /Chapter06/manual-upscale-spa/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif; 3 | font-size: 16px; 4 | line-height: 24px; 5 | font-weight: 400; 6 | 7 | color-scheme: light dark; 8 | color: rgba(255, 255, 255, 0.87); 9 | background-color: #242424; 10 | 11 | font-synthesis: none; 12 | text-rendering: optimizeLegibility; 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | -webkit-text-size-adjust: 100%; 16 | } 17 | 18 | a { 19 | font-weight: 500; 20 | color: #646cff; 21 | text-decoration: inherit; 22 | } 23 | a:hover { 24 | color: #535bf2; 25 | } 26 | 27 | a { 28 | font-weight: 500; 29 | color: #646cff; 30 | text-decoration: inherit; 31 | cursor: pointer; 32 | } 33 | a:hover { 34 | color: #535bf2; 35 | text-decoration: underline; 36 | } 37 | 38 | body { 39 | margin: 0; 40 | } 41 | 42 | h1 { 43 | font-size: 3.2em; 44 | line-height: 1.1; 45 | } 46 | 47 | button { 48 | border-radius: 8px; 49 | border: 1px solid transparent; 50 | padding: 0.6em 1.2em; 51 | font-size: 1em; 52 | font-weight: 500; 53 | font-family: inherit; 54 | background-color: #1a1a1a; 55 | color:white; 56 | cursor: pointer; 57 | transition: border-color 0.25s; 58 | } 59 | button:hover { 60 | background-color: #646cff; 61 | } 62 | button:focus, 63 | button:focus-visible { 64 | outline: 4px auto -webkit-focus-ring-color; 65 | } 66 | 67 | .card { 68 | padding: 2em; 69 | } 70 | 71 | 72 | @media (prefers-color-scheme: light) { 73 | :root { 74 | color: #213547; 75 | background-color: #ffffff; 76 | } 77 | a:hover { 78 | color: #747bff; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Chapter06/manual-upscale-spa/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | // import basicSSL from "@vitejs/plugin-basic-ssl" 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [vue()] 8 | }) 9 | -------------------------------------------------------------------------------- /Chapter06/vite-pwa-plugin/README.md: -------------------------------------------------------------------------------- 1 | # Chapter 6 2 | 3 | This example code provides code and configuration to create a Progressive Web Application, using Vite-PWA plugin. Use this code as companion for Chapter 6. 4 | 5 | ## Installation 6 | 7 | Download the code, and install dependencies from the terminal in the root directory with the command: 8 | 9 | `npm install` 10 | 11 | Run the application with: 12 | 13 | `npm run dev` 14 | 15 | The application can be built for production with the following command: 16 | 17 | `npm run build` 18 | 19 | ## Recommended IDE Setup 20 | 21 | - [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) 22 | 23 | *** 24 | 25 | By **Pablo David Garaguso** -------------------------------------------------------------------------------- /Chapter06/vite-pwa-plugin/dev-dist/registerSW.js: -------------------------------------------------------------------------------- 1 | if('serviceWorker' in navigator) navigator.serviceWorker.register('/dev-sw.js?dev-sw', { scope: '/', type: 'classic' }) -------------------------------------------------------------------------------- /Chapter06/vite-pwa-plugin/dev-dist/sw.js: -------------------------------------------------------------------------------- 1 | if(!self.define){let e,t={};const i=(i,n)=>(i=new URL(i+".js",n).href,t[i]||new Promise((t=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=t,document.head.appendChild(e)}else e=i,importScripts(i),t()})).then((()=>{let e=t[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e})));self.define=(n,r)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(t[o])return;let s={};const l=e=>i(e,o),u={module:{uri:o},exports:s,require:l};t[o]=Promise.all(n.map((e=>u[e]||l(e)))).then((e=>(r(...e),s)))}}define(["./workbox-3625d7b0"],(function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"registerSW.js",revision:"3ca0b8505b4bec776b69afdba2768812"},{revision:null,url:"index.html"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html"),{allowlist:[/^\/$/]}))})); 2 | -------------------------------------------------------------------------------- /Chapter06/vite-pwa-plugin/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Vue 3 Design Patterns - Chapter 6 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Chapter06/vite-pwa-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter-6", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview", 10 | "dev-host": "vite --host" 11 | }, 12 | "dependencies": { 13 | "vue": "^3.2.41" 14 | }, 15 | "devDependencies": { 16 | "@vitejs/plugin-vue": "^3.2.0", 17 | "vite": "^3.2.3", 18 | "vite-plugin-pwa": "^0.13.3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chapter06/vite-pwa-plugin/public/images/chapter_6_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter06/vite-pwa-plugin/public/images/chapter_6_icon.png -------------------------------------------------------------------------------- /Chapter06/vite-pwa-plugin/public/images/chapter_6_icon_192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter06/vite-pwa-plugin/public/images/chapter_6_icon_192x192.png -------------------------------------------------------------------------------- /Chapter06/vite-pwa-plugin/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / -------------------------------------------------------------------------------- /Chapter06/vite-pwa-plugin/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter06/vite-pwa-plugin/src/App.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | 63 | 64 | 69 | -------------------------------------------------------------------------------- /Chapter06/vite-pwa-plugin/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import './style.css' 3 | import App from './App.vue' 4 | 5 | createApp(App).mount('#app') 6 | -------------------------------------------------------------------------------- /Chapter06/vite-pwa-plugin/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif; 3 | font-size: 16px; 4 | line-height: 24px; 5 | font-weight: 400; 6 | 7 | color-scheme: light dark; 8 | color: rgba(255, 255, 255, 0.87); 9 | background-color: #242424; 10 | 11 | font-synthesis: none; 12 | text-rendering: optimizeLegibility; 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | -webkit-text-size-adjust: 100%; 16 | } 17 | 18 | a { 19 | font-weight: 500; 20 | color: #646cff; 21 | text-decoration: inherit; 22 | } 23 | a:hover { 24 | color: #535bf2; 25 | } 26 | 27 | a { 28 | font-weight: 500; 29 | color: #646cff; 30 | text-decoration: inherit; 31 | cursor: pointer; 32 | } 33 | a:hover { 34 | color: #535bf2; 35 | text-decoration: underline; 36 | } 37 | 38 | body { 39 | margin: 0; 40 | } 41 | 42 | h1 { 43 | font-size: 3.2em; 44 | line-height: 1.1; 45 | } 46 | 47 | button { 48 | border-radius: 8px; 49 | border: 1px solid transparent; 50 | padding: 0.6em 1.2em; 51 | font-size: 1em; 52 | font-weight: 500; 53 | font-family: inherit; 54 | background-color: #1a1a1a; 55 | color:white; 56 | cursor: pointer; 57 | transition: border-color 0.25s; 58 | } 59 | button:hover { 60 | background-color: #646cff; 61 | } 62 | button:focus, 63 | button:focus-visible { 64 | outline: 4px auto -webkit-focus-ring-color; 65 | } 66 | 67 | .card { 68 | padding: 2em; 69 | } 70 | 71 | 72 | @media (prefers-color-scheme: light) { 73 | :root { 74 | color: #213547; 75 | background-color: #ffffff; 76 | } 77 | a:hover { 78 | color: #747bff; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Chapter06/vite-pwa-plugin/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | import { VitePWA } from 'vite-plugin-pwa' 4 | 5 | export default defineConfig({ 6 | plugins: [ 7 | vue(), 8 | VitePWA({ 9 | registerType: "autoUpdate", 10 | injectRegister: 'auto', 11 | devOptions: { enabled: true }, 12 | workbox: { 13 | globPatterns: ['**/*.{js,css,html,ico,png,svg}'] 14 | }, 15 | includeAssets: ['fonts/*.ttf', 'images/*.png', 'css/*.css'], 16 | manifest: { 17 | "short_name": "PWA Example", 18 | "name": "Chapter 6 - Progressive Web Application Example", 19 | "start_url": "/", 20 | "display": "standalone", 21 | "theme_color": "#333333", 22 | "background_color": "#000000", 23 | "orientation": "portrait", 24 | "icons": [ 25 | { 26 | "src": "/images/chapter_6_icon_192x192.png", 27 | "sizes": "192x192", 28 | "type": "image/png" 29 | }, 30 | { 31 | "src": "/images/chapter_6_icon.png", 32 | "sizes": "512x512", 33 | "type": "image/png" 34 | }, 35 | { 36 | "src": "/images/chapter_6_icon.png", 37 | "sizes": "512x512", 38 | "type": "image/png", 39 | "purpose":"maskable" 40 | } 41 | ], 42 | "prefer_related_applications": false 43 | } 44 | })] 45 | }) 46 | -------------------------------------------------------------------------------- /Chapter07/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | -------------------------------------------------------------------------------- /Chapter07/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"] 3 | } 4 | -------------------------------------------------------------------------------- /Chapter07/README.md: -------------------------------------------------------------------------------- 1 | # chapter-7 2 | 3 | This template should help get you started developing with Vue 3 in Vite. 4 | 5 | ## Recommended IDE Setup 6 | 7 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). 8 | 9 | ## Customize configuration 10 | 11 | See [Vite Configuration Reference](https://vitejs.dev/config/). 12 | 13 | ## Project Setup 14 | 15 | ```sh 16 | npm install 17 | ``` 18 | 19 | ### Compile and Hot-Reload for Development 20 | 21 | ```sh 22 | npm run dev 23 | ``` 24 | 25 | ### Compile and Minify for Production 26 | 27 | ```sh 28 | npm run build 29 | ``` 30 | -------------------------------------------------------------------------------- /Chapter07/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Chapter 7 - Data workflow 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Chapter07/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter-7", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "mitt": "^3.0.0", 12 | "pinia": "^2.0.26", 13 | "vue": "^3.2.45" 14 | }, 15 | "devDependencies": { 16 | "@vitejs/plugin-vue": "^3.2.0", 17 | "vite": "^3.2.4" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chapter07/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/Chapter07/public/favicon.ico -------------------------------------------------------------------------------- /Chapter07/src/App.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 42 | 43 | 46 | -------------------------------------------------------------------------------- /Chapter07/src/assets/main.css: -------------------------------------------------------------------------------- 1 | *{ 2 | box-sizing: border-box; 3 | } 4 | 5 | :root{ 6 | --padding: 1rem; 7 | --shadow: rgba(0,0,30,0.1); 8 | } 9 | 10 | html, body{ 11 | width: 100%; 12 | height: 100%; 13 | font-size: 1rem; 14 | font-family: 'Open Sans', sans-serif; 15 | user-select: none; 16 | } 17 | 18 | body{ 19 | margin:0; 20 | padding: var(--padding); 21 | } 22 | 23 | .padding{ 24 | padding: var(--padding); 25 | } 26 | 27 | .semi-padding{ 28 | padding-top: var(--padding); 29 | padding-bottom: var(--padding); 30 | } 31 | 32 | .side-padding{ 33 | padding-left: var(--padding); 34 | padding-right: var(--padding); 35 | } 36 | 37 | .with-background{ 38 | background-color: var(--shadow); 39 | } 40 | 41 | .badge{ 42 | display: inline-block; 43 | text-align: center; 44 | color: red; 45 | font-weight: 700; 46 | background-color: white; 47 | padding: 4px 8px; 48 | border-radius: 1rem; 49 | min-width: 3rem; 50 | border: 1px solid var(--shadow); 51 | } 52 | 53 | .flex-container{ 54 | display: flex; 55 | gap: var(--padding); 56 | } 57 | 58 | .flex-wrap{ 59 | flex-wrap: wrap; 60 | } 61 | 62 | button{ 63 | cursor: pointer; 64 | padding: calc(var(--padding) / 1.6) var(--padding); 65 | } -------------------------------------------------------------------------------- /Chapter07/src/components/basic/Child.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 23 | 24 | -------------------------------------------------------------------------------- /Chapter07/src/components/basic/ParentBasic.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 43 | 44 | -------------------------------------------------------------------------------- /Chapter07/src/components/bus/Child.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 41 | 42 | -------------------------------------------------------------------------------- /Chapter07/src/components/bus/ParentBus.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 17 | 18 | -------------------------------------------------------------------------------- /Chapter07/src/components/pinia/ChildPinia.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | 17 | -------------------------------------------------------------------------------- /Chapter07/src/components/pinia/ParentPinia.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 29 | 30 | -------------------------------------------------------------------------------- /Chapter07/src/components/session_storage/ChildSession.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | 15 | -------------------------------------------------------------------------------- /Chapter07/src/components/session_storage/ParentSession.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 37 | 38 | -------------------------------------------------------------------------------- /Chapter07/src/components/simple/ChildSimple.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter07/src/components/simple/ParentSimple.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 30 | 31 | -------------------------------------------------------------------------------- /Chapter07/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import { createPinia } from 'pinia' 3 | import App from './App.vue' 4 | 5 | import './assets/main.css' 6 | 7 | const app = createApp(App) 8 | 9 | app.use(createPinia()) 10 | 11 | app.mount('#app') 12 | -------------------------------------------------------------------------------- /Chapter07/src/services/MessageBus.js: -------------------------------------------------------------------------------- 1 | import mitt from "mitt" 2 | 3 | const MessageBus = new mitt() 4 | 5 | export default MessageBus -------------------------------------------------------------------------------- /Chapter07/src/services/SimpleState.js: -------------------------------------------------------------------------------- 1 | /** 2 | A Vue 3 Composable for a simple application wide reactive state 3 | */ 4 | 5 | import { reactive } from "vue" 6 | 7 | const 8 | _state=reactive({ counter: 0 }) 9 | 10 | function useState(){ 11 | return _state; 12 | } 13 | 14 | export default useState; -------------------------------------------------------------------------------- /Chapter07/src/services/sessionStorage.js: -------------------------------------------------------------------------------- 1 | import { reactive } from 'vue'; 2 | 3 | 4 | let handler = { 5 | 6 | // Internal reactive object to keep in sync 7 | props: reactive({}), 8 | 9 | // Get trap, to intercept properties and methods 10 | get(target, prop, receiver) { 11 | 12 | // Check if the target has the property 13 | let value = target[prop] 14 | 15 | if (value instanceof Function) { 16 | // Call of a native method, pass it through 17 | return (...args) => { 18 | return target[prop](...args) 19 | } 20 | 21 | } else { 22 | 23 | // Check if the value exists in the store 24 | value = target.getItem(prop) 25 | 26 | if (value) { 27 | // A value exists already, sets it as default 28 | this.props[prop] = value; 29 | } 30 | 31 | // Request of a property, return it 32 | return this.props[prop] 33 | } 34 | }, 35 | 36 | // Set operations, to handle normal assignments 37 | set(target, prop, value) { 38 | 39 | // Keep storage and internal reactivity in sync 40 | target.setItem(prop, value) 41 | this.props[prop] = value 42 | 43 | // Operation Ok 44 | return true; 45 | } 46 | } 47 | 48 | const Decorator= new Proxy(window.sessionStorage, handler); 49 | 50 | function useSessionStorage(){ 51 | return Decorator; 52 | } 53 | 54 | // We capture both types of imports 55 | export default useSessionStorage; 56 | export { useSessionStorage } -------------------------------------------------------------------------------- /Chapter07/src/stores/counter.js: -------------------------------------------------------------------------------- 1 | // Using composition API 2 | 3 | import { ref, computed } from 'vue' 4 | import { defineStore } from 'pinia' 5 | 6 | const useCounterStore = defineStore('counter', () => { 7 | const 8 | count = ref(0), 9 | in_range=ref(true) 10 | 11 | const 12 | doubleCount = computed(() => { 13 | if(count.value>=0){ 14 | return count.value *2; 15 | }else{ 16 | return 0 17 | } 18 | }), 19 | inRange = computed(()=>{ 20 | return count.value>=0; 21 | }) 22 | 23 | 24 | function increment() { 25 | count.value++ 26 | } 27 | 28 | function decrement(){ 29 | count.value--; 30 | } 31 | 32 | return { count, doubleCount, inRange, increment, decrement } 33 | }); 34 | 35 | export {useCounterStore }; -------------------------------------------------------------------------------- /Chapter07/vite.config.js: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url' 2 | 3 | import { defineConfig } from 'vite' 4 | import vue from '@vitejs/plugin-vue' 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [vue()], 9 | resolve: { 10 | alias: { 11 | '@': fileURLToPath(new URL('./src', import.meta.url)) 12 | } 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /Chapter08/client/README.md: -------------------------------------------------------------------------------- 1 | # Vue 3 + Vite 2 | 3 | This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 ` 12 | 13 | 14 | -------------------------------------------------------------------------------- /Chapter08/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter8", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "start":"vite", 9 | "build": "vite build", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "axios": "^1.2.1", 14 | "dexie": "^3.2.2", 15 | "vue": "^3.2.45" 16 | }, 17 | "devDependencies": { 18 | "@vitejs/plugin-vue": "^4.0.0", 19 | "vite": "^4.0.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chapter08/client/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter08/client/src/App.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 46 | 47 | 50 | -------------------------------------------------------------------------------- /Chapter08/client/src/components/NetworkCommunication.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 50 | 51 | -------------------------------------------------------------------------------- /Chapter08/client/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import './style.css' 3 | import App from './App.vue' 4 | 5 | createApp(App).mount('#app') 6 | -------------------------------------------------------------------------------- /Chapter08/client/src/services/WebWorker.js: -------------------------------------------------------------------------------- 1 | import WebWorker from "../webworker/index.js?worker" 2 | 3 | const _worker = new WebWorker() 4 | 5 | const service = { 6 | queue:{}, 7 | request(command, payload = {}) { 8 | return new Promise((resolve, reject) => { 9 | 10 | // Command message for the web worker 11 | let message = { 12 | id: crypto.randomUUID(), 13 | command, 14 | payload//: JSON.stringify(payload) 15 | } 16 | 17 | // Save reference 18 | service.queue[message.id]={resolve, reject} 19 | 20 | // Dispatch the message 21 | _worker.postMessage(message); 22 | 23 | }) 24 | }, 25 | processMessage(data) { 26 | let id=data.id 27 | if(data.success){ 28 | service.queue[id].resolve(data.payload) 29 | }else{ 30 | service.queue[id].reject(data.payload) 31 | } 32 | delete service.queue[id]; 33 | } 34 | } 35 | 36 | _worker.onmessage = (event) => { 37 | service.processMessage(event.data); 38 | } 39 | 40 | export default service; -------------------------------------------------------------------------------- /Chapter08/client/src/style.css: -------------------------------------------------------------------------------- 1 | *{ 2 | box-sizing: border-box; 3 | } 4 | 5 | :root{ 6 | --padding: 1rem; 7 | --gray: #ccc; 8 | } 9 | 10 | html, body{ 11 | padding:0; 12 | margin:0; 13 | width: 100%; 14 | height: 100%; 15 | font-family: sans-serif; 16 | } 17 | 18 | .padded{ 19 | padding: var(--padding); 20 | } 21 | 22 | .flex-container{ 23 | display: flex; 24 | } 25 | 26 | .flex-justify{ 27 | justify-content: space-between; 28 | } 29 | 30 | .flex-grow{ 31 | flex-grow: 1; 32 | } 33 | 34 | .gap{ 35 | gap: 2rem; 36 | } 37 | 38 | button{ 39 | padding: 0.6rem 1rem; 40 | background-color: var(--gray); 41 | border: 2px solid; 42 | cursor: pointer; 43 | } 44 | 45 | button:hover{ 46 | filter: brightness(1.1); 47 | } 48 | 49 | input, textarea{ 50 | padding: 4px; 51 | width: 100%; 52 | border: 1px solid var(--gray); 53 | } 54 | 55 | textarea{ 56 | min-height: 4rem; 57 | resize: none; 58 | } 59 | 60 | label{ 61 | display: flex; 62 | align-content: center; 63 | } 64 | 65 | label > input{ 66 | width: auto; 67 | margin: 0 8px; 68 | } -------------------------------------------------------------------------------- /Chapter08/client/src/webworker/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | Web Worker 3 | Handles communications and database operations 4 | */ 5 | import dbService from "./services/dbService"; 6 | import netService from "./services/network" 7 | import testService from "./services/test" 8 | 9 | const services=[dbService, netService, testService] 10 | 11 | function sendRequest(id, success=false, payload={}){ 12 | self.postMessage({id, success, payload}) 13 | } 14 | 15 | self.onmessage=(event)=>{ 16 | let data=event.data, 17 | payload=data.payload 18 | ; 19 | services.forEach(service=>{ 20 | if(service[data.command]){ 21 | service[data.command](payload).then(result=>{ 22 | sendRequest(data.id, true, result) 23 | }, err=>{ 24 | sendRequest(data.id, false, err) 25 | }) 26 | } 27 | }) 28 | } 29 | 30 | console.log("Web Worker ready!") -------------------------------------------------------------------------------- /Chapter08/client/src/webworker/services/dbService.js: -------------------------------------------------------------------------------- 1 | import Dexie from "dexie" 2 | 3 | // Start up database 4 | const db=new Dexie("Notes") 5 | 6 | // DB versioning 7 | db.version(1).stores({ 8 | notes: "++id,title" // Makes "title" searchable 9 | }) 10 | 11 | const service={ 12 | 13 | addNote(note={}){ 14 | return new Promise(async (resolve, reject)=>{ 15 | try{ 16 | let result_id=await db.notes.add(JSON.parse(note)) 17 | resolve({id:result_id}) 18 | }catch(err){ 19 | console.log(err) 20 | reject({}) 21 | } 22 | }) 23 | }, 24 | getNotes(){ 25 | return new Promise(async (resolve, reject)=>{ 26 | try{ 27 | let result=await db.notes.toArray(); 28 | resolve(result) 29 | }catch{ 30 | reject([]) 31 | } 32 | }) 33 | }, 34 | deleteNote({id}){ 35 | return new Promise(async (resolve, reject)=>{ 36 | try{ 37 | let result=await db.notes.delete(id) 38 | resolve({}) 39 | }catch{ 40 | reject({}) 41 | } 42 | }) 43 | } 44 | 45 | } 46 | 47 | export default service; -------------------------------------------------------------------------------- /Chapter08/client/src/webworker/services/network.js: -------------------------------------------------------------------------------- 1 | import axios from "axios" 2 | 3 | axios.defaults.baseURL="http://localhost:3000" 4 | 5 | const service={ 6 | GET(payload={}){ 7 | return new Promise((resolve, reject)=>{ 8 | axios 9 | .get(payload.url, {params: { data: payload.data}} ) 10 | .then(result=>{ 11 | if(result.status>=200 && result.status<300){ 12 | resolve(result.data) 13 | }else{ 14 | reject() 15 | } 16 | }) 17 | .catch(()=>{ 18 | reject() 19 | }) 20 | 21 | }) 22 | 23 | }, 24 | POST(payload={}){ 25 | return new Promise((resolve, reject)=>{ 26 | axios 27 | .post(payload.url, { data: payload.data} ) 28 | .then(result=>{ 29 | if(result.status>=200 && result.status<300){ 30 | resolve(result.data) 31 | }else{ 32 | reject() 33 | } 34 | }) 35 | .catch(()=>{ 36 | reject() 37 | }) 38 | 39 | }) 40 | } 41 | } 42 | 43 | export default service; -------------------------------------------------------------------------------- /Chapter08/client/src/webworker/services/test.js: -------------------------------------------------------------------------------- 1 | const service={ 2 | test(){ 3 | return new Promise((resolve, reject)=>{ 4 | setTimeout(()=>{ 5 | resolve("Worker alive and working!") 6 | }, 3000) 7 | }) 8 | } 9 | } 10 | 11 | export default service; -------------------------------------------------------------------------------- /Chapter08/client/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [vue()], 7 | }) 8 | -------------------------------------------------------------------------------- /Chapter08/server/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express") 2 | const cors=require("cors") 3 | const app=express() 4 | const PORT=3000 5 | 6 | // Allows connections from any source 7 | app.use(cors()) 8 | 9 | // Parse the request's body as json 10 | app.use(express.json()) 11 | 12 | /** 13 | Mirror REST operations. The server returns the same data sent. 14 | */ 15 | 16 | app.get("/api/test", (req, res)=>{ 17 | let data=req.query 18 | res.jsonp(data) 19 | }) 20 | app.post("/api/test", (req, res)=>{ 21 | let data=req.body 22 | res.jsonp(data) 23 | }) 24 | app.put("/api/test", (req, res)=>{ 25 | let data=req.body 26 | res.jsonp(data) 27 | }) 28 | app.delete("/api/test", (req, res)=>{ 29 | let data=req.query 30 | res.jsonp(data) 31 | }) 32 | 33 | 34 | // Launches the server in port 3000 35 | app.listen(PORT, ()=>{console.log("Server listening in port " + PORT)}) -------------------------------------------------------------------------------- /Chapter08/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "Simple NodeJS RESTful server", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node ." 8 | }, 9 | "author": "Pablo David Garaguso", 10 | "license": "ISC", 11 | "dependencies": { 12 | "cors": "^2.8.5", 13 | "express": "^4.18.2" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chapter09/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /Chapter09/README.md: -------------------------------------------------------------------------------- 1 | # Vue 3 + Vite 2 | 3 | This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 ` 12 | 13 | 14 | -------------------------------------------------------------------------------- /Chapter09/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter10", 3 | "private": true, 4 | "version": "0.1.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "start": "vite", 9 | "build": "vite build", 10 | "preview": "vite preview", 11 | "test": "vitest", 12 | "test:once": "vitest run", 13 | "test:coverage": "vitest run --coverage", 14 | "test:ui":"vitest --ui" 15 | }, 16 | "dependencies": { 17 | "vue": "^3.2.45" 18 | }, 19 | "devDependencies": { 20 | "@vitejs/plugin-vue": "^4.0.0", 21 | "@vitest/coverage-c8": "^0.28.5", 22 | "@vitest/ui": "^0.28.5", 23 | "@vue/test-utils": "^2.3.0", 24 | "jsdom": "^21.1.0", 25 | "vite": "^4.1.0", 26 | "vitest": "^0.28.5" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Chapter09/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter09/src/App.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 29 | 30 | 36 | -------------------------------------------------------------------------------- /Chapter09/src/assets/vue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter09/src/components/FibonacciInput.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 25 | 26 | -------------------------------------------------------------------------------- /Chapter09/src/components/FibonacciOutput.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 26 | 27 | -------------------------------------------------------------------------------- /Chapter09/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import './style.css' 3 | import App from './App.vue' 4 | 5 | createApp(App).mount('#app') 6 | -------------------------------------------------------------------------------- /Chapter09/src/services/Fibonacci.js: -------------------------------------------------------------------------------- 1 | /** 2 | A simple implementation of the Fibonacci calculator 3 | */ 4 | 5 | function Fibonacci(n) { 6 | if (n < 0) { 7 | throw "Undefined for negative numbers" 8 | } else { 9 | switch (n) { 10 | case 0: 11 | case 1: 12 | return n; 13 | default: 14 | let pre_1 = 0, pre_2 = 1, value; 15 | for (let i = 1; i < n; i++) { 16 | value = pre_1 + pre_2; 17 | pre_1 = pre_2; 18 | pre_2 = value; 19 | } 20 | return value; 21 | } 22 | } 23 | } 24 | 25 | function FibonacciPromise(n) { 26 | return new Promise((resolve, reject) => { 27 | if (n < 0) { 28 | reject() 29 | } else { 30 | switch (n) { 31 | case 0: 32 | case 1: 33 | resolve(n); 34 | break; 35 | default: 36 | let pre_1 = 0, pre_2 = 1, value; 37 | for (let i = 1; i < n; i++) { 38 | value = pre_1 + pre_2; 39 | pre_1 = pre_2; 40 | pre_2 = value; 41 | } 42 | resolve(value); 43 | } 44 | } 45 | }) 46 | } 47 | 48 | export default { Fibonacci, FibonacciPromise } 49 | export { Fibonacci , FibonacciPromise } -------------------------------------------------------------------------------- /Chapter09/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | font-synthesis: none; 7 | text-rendering: optimizeLegibility; 8 | -webkit-font-smoothing: antialiased; 9 | -moz-osx-font-smoothing: grayscale; 10 | -webkit-text-size-adjust: 100%; 11 | } 12 | 13 | a { 14 | font-weight: 500; 15 | color: #646cff; 16 | text-decoration: inherit; 17 | } 18 | a:hover { 19 | color: #535bf2; 20 | } 21 | 22 | a { 23 | font-weight: 500; 24 | color: #646cff; 25 | text-decoration: inherit; 26 | } 27 | a:hover { 28 | color: #535bf2; 29 | } 30 | 31 | body { 32 | margin: 0; 33 | min-width: 320px; 34 | min-height: 100vh; 35 | display: flex; 36 | justify-content: center; 37 | } 38 | 39 | h1 { 40 | font-size: 3.2em; 41 | line-height: 1.1; 42 | } 43 | 44 | button { 45 | border: 1px solid transparent; 46 | padding: 0.6em 1.2em; 47 | font-size: 1em; 48 | font-weight: 500; 49 | font-family: inherit; 50 | cursor: pointer; 51 | transition: border-color 0.25s; 52 | } 53 | button:hover { 54 | border-color: #646cff; 55 | } 56 | button:focus, 57 | button:focus-visible { 58 | outline: 4px auto -webkit-focus-ring-color; 59 | } 60 | 61 | .card { 62 | padding: 2em; 63 | } 64 | 65 | @media (prefers-color-scheme: light) { 66 | :root { 67 | color: #213547; 68 | background-color: #ffffff; 69 | } 70 | a:hover { 71 | color: #747bff; 72 | } 73 | button { 74 | background-color: #f9f9f9; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Chapter09/src/tests/Fibonacci.test.js: -------------------------------------------------------------------------------- 1 | import { describe, expect, test } from "vitest" 2 | import { Fibonacci, FibonacciPromise } from "../services/Fibonacci.js" 3 | 4 | 5 | describe("Test the results in fibonacci()", () => { 6 | 7 | test("Results according to the series definition", ()=>{ 8 | 9 | // Expected values as defined by the series 10 | expect(Fibonacci(0)).toBe(0) 11 | expect(Fibonacci(1)).toBe(1) 12 | expect(Fibonacci(2)).toBe(1) 13 | expect(Fibonacci(3)).toBe(2) 14 | 15 | // A value defined by the calculation of the series 16 | expect(Fibonacci(10)).toBe(55) 17 | 18 | }) 19 | }) 20 | 21 | describe("No negative numbers", () => { 22 | test("Out of range, must fail and throw an error", ()=>{ 23 | 24 | // The series is not defined for negative numbers, so it must throw an error. 25 | expect(()=>Fibonacci(-5)).toThrow() 26 | }) 27 | }) 28 | 29 | describe("Check async function", ()=>{ 30 | // For testing asynchronouse functions, the testing function should be async 31 | // and we "await" the entire "expect" resolution 32 | test("Resolve promise", async ()=>{ 33 | await expect(FibonacciPromise(10)).resolves.toBe(55) 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /Chapter09/src/tests/FibonacciInput.test.js: -------------------------------------------------------------------------------- 1 | import { describe, expect, test } from "vitest" 2 | import { mount } from "@vue/test-utils" 3 | 4 | // Import the component to test 5 | import FibonacciInput from "../components/FibonacciInput.vue" 6 | 7 | describe("Check Component action and event", ()=>{ 8 | test("Enter value and emit event on button click", ()=>{ 9 | let wrapper=mount(FibonacciInput) 10 | 11 | // Enter the value in the input component 12 | wrapper.find("input").setValue(10) 13 | 14 | // Find the button and activate it 15 | wrapper.find("button").trigger("click") 16 | 17 | // Capture the event parameters 18 | let inputEvents=wrapper.emitted("input") 19 | 20 | // Assert the event was emitted, and with the correct value 21 | // Each event provides an array with the arguments passed 22 | expect(inputEvents[0]).toEqual([10]) 23 | // or 24 | expect(inputEvents[0][0]).toBe(10) 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /Chapter09/src/tests/FibonacciOutput.test.js: -------------------------------------------------------------------------------- 1 | import { describe, expect, test } from "vitest" 2 | import { mount } from "@vue/test-utils" 3 | 4 | // Import the component to test 5 | import FibonacciOutput from "../components/FibonacciOutput.vue" 6 | 7 | describe("Check Component props and HTML", () => { 8 | test("Props input and HTML output", () => { 9 | // Mount the component to interact with it 10 | // We pass a prop and check the output html/text 11 | const wrapper = mount(FibonacciOutput, { props: { number: 10 } }) 12 | expect(wrapper.text()).toContain(55) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /Chapter09/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [vue()], 7 | test:{ 8 | environment:"jsdom", 9 | coverage: { 10 | reporter: ['text', 'json', 'html'], 11 | } 12 | } 13 | }) 14 | -------------------------------------------------------------------------------- /Chapter10/apache/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews 4 | 5 | 6 | 7 | 8 | 9 | RewriteEngine On 10 | RewriteBase / 11 | RewriteRule ^index\.html$ - [L] 12 | RewriteCond %{REQUEST_FILENAME} !-f 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteRule . /index.html [L] 15 | 16 | -------------------------------------------------------------------------------- /Chapter10/nginx/default.server: -------------------------------------------------------------------------------- 1 | server { 2 | 3 | // Server listening port 4 | listen 80; 5 | 6 | // index file, default 7 | index index.html; 8 | 9 | // Absolute path to our application folder's 10 | root /home/user/www; 11 | 12 | // Associated domains and subdomains with this server entry 13 | server_name www.mydomain.com mydomain.com; 14 | 15 | // Domain path to listen, here is root. 16 | location / { 17 | try_files $uri $uri/ /index.html; 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /Chapter11/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /Chapter11/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"] 3 | } 4 | -------------------------------------------------------------------------------- /Chapter11/README.md: -------------------------------------------------------------------------------- 1 | # Vue 3 + Vite 2 | 3 | This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 ` 12 | 13 | 14 | -------------------------------------------------------------------------------- /Chapter11/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter-9", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "vue": "^3.2.45" 13 | }, 14 | "devDependencies": { 15 | "@vitejs/plugin-vue": "^4.0.0", 16 | "vite": "^4.0.0" 17 | } 18 | } -------------------------------------------------------------------------------- /Chapter11/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chapter11/src/App.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 36 | 37 | 45 | -------------------------------------------------------------------------------- /Chapter11/src/components/InfiniteScroller.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 26 | 27 | -------------------------------------------------------------------------------- /Chapter11/src/components/Spinner.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 17 | 18 | -------------------------------------------------------------------------------- /Chapter11/src/components/Toggle.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 26 | 27 | -------------------------------------------------------------------------------- /Chapter11/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import './style.css' 3 | import App from './App.vue' 4 | 5 | createApp(App).mount('#app') 6 | -------------------------------------------------------------------------------- /Chapter11/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif; 3 | font-size: 16px; 4 | line-height: 24px; 5 | font-weight: 400; 6 | 7 | color-scheme: light dark; 8 | color: rgba(255, 255, 255, 0.87); 9 | background-color: #242424; 10 | 11 | font-synthesis: none; 12 | text-rendering: optimizeLegibility; 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | -webkit-text-size-adjust: 100%; 16 | } 17 | 18 | a { 19 | font-weight: 500; 20 | color: #646cff; 21 | text-decoration: inherit; 22 | } 23 | a:hover { 24 | color: #535bf2; 25 | } 26 | 27 | a { 28 | font-weight: 500; 29 | color: #646cff; 30 | text-decoration: inherit; 31 | } 32 | a:hover { 33 | color: #535bf2; 34 | } 35 | 36 | body { 37 | margin: 0; 38 | min-width: 320px; 39 | min-height: 100vh; 40 | } 41 | 42 | h1 { 43 | font-size: 3.2em; 44 | line-height: 1.1; 45 | } 46 | 47 | button { 48 | border-radius: 8px; 49 | border: 1px solid transparent; 50 | padding: 0.6em 1.2em; 51 | font-size: 1em; 52 | font-weight: 500; 53 | font-family: inherit; 54 | background-color: #1a1a1a; 55 | cursor: pointer; 56 | transition: border-color 0.25s; 57 | } 58 | button:hover { 59 | border-color: #646cff; 60 | } 61 | button:focus, 62 | button:focus-visible { 63 | outline: 4px auto -webkit-focus-ring-color; 64 | } 65 | 66 | .card { 67 | padding: 2em; 68 | } 69 | 70 | #app { 71 | max-width: 1280px; 72 | margin: 0 auto; 73 | padding: 2rem; 74 | } 75 | 76 | @media (prefers-color-scheme: light) { 77 | :root { 78 | color: #213547; 79 | background-color: #ffffff; 80 | } 81 | a:hover { 82 | color: #747bff; 83 | } 84 | button { 85 | background-color: #f9f9f9; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Chapter11/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [vue()], 7 | }) 8 | -------------------------------------------------------------------------------- /basic site/README.md: -------------------------------------------------------------------------------- 1 | # Vue 3 + Vite 2 | 3 | This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 ` 16 | 17 | 18 | -------------------------------------------------------------------------------- /basic site/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chapter-3", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "vue": "^3.2.37" 13 | }, 14 | "devDependencies": { 15 | "@vitejs/plugin-vue": "^3.0.3", 16 | "vite": "^3.0.7" 17 | } 18 | } -------------------------------------------------------------------------------- /basic site/public/css/regular.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :root, :host { 7 | --fa-font-regular: normal 400 1em/1 "Font Awesome 6 Free"; } 8 | 9 | @font-face { 10 | font-family: "Font Awesome 6 Free"; 11 | font-style: normal; 12 | font-weight: 400; 13 | font-display: block; 14 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); } 15 | 16 | .far, 17 | .fa-regular { 18 | font-family: "Font Awesome 6 Free"; 19 | font-weight: 400; } 20 | -------------------------------------------------------------------------------- /basic site/public/css/regular.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :host,:root{--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")}.fa-regular,.far{font-family:"Font Awesome 6 Free";font-weight:400} -------------------------------------------------------------------------------- /basic site/public/css/solid.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :root, :host { 7 | --fa-font-solid: normal 900 1em/1 "Font Awesome 6 Free"; } 8 | 9 | @font-face { 10 | font-family: "Font Awesome 6 Free"; 11 | font-style: normal; 12 | font-weight: 900; 13 | font-display: block; 14 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 15 | 16 | .fas, 17 | .fa-solid { 18 | font-family: "Font Awesome 6 Free"; 19 | font-weight: 900; } 20 | -------------------------------------------------------------------------------- /basic site/public/css/solid.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | :host,:root{--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}@font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}.fa-solid,.fas{font-family:"Font Awesome 6 Free";font-weight:900} -------------------------------------------------------------------------------- /basic site/public/css/v4-font-face.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face { 7 | font-family: "FontAwesome"; 8 | font-display: block; 9 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 10 | 11 | @font-face { 12 | font-family: "FontAwesome"; 13 | font-display: block; 14 | src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); } 15 | 16 | @font-face { 17 | font-family: "FontAwesome"; 18 | font-display: block; 19 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); 20 | unicode-range: U+F003,U+F006,U+F014,U+F016-F017,U+F01A-F01B,U+F01D,U+F022,U+F03E,U+F044,U+F046,U+F05C-F05D,U+F06E,U+F070,U+F087-F088,U+F08A,U+F094,U+F096-F097,U+F09D,U+F0A0,U+F0A2,U+F0A4-F0A7,U+F0C5,U+F0C7,U+F0E5-F0E6,U+F0EB,U+F0F6-F0F8,U+F10C,U+F114-F115,U+F118-F11A,U+F11C-F11D,U+F133,U+F147,U+F14E,U+F150-F152,U+F185-F186,U+F18E,U+F190-F192,U+F196,U+F1C1-F1C9,U+F1D9,U+F1DB,U+F1E3,U+F1EA,U+F1F7,U+F1F9,U+F20A,U+F247-F248,U+F24A,U+F24D,U+F255-F25B,U+F25D,U+F271-F274,U+F278,U+F27B,U+F28C,U+F28E,U+F29C,U+F2B5,U+F2B7,U+F2BA,U+F2BC,U+F2BE,U+F2C0-F2C1,U+F2C3,U+F2D0,U+F2D2,U+F2D4,U+F2DC; } 21 | 22 | @font-face { 23 | font-family: "FontAwesome"; 24 | font-display: block; 25 | src: url("../webfonts/fa-v4compatibility.woff2") format("woff2"), url("../webfonts/fa-v4compatibility.ttf") format("truetype"); 26 | unicode-range: U+F041,U+F047,U+F065-F066,U+F07D-F07E,U+F080,U+F08B,U+F08E,U+F090,U+F09A,U+F0AC,U+F0AE,U+F0B2,U+F0D0,U+F0D6,U+F0E4,U+F0EC,U+F10A-F10B,U+F123,U+F13E,U+F148-F149,U+F14C,U+F156,U+F15E,U+F160-F161,U+F163,U+F175-F178,U+F195,U+F1F8,U+F219,U+F27A; } 27 | -------------------------------------------------------------------------------- /basic site/public/css/v4-font-face.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2"),url(../webfonts/fa-v4compatibility.ttf) format("truetype");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a} -------------------------------------------------------------------------------- /basic site/public/css/v5-font-face.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face { 7 | font-family: "Font Awesome 5 Brands"; 8 | font-display: block; 9 | font-weight: 400; 10 | src: url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.ttf") format("truetype"); } 11 | 12 | @font-face { 13 | font-family: "Font Awesome 5 Free"; 14 | font-display: block; 15 | font-weight: 900; 16 | src: url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.ttf") format("truetype"); } 17 | 18 | @font-face { 19 | font-family: "Font Awesome 5 Free"; 20 | font-display: block; 21 | font-weight: 400; 22 | src: url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.ttf") format("truetype"); } 23 | -------------------------------------------------------------------------------- /basic site/public/css/v5-font-face.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 6.1.2 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | * Copyright 2022 Fonticons, Inc. 5 | */ 6 | @font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.ttf) format("truetype")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.ttf) format("truetype")} -------------------------------------------------------------------------------- /basic site/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /basic site/public/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/basic site/public/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /basic site/public/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/basic site/public/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /basic site/public/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/basic site/public/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /basic site/public/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/basic site/public/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /basic site/public/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/basic site/public/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /basic site/public/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/basic site/public/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /basic site/public/webfonts/fa-v4compatibility.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/basic site/public/webfonts/fa-v4compatibility.ttf -------------------------------------------------------------------------------- /basic site/public/webfonts/fa-v4compatibility.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Vue.js-3-Design-Patterns-and-Best-Practices/a28006ff8b533b1959a6b4c99305249caa245df2/basic site/public/webfonts/fa-v4compatibility.woff2 -------------------------------------------------------------------------------- /basic site/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 18 | 19 | 32 | -------------------------------------------------------------------------------- /basic site/src/assets/vue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /basic site/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 35 | 36 | 41 | -------------------------------------------------------------------------------- /basic site/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from "vue" 2 | import "./style.css" 3 | import App from "./App.vue" 4 | 5 | createApp(App).mount("#app") 6 | -------------------------------------------------------------------------------- /basic site/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif; 3 | font-size: 16px; 4 | line-height: 24px; 5 | font-weight: 400; 6 | 7 | color-scheme: light dark; 8 | color: rgba(255, 255, 255, 0.87); 9 | background-color: #242424; 10 | 11 | font-synthesis: none; 12 | text-rendering: optimizeLegibility; 13 | -webkit-font-smoothing: antialiased; 14 | -moz-osx-font-smoothing: grayscale; 15 | -webkit-text-size-adjust: 100%; 16 | } 17 | 18 | a { 19 | font-weight: 500; 20 | color: #646cff; 21 | text-decoration: inherit; 22 | } 23 | a:hover { 24 | color: #535bf2; 25 | } 26 | 27 | a { 28 | font-weight: 500; 29 | color: #646cff; 30 | text-decoration: inherit; 31 | } 32 | a:hover { 33 | color: #535bf2; 34 | } 35 | 36 | body { 37 | margin: 0; 38 | display: flex; 39 | place-items: center; 40 | min-width: 320px; 41 | min-height: 100vh; 42 | } 43 | 44 | h1 { 45 | font-size: 3.2em; 46 | line-height: 1.1; 47 | } 48 | 49 | button { 50 | border-radius: 8px; 51 | border: 1px solid transparent; 52 | padding: 0.6em 1.2em; 53 | font-size: 1em; 54 | font-weight: 500; 55 | font-family: inherit; 56 | background-color: #1a1a1a; 57 | cursor: pointer; 58 | transition: border-color 0.25s; 59 | } 60 | button:hover { 61 | border-color: #646cff; 62 | } 63 | button:focus, 64 | button:focus-visible { 65 | outline: 4px auto -webkit-focus-ring-color; 66 | } 67 | 68 | .card { 69 | padding: 2em; 70 | } 71 | 72 | #app { 73 | max-width: 1280px; 74 | margin: 0 auto; 75 | padding: 2rem; 76 | text-align: center; 77 | } 78 | 79 | @media (prefers-color-scheme: light) { 80 | :root { 81 | color: #213547; 82 | background-color: #ffffff; 83 | } 84 | a:hover { 85 | color: #747bff; 86 | } 87 | button { 88 | background-color: #f9f9f9; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /basic site/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite" 2 | import vue from "@vitejs/plugin-vue" 3 | import path from "path" 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [vue()], 8 | resolve:{ 9 | alias:{ 10 | "@components": path.resolve(__dirname, "src", "components") 11 | } 12 | } 13 | }) 14 | --------------------------------------------------------------------------------