belajarkoding © 2025 BelajarKoding. All rights reserved.
Belajar Produk UpgradeCari... KToggle theme Loading... Belajar Produk UpgradeCari... KToggle theme Loading... Belajar Produk UpgradeCari... KToggle theme Loading...
Vue 3 Cheat Sheet Referensi lengkap Vue 3 dengan Composition API. Reactive state, lifecycle, components, dan fitur modern Vue. Perfect buat frontend development.
JavaScript 11 min read 2.023 kata
Silakan
login atau
daftar untuk membaca cheat sheet ini.
Baca Cheat Sheet Lengkap Login atau daftar akun gratis untuk membaca cheat sheet ini.
Vue 3 Cheat Sheet - BelajarKoding | BelajarKoding
# Getting Started
Panduan awal untuk memulai pengembangan aplikasi dengan Vue.js framework.
# Installation
Cara menginstall Vue.js menggunakan berbagai method seperti npm atau CDN.
# Pake npm
npm create vue@latest
# Pake pnpm
pnpm create vue@latest
# Via CDN
< script src = "https://unpkg.com/vue@3" >< /script
>
Cara membuat aplikasi Vue.js dasar dengan setup minimal.
import { createApp } from 'vue'
import App from './App.vue'
createApp (App). mount ( '#app' ) Sintaks template Vue.js untuk menampilkan data dan mengatur interaksi.
Cara menampilkan data JavaScript dalam template menggunakan double curly braces.
< template >
< p >{{ message }}</ p >
< p >{{ count + 1 }}</ p >
< p >{{ ok ? 'YES' : 'NO' }}</ p >
< p >{{ message. split
Directive Vue.js untuk mengatur behavior element HTML dengan berbagai fungsi.
< template >
<!-- v-bind - Attribute binding -->
< img v-bind : src = " imageUrl " />
<
API baru Vue 3 untuk mengorganisir logic komponen dengan cara yang lebih fleksibel.
Fungsi setup yang menjadi entry point untuk Composition API dalam komponen.
< script >
import { ref, reactive } from 'vue'
export default {
setup () {
const count = ref ( 0 )
const user = reactive ({
name: 'Budi'
# script setup (Recommended)Sintaks script setup yang lebih sederhana untuk menggunakan Composition API.
< script setup >
import { ref, reactive } from 'vue'
// Gak perlu return, auto-exposed ke template
const count = ref ( 0 )
const user = reactive ({
name: 'Budi' ,
age:
Sistem reaktivitas Vue.js yang secara otomatis mengupdate UI ketika data berubah.
Cara membuat reactive reference untuk primitive values.
< script setup >
import { ref } from 'vue'
// Reactive reference
const count = ref ( 0 )
const message = ref ( 'Hello' )
// Access value dengan .value
console.
< script setup >
import { reactive } from 'vue'
// Reactive object
const state = reactive ({
count: 0 ,
message: 'Hello'
})
// Akses langsung, gak pake .value
state.count
< script setup >
import { ref, computed } from 'vue'
const firstName = ref ( 'Budi' )
const lastName = ref ( 'Santoso' )
// Computed property
< script setup >
import { ref, watch, watchEffect } from 'vue'
const count = ref ( 0 )
const user = reactive
# Composition API Lifecycle< script setup >
import {
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted
} from 'vue'
// Before component is mounted
onBeforeMount
<!-- MyComponent.vue -->
< script setup >
import { ref } from 'vue'
const count = ref ( 0 )
</ script >
< template >
< button @ click
< script setup >
// Define props
const props = defineProps ({
title: String,
count: {
type: Number,
default: 0 ,
required: true
},
user: Object,
tags: Array
< script setup >
// Define emits
const emit = defineEmits ([ 'update' , 'delete' ])
// Dengan validation
const emit = defineEmits ({
update : (
<!-- Parent -->
< template >
< CustomInput v-model = " text " />
</ template >
<!-- CustomInput.vue -->
< script setup >
const props = defineProps
<!-- Parent -->
< template >
< Card >
< template # header >
< h1 >Title</ h1 >
</ template >
< template #
<!-- Parent -->
< template >
< UserList >
< template # default = " { user } " >
< p >{{ user.name }} - {{ user.email }}</ p >
</ template >
// useCounter.js
import { ref, computed } from 'vue'
export function useCounter ( initialValue = 0 ) {
const count = ref (initialValue)
const doubled = computed (() =>
< script setup >
import { useCounter } from './composables/useCounter'
const { count , doubled , increment , decrement , reset } = useCounter ( 10 )
</
// useFetch.js
import { ref } from 'vue'
export function useFetch ( url ) {
const data = ref ( null )
const error
# Pinia (State Management)// main.js
import { createPinia } from 'pinia'
const pinia = createPinia ()
app. use (pinia) // stores/counter.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useCounterStore = defineStore ( 'counter' , () => {
// State
< script setup >
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore ()
// Access state
console. log (counter.count)
// Access getters
console. log (counter.doubled)
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '@/views/Home.vue'
import About from '@/views/About.vue'
const routes = [
{
path: '/' ,
< script setup >
import { useRouter, useRoute } from 'vue-router'
const router = useRouter ()
const route = useRoute ()
// Navigate
function goToAbout
< template >
<!-- v-text -->
< span v-text = " message " ></ span >
<!-- v-html (hati-hati XSS!) -->
< div v-html = " htmlContent " ></ div >
< script setup >
// Directive definition
const vFocus = {
mounted ( el ) {
el. focus ()
}
}
const vColor = {
mounted ( el
< template >
<!-- Teleport ke body -->
< Teleport to = "body" >
< div class = "modal" >
< p >Modal content</ p >
</ div >
</ Teleport >
< template >
< Suspense >
<!-- Component yang async -->
< template # default >
< AsyncComponent />
</ template >
<!-- Loading state -->
< template # fallback >
< script setup >
import { ref, computed } from 'vue'
const count = ref ( 0 )
// Computed - cached, cuma re-evaluate kalo dependencies berubah
const doubled = computed (() => count.value
< script setup >
// 1. Imports
import { ref, computed, onMounted } from 'vue'
import MyComponent from './MyComponent.vue'
// 2. Props & Emits
const props = defineProps ([ 'title' ])
const
< script setup >
import { shallowRef, shallowReactive } from 'vue'
// Shallow reactivity - cuma top-level yang reactive
const state = shallowReactive ({
foo: 1 ,
nested: {
bar: 2
}
})
# defineOptions (Vue 3.3+)< script setup >
// Set component options
defineOptions ({
name: 'MyComponent' ,
inheritAttrs: false
})
</ script > (
''
).
reverse
().
join
(
''
) }}</
p
>
</ template >
img
:
src
=
"
imageUrl
"
/>
<!-- Shorthand -->
< div : class = " { active: isActive } " ></ div >
< div : style = " { color: textColor } " ></ div >
<!-- v-on - Event handling -->
< button v-on : click = " handleClick " >Click</ button >
< button @ click = " handleClick " >Click</ button > <!-- Shorthand -->
< input @ input = " handleInput " />
<!-- v-model - Two-way binding -->
< input v-model = " message " />
< textarea v-model = " text " ></ textarea >
< input type = "checkbox" v-model = " checked " />
< select v-model = " selected " >
< option >A</ option >
< option >B</ option >
</ select >
<!-- v-if, v-else-if, v-else -->
< div v-if = " type === 'A'" >A</ div >
< div v-else-if = " type === 'B'" >B</ div >
< div v-else >Not A or B</ div >
<!-- v-show (CSS display) -->
< div v-show = " isVisible " >Show me</ div >
<!-- v-for - List rendering -->
< li v-for = " item in items " : key = " item.id " >
{{ item.name }}
</ li >
< div v-for = " (item, index) in items " : key = " index " >
{{ index }}: {{ item }}
</ div >
< div v-for = " (value, key) in object " : key = " key " >
{{ key }}: {{ value }}
</ div >
</ template >
,
age: 25
})
function increment () {
count.value ++
}
return {
count,
user,
increment
}
}
}
</ script >
25
})
function increment () {
count.value ++
}
</ script >
< template >
< button @ click = " increment " >{{ count }}</ button >
< p >{{ user.name }}</ p >
</ template >
log
(count.value)
// 0
count.value ++
// Di template gak perlu .value
</ script >
< template >
< p >{{ count }}</ p >
</ template >
++
state.message = 'Hi'
// Nested objects juga reactive
const user = reactive ({
profile: {
name: 'Budi' ,
email: 'budi@example.com'
}
})
user.profile.name = 'Ani' // Reactive
</ script >
const fullName = computed (() => {
return firstName.value + ' ' + lastName.value
})
// Writable computed
const fullNameWritable = computed ({
get () {
return firstName.value + ' ' + lastName.value
},
set ( value ) {
[firstName.value, lastName.value] = value. split ( ' ' )
}
})
</ script >
< template >
< p >{{ fullName }}</ p >
</ template >
({ name:
'Budi'
})
// Watch specific source
watch (count, ( newValue , oldValue ) => {
console. log ( `Count changed from ${ oldValue } to ${ newValue }` )
})
// Watch multiple sources
watch ([count, () => user.name], ([ newCount , newName ]) => {
console. log ( `Count: ${ newCount }, Name: ${ newName }` )
})
// Deep watch untuk object
watch (
() => user,
( newUser ) => {
console. log ( 'User changed:' , newUser)
},
{ deep: true }
)
// watchEffect - auto track dependencies
watchEffect (() => {
console. log ( `Count is ${ count . value }` )
})
// watchEffect dengan cleanup
watchEffect (( onCleanup ) => {
const timer = setTimeout (() => {
console. log (count.value)
}, 1000 )
onCleanup (() => {
clearTimeout (timer)
})
})
</ script >
(()
=>
{
console. log ( 'Before Mount' )
})
// After component is mounted
onMounted (() => {
console. log ( 'Mounted' )
// Good place buat API calls, DOM manipulation
})
// Before component updates
onBeforeUpdate (() => {
console. log ( 'Before Update' )
})
// After component updates
onUpdated (() => {
console. log ( 'Updated' )
})
// Before component unmounts
onBeforeUnmount (() => {
console. log ( 'Before Unmount' )
// Cleanup subscriptions, timers, etc
})
// After component unmounts
onUnmounted (() => {
console. log ( 'Unmounted' )
})
</ script >
=
"
count
++
"
>{{ count }}</
button
>
</ template >
< style scoped >
button {
background : blue ;
color : white ;
}
</ style >
})
// Dengan TypeScript
const props = defineProps <{
title : string
count ?: number
user : { name : string ; age : number }
}>()
// Access props
console. log (props.title)
console. log (props.count)
</ script >
< template >
< h1 >{{ title }}</ h1 >
< p >{{ count }}</ p >
</ template >
value
)
=>
{
return typeof value === 'string'
},
delete: null
})
// Dengan TypeScript
const emit = defineEmits <{
update : [ value : string ]
delete : [ id : number ]
}>()
// Emit event
function handleUpdate () {
emit ( 'update' , 'new value' )
}
function handleDelete () {
emit ( 'delete' , 123 )
}
</ script >
< template >
< button @ click = " handleUpdate " >Update</ button >
< button @ click = " handleDelete " >Delete</ button >
</ template >
([
'modelValue'
])
const emit = defineEmits ([ 'update:modelValue' ])
function handleInput ( e ) {
emit ( 'update:modelValue' , e.target.value)
}
</ script >
< template >
< input
: value = " modelValue "
@ input = " handleInput "
/>
</ template >
default
>
< p >Content here</ p >
</ template >
< template # footer >
< button >OK</ button >
</ template >
</ Card >
</ template >
<!-- Card.vue -->
< template >
< div class = "card" >
< div class = "card-header" >
< slot name = "header" ></ slot >
</ div >
< div class = "card-body" >
< slot ></ slot > <!-- Default slot -->
</ div >
< div class = "card-footer" >
< slot name = "footer" ></ slot >
</ div >
</ div >
</ template >
</ UserList >
</ template >
<!-- UserList.vue -->
< script setup >
const users = ref ([
{ id: 1 , name: 'Budi' , email: 'budi@example.com' },
{ id: 2 , name: 'Ani' , email: 'ani@example.com' }
])
</ script >
< template >
< div v-for = " user in users " : key = " user.id " >
< slot : user = " user " ></ slot >
</ div >
</ template >
count.value
*
2
)
function increment () {
count.value ++
}
function decrement () {
count.value --
}
function reset () {
count.value = initialValue
}
return {
count,
doubled,
increment,
decrement,
reset
}
}
script
>
< template >
< p >Count: {{ count }}</ p >
< p >Doubled: {{ doubled }}</ p >
< button @ click = " increment " >+</ button >
< button @ click = " decrement " >-</ button >
< button @ click = " reset " >Reset</ button >
</ template >
=
ref
(
null
)
const loading = ref ( false )
async function fetchData () {
loading.value = true
try {
const response = await fetch (url)
data.value = await response. json ()
} catch (e) {
error.value = e
} finally {
loading.value = false
}
}
return { data, error, loading, fetchData }
}
// useLocalStorage.js
import { ref, watch } from 'vue'
export function useLocalStorage ( key , defaultValue ) {
const value = ref (
JSON . parse (localStorage. getItem (key)) ?? defaultValue
)
watch (value, ( newValue ) => {
localStorage. setItem (key, JSON . stringify (newValue))
}, { deep: true })
return value
}
const count = ref ( 0 )
// Getters
const doubled = computed (() => count.value * 2 )
// Actions
function increment () {
count.value ++
}
function decrement () {
count.value --
}
return {
count,
doubled,
increment,
decrement
}
})
// Options API style
export const useCounterStore = defineStore ( 'counter' , {
state : () => ({
count: 0
}),
getters: {
doubled : ( state ) => state.count * 2
},
actions: {
increment () {
this .count ++
}
}
})
// Call actions
counter. increment ()
// Destructure dengan storeToRefs
import { storeToRefs } from 'pinia'
const { count , doubled } = storeToRefs (counter)
const { increment , decrement } = counter
</ script >
name: 'home' ,
component: Home
},
{
path: '/about' ,
name: 'about' ,
component: About
},
{
path: '/user/:id' ,
name: 'user' ,
component : () => import ( '@/views/User.vue' ) // Lazy loading
}
]
const router = createRouter ({
history: createWebHistory (),
routes
})
export default router
() {
router. push ( '/about' )
router. push ({ name: 'about' })
router. push ({ path: '/user/123' })
}
// Access params
console. log (route.params.id)
// Access query
console. log (route.query.search)
</ script >
< template >
<!-- router-link -->
< router-link to = "/" >Home</ router-link >
< router-link : to = " { name: 'about' } " >About</ router-link >
<!-- router-view -->
< router-view />
</ template >
<!-- v-cloak -->
< div v-cloak >{{ message }}</ div >
<!-- v-once - render sekali -->
< span v-once >{{ message }}</ span >
<!-- v-memo - memoize subtree -->
< div v-memo = " [count] " >
{{ count }}
</ div >
</ template >
,
binding
) {
el.style.color = binding.value
},
updated ( el , binding ) {
el.style.color = binding.value
}
}
</ script >
< template >
< input v-focus />
< p v-color = "'red'" >Red text</ p >
</ template >
<!-- Teleport ke selector -->
< Teleport to = "#modal-container" >
< div >Content</ div >
</ Teleport >
</ template >
< div >Loading...</ div >
</ template >
</ Suspense >
</ template >
< script setup >
// AsyncComponent.vue
const data = await fetch ( '/api/data' ). then ( r => r. json ())
</ script >
*
2
)
// Method - always execute
function getDoubled () {
return count.value * 2
}
</ script >
< template >
<!-- Computed - efficient -->
< p >{{ doubled }}</ p >
<!-- Method - execute setiap render -->
< p >{{ getDoubled () }}</ p >
</ template >
emit
=
defineEmits
([
'update'
])
// 3. State
const count = ref ( 0 )
// 4. Computed
const doubled = computed (() => count.value * 2 )
// 5. Functions
function increment () {
count.value ++
}
// 6. Lifecycle
onMounted (() => {
console. log ( 'Mounted' )
})
</ script >
// Bisa update nested tapi gak trigger reactivity
state.nested.bar = 3 // Won't trigger update
// Update top-level bakal trigger
state.foo = 2 // Will trigger
</ script >