Vuejs
Jump to navigation
Jump to search
Vuejs
Vuejs Training Materials
Copyright Notice
Copyright © 2004-2023 by NobleProg Limited All rights reserved.
This publication is protected by copyright, and permission must be obtained from the publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any form or by any means, electronic, mechanical, photocopying, recording, or likewise.
Introduction
- JavaScript framework for building UI (user interfaces)
- What do we need?
- HTML, CSS, and JavaScript
- Declarative, component-based programming model
- Declarative rendering
- Reactivity
- Progressive framework
- Single-file components (SFC)
- API Styles - options VS composition
Not That
BUT still - we'll have a lot to see! (-'
Framework
Progressive Framework - "framework that can grow with you and adapt to your needs"
- framework and ecosystem
- designed to be flexible and incrementally adoptable
- can be used in
- enhancing static HTML without a build step
- embedding as Web Components on any page
- Single-Page Application (SPA)
- Fullstack / Server-Side Rendering (SSR)
- Jamstack / Static Site Generation (SSG)
- targeting desktop, mobile, WebGL, and even the terminal
Overview of Vue JS
- Declarative rendering
- Component composition
Declarative rendering
- Declaring Reactive State
- data(), reserved prefixes ( $, _ )
- strong use of JavaScript Proxies
- Declaring Methods - methods()
- this is bind automatically (no arrows here!)
- accessible in template (mostly as event listeners)
- Deep Reactivity - by default
- detects even mutation of nested obj or array
- DOM Update Timing - not synchronous, buffered until the nextTick(), fixable with async..await
- in the update cycle - ensures each component updates only once (with all the state changes)
- Stateful Methods - dynamically created methods
- in reused components - to avoid interference use created() lifecycle hook
Component composition
- SFC - Single-File Components
- Options API vs Compositions API - two styles
SFC
- HTML-like file format (*.vue)
- logic (JS), template (HTML), and styles (CSS) - together
- for build-tool-enabled projects
- recommended way
- Example
<script>
export default {
data() {
return {
coursesInCart: 0
}
}
}
</script>
<template>
<button @click="coursesInCart + 1">You have: {{ coursesInCart }} courses in your bucket!</button>
</template>
<style scoped>
button {
font-size: 48px;
}
</style>
Options vs Composition
Compare of | Options API | Composition API |
---|---|---|
Component's logic | Object with options (data, methods, mounted, etc) | Imported API functions (ref, onMounted, etc) |
Properties | Exposed on this in functions | Declared with functions (ref) |
Syntax (some bits only) | the usual <script> | <script setup>, less boilerplate |
Common web use cases | covered | covered |
Centered on | component instance (this), beginner-friendly, organized | state directly in function, free-form, more flexible |
For production use | no build tools, low-complex cases | builds and full apps (+SFC) |
Options vs Composition Con't
- different interfaces - same underlying system
- Options are implemented on top of the Composition
- fundamental concepts and knowledge - shared across them
- more here - https://vuejs.org/guide/extras/composition-api-faq
Options vs Composition, Example
Options | Composition |
---|---|
<script>
export default {
// Properties returned from data() become reactive state and will be exposed on `this`.
data() {
return {
invoice: { id: 'INV_integer', type: 'default', owner: 'countryPrefix_franchisee' }
},
// Methods are functions that mutate state and trigger updates.
// They can be bound as event handlers in templates.
methods: {
setInv() {
this.invoice = { id: 'INV2378', type: 'consultancy', owner: 'NPUK_franchisee' }
}
},
// Lifecycle hooks are called at different stages of a component's existence.
// This function will be called when the component is mounted.
mounted() {
console.log(`The invoice for this ${this.invoice.type} is ${this.invoice.id}.`)
}
}
</script>
<template>
<button @click="setInv">Send invoice from: {{ invoice.owner }}</button>
</template>
|
<script setup>
import { ref, onMounted } from 'vue'
// reactive state
const invoice = ref( { id: '', type: '', owner: '' } )
// functions that mutate state and trigger updates
function setInv() {
invoice.value = { id: 'INV2378', type: 'consultancy', owner: 'NPUK_franchisee' }
}
// lifecycle hooks
onMounted(() => {
console.log(`The default invoice has an empty ID: ${invoice.value.id}.`)
})
</script>
<template>
<button @click="setInv">Send invoice from: {{ invoice.owner }}</button>
</template>
|
Setting up a development environment
- Nodejs, nvm
- IDEs - VSC + official Vue ext
- Useful plugin - es6-string-html
- Alternatives with some LSP/LSIF support: WebStorm, Sublime, vim, emacs
- git
- Vite vs VueCLI (migratable)
- ??
vue itself
npm create vue@latest # answer the interactive questions accordingly (proj-name, ts, routing, pinia, testing, etc) cd proj-name ; npm i ; npm run format ; npm run dev
OR
npx create-vue proj-name # answer the questions cd proj-name ; npm i ; npm run format ; npm run dev
Creating your first application
Build game "Find the jewel". The objective of the game is to find a random computer-chosen jewel in as few tries as possible. Approach: * First think about the functionality we want to offer * Second think about the data and behavior that can support the functionality * Third think about how to build a user interface for it Test it with 'live-server' (if not yet installed in the training machine, run 'sudo npm i -g live-server') * in command line go to application's root folder and execute the command 'live-server --cors'
- Designing the component
- Detailing the features that we want the app to support
- Choosing random jewel (origJewel)
- Providing input for a user to find the jewel (findJewel)
- Tracking the number of tries already made (howManyTries)
- Giving the user hints to improve their try based on their input (hinting)
- Giving a success message if the user found the proper jewel (hinting)
- Determining what we need to display to the user and what data we need to track
- Names in round brackets above are the properties that will support those features
- We need to include these properties in our component
- Detailing the features that we want the app to support
Exercise
Working with Templates
- Vue uses an HTML-based template syntax
- declaratively binds
- the rendered DOM to the underlying component instance's data
- declaratively binds
- syntactically valid HTML
- parseable by spec-compliant browsers and HTML parsers
- compiled into highly-optimized JS - when the app state changes
- intelligently re-renders the minimal no of components
- applies the minimal amount of DOM manipulations
- can be written directly as render functions instead
- JSX is optionally supported
- but not the same level of compile-time optimizations
Methods and computed properties
Method - manages actions, mutates state, etc
- New option - methods : { setInvoice(){} }
- Or just functions in composition's setup() { function setInvoice(){} }
- always called whenever a re-render happens
- must be returned together with properties
Computed property - solves complex logic that includes reactive data
- New option - computed: { getInvoicesPerFranchisee(){} }
- Or
- cached based on its reactive dependencies
- getter-only by default, changeable with giving it the setter
- should be side-effect free, don't:
- mutate other state
- make async requests
- mutate the DOM inside a computed getter
- also mutating its own computed value
Reactive programming
Directives and data rendering
Dividing the application into smaller, self-contained components
- Component Pattern instead of MVC
- Constructs
- expressions, data binding syntax
- Change detection
- Web components
Component pattern
In web applications
- No messes of spaghetti code in applications
- Reasoning about specific parts of the application in isolation from the other parts
- Maintenance costs are less
- Each component's internal logic can be managed separately
- No affecting the other parts of the application
- Self-describing components
- Makes the application easier to understand at a higher level of abstraction
Constructs
- Usually they live in the HTML template
- They are linking the view HTML and component code
- Similar to standard HTML with new symbols:
: property bindings (v-bind) @ event bindings (v-on) {{ }} expressions (interpolation)
Routing
Managing state (Pinia)
Refactoring components
Debugging and performance
Embedding Vue.js into existing pages
Deploying your application to production Vue-CLI
- Vite as a replacement for Vue-CLI
- npm run dev
- npm run build
- interactive CLI commands:
press r + enter to restart the server press u + enter to show server url press o + enter to open in browser press c + enter to clear console press q + enter to quit
Scaling your application
- Lighter-weight way (no-build-step usage)
- TS - vue-tsc instead of just tsc
- Testing - Vitest rather then Jest; Cypress is preferred
- More here
Helpers
- Official devtools
- Testing
- Awesome
Exercises
- Simple ftj - discussing app skeleton (index.html, main.js)
- Map the state in data() (main.js)
- add all the properties from designing part
- use this property below as our main model for now
jewels: ['ruby','diamond','agate','amber','aquamarine','amethyst','opal','tourmaline','emerald','onyx','pearl','sapphire']
- Update our main html template with howmManyTries
- Exercise: improve it with dynamic data (index.html)
- observe it in the browser - use Vue dev-tools
- Map the state in data() (main.js)
- Design our game engine - initGame() method
- directives
- events
- ?