docs are here. Vue is declarative. Vue extends html. JS, HTML, CSS in single file with script, template, and style tags respectively
Options API and Composition API (Options API is implemented on top of Composition API)
Vue Instance serves as the root of a Vue application and binds the Vue instance to an HTML element.
Vue Components are reusable and self-contained building blocks of a Vue application, which encapsulate HTML, CSS, and JavaScript.
Data Binding: Vue has two-way data binding, which allows you to bind data properties in the Vue instance to the HTML template, enabling automatic updates in both directions.
Directives: Vue directives like v-if, v-for, and v-bind (or shorthand :), which modify the behavior or appearance of HTML elements based on the Vue instance’s data.
Computed Properties: functions in a Vue component that calculate and cache values based on reactive data properties, and can be accessed like data properties in the template.
Lifecycle Hooks: created, mounted, updated, and destroyed. Allow you to perform actions at specific stages during a component’s lifecycle.
Vue Router: a routing library for Vue.js applications that enables navigation between different views or components based on defined routes.
Vuex: Vue’s official state management pattern and library, used for managing application-level state and providing a centralized store accessible by all components.
Single-File Components (SFC): a file format introduced by Vue that allows you to define a component’s template, script, and styles in a single .vue file, improving modularity and maintainability.
Vue CLI: a command-line tool used for scaffolding and managing Vue.js projects, which provides a development server, build tools, and project configuration.
Video here from the Net Ninja and pinia docs here. 60 minute video that can be watched on 2x speed.
Pinia is a state manager in Vue. It is an alternative to vuex and similar to redux in the react ecosystem. it holds state and has getters (for accessing the state via more complex logic) and actions (Like CRUD for the state values).
Download the VUE VS Code Snippets VSCode extension and also the VUE dev tools chrome extension. Pinia store will show inside Vue dev tools but man it is slow and require manual page refreshes.
Run the install script and then register as middleware with {createPinia} and the defineStore
method which takes two parameters, a name and a state:
export const useTaskStore = defineStore("whatEvsName", YourState)
{ state: () => ({
tasks: [{},{},{}],
otherStateEx: "Satoshi"
})
}
In the consuming file, import into the script area of the file.
export default {
setup() {
const taskStore = useTaskStore()
return {taskScore}
}
}
Then you can leverage in the template with:
{{taskStore.name}} // or taskStore.whatEvs
Or with a map
<div class="task-list">
<div v-for="task in taskStore.tasks">
<p>{{task.title}}</p>
</div>
</div>
Pass data down to child components with v-bind shorthand:
:task="task"
// then receive data in child comp with:
<script>
export default {
props: ['task']
}
</script>
Getters in Pinia – Why Bother?
Think of as pre-written queries, like “isFav” or “getTotalAmount” or “getCount”
getters: {
favs() {
return this.tasks.filter(t=>t.isFilter)
}
}
Actions in Pinia allow you to update values in the store. For example: delete a task, toggle a favorite task, add a new task, etc.
Note: conditional classes in Vue can be accomplished with:
class="material-icons" :class="{active: task.isFav}"
Syncing Pinia store with a database using Async Actions
This course showed how to use JSON web server and a local “data/db.json” file to act as a mock database. Used fetch to get initial data. Interesting but simple implementation. He essentially converts all the actions to async actions using fetch requests.
Resetting the store state with a special reset function is super cool.
.$reset
There is also a hook from pinia called “storeToRefs” that essentially destructures. Note: this doesn’t apply to actions.
Overall Vue seemed super simple. I liked the seamless scoped css in the component file without any configuration. Very unopinionated.
Not sure if the router is more or less complicated then page-based routing like Next.js
Didn’t see global state via vuex, did see the prop drilling though.
v-bind // is also :=""
v-for // used for lists ="task in task"
v-on // is also @=""
// @click is an event
@click="onDelete(task.id)"
Note: a colon key (:key) is needed on v-for similar to react
The beginning of the course uses a very simple project with the Vue CDN
@~25 minutes is the VUI CLI to start a more advanced task tracker project
export default {
name: "task",
props: {
tasks: Array
},
components: {Header}
}
Note: if you are trying to use emmet and it isn’t working go to VSCODE preferences and in the json file there is a includedLanguages key you need to update.
Install Vetur VSCode extension.
Global styles can go in App.vue
@~30mins Creating components and Props
<template></template>
<script>
export default {
name: "Header"
}
</script>
<style scoped></style>
Note: I really like the ease of scoped CSS
After creating your component you need to import it and register is wherever it is used.
A few ways to define props in a component. One way is as an array and another way is as an object with the name as the key and the type as the value.
// one way
props: ["title"]
// another way
props: {title: String}
// another way with default value
props: {
title: {
type: String,
default: "Hello World"
}
}
Access props in your template with double curly brackets
Binding props if for wanted to add a color to a child Button component.
Add a methods key set to an object in your component if applicable.
methods: {
onClick() {
console.log("click")
}
}
And bind with @click or similar
<button :click="onClick()"
@36m added hardcoded data to app.vue file
data() {
return {
tasks: []
}
}
created() {
//lifecycle method fire at certain times
// used for http requests
return {
this.tasks = //make you request
}
}
@38 minute creates a “Tasks.vue” component to take in a prop of tasks loop through an render another component for each one. Uses v-bind to pass in the tasks data to this component and inside has a div with a “v-for” to loop through.
Note: uniques keys are needed when you loop with v-bind the same as in react.
Any code for things like CDNs for font-awesome or google-analytics code can go in the public/index/html file
@~46minutes Good section here he talks about emitting data up and passing data down to avoid using a state manager like VUEX. He uses an @click calling an onDelete, and also defines that function in the “methods” area of the component.
Need to define an emits key when passing data between components.
Note: inside brackets you can have a ternary operator:
<div :class="[task.reminder ? "reminder" : ""]", "otherClassGoesHere"><div>
Actions emit data up
this.$emit("name", parameter)
this.$emit("delete-task", task.id)
And you catch emitted data with v-on or @ syntax:
/code @delet-task=”$emit(“delete-task, task.id)”
Can run into a potential warning in the console here “Extra non-emits event listeners passed” and to solve this you define an “emits” key
emits: ['delete-task']
Cacth methods emitted up by adding a methods key in the app.vue file:
<Addtask @add-task="add-task"/>
So 4 places really, 2 in app and 2 in button.
@~70minutes conditional v-bind
<Button :text="showAddTask ? "Close" : "Add Task"/>
“dist” is the folder to deploy after build.
@~74minutes JSON Web Server Refactor
converts methods such as addtask to async and uses fetch to make call. returns data uses data by setting await this.addTask.
converts all CRUD actions to this syntax.
@~90minutes is Router
Straightforward. Manually add a “router” folder or the cli can do for you and an index.js file inside that defines the routes with path, name, and component keys.
import {createRouter, createWebHistory}
const routes = [
{
path: "/about",
name: "About",
component: About
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
And to actually use the router in your application you need to add, to main.js or whatever your entry point is, you need import the router and add a middleware-like function:
createApp(App).use(router).mount('#app')
A “router-view” is essentially a page.
Note: you can pass props into the actual router-view which is interesting.
The “router-link” is what prevents a page from doing a full page refresh.
<router-link to="about">About</router-link>
Fireship video here and the Nuxt video here
Traversy Media Video from 2021 here
1-hour Crash course from Vue Mastery in 2022 here