Vue Quick Notes
Quick notes for dummies. Using <script setup lang="ts">
.
Table of contents
Props
- Props are reactive by default
- You don’t explicitly import defineProps; it is a compiler macro for
<script setup>
- If you don’t pass optional props, they have a value of
undefined
- In the template, you can access the props without having to do
props.someVarName
, just usesomeVarName
. - Even if you
toRef
a prop, they will not become a copy. If you modify thetoRef
-ed prop, it will affect the original.
To use props in child component
Without default values
const props = defineProps<{
a: string
b: number
}>()
With default values
interface MyProps {
a: strings
b?: number
}
const props = withDefaults(defineProps<MyProps>(), {
b: 0
})
Ref / Reactive
- You can use
ref
with primitive types likestring
andnumber
but not withreactive
- You access
ref
s byrefObj.value
andreactive
s byreactiveObj
- Everything that belonged in the
data
part before the Composition API should be wrapped withref
orreactive
. (Unless they’re nonchanging in value.)
Computed / Watch
See details here.
watch
watches for a specific set of changes, and runs a function.- With
watch
you can also get the prev and new value. - You can watch
ref
like a normal variable, but you gotta use() => reactiveObj
instead for reactive objects. watchEffect
watches for all change in every variable used in its function.watchEffect
is kinda more likecomputed
except it’s purpose is not to to get or set a variable.computed
with a single arrow function creates a getter (so immutable). If you give it instead an object withget
andset
, it will be writable.- If you store
watch
andwatchEffect
in a variable namedmyVar
for example, you can stop its watch behavior by callingmyVar()
. - There exists,
onTrack
andonTrigger
for debugging.
Event / Emits
To use emits
const emits = defineEmits<{
(e: 'myEvent', valueImGivingBack: string): void
}>(
// Then later
function onEvent(e: Event) {
const newVal = (e.target as HTMLTextAreaElement).value
emits('myEvent', newVal)
}
v-model
- Syntax changed since Vue2, see here for details.
v-model
is a syntactic sugar: you can always do the same thing with regular propping and emitting.- Basically, if you use the vanilla
v-model
as is, the name of the prop and the event will have to bemodelValue
andupdate:modelValue
. - If you give it a name like
v-model:childProp
, it will bechildProp
andupdate:childProp
. - You can use multiple
v-model
s with a child component; just give it different names. - Remember,
v-model
needs to be used withref
orreactive
variable
Parent-Child usage example
// Parent.vue
<template>
<Child v-model:childProp="parentVar">
</template>
<script setup lang="ts">
const parentVar = ref('hey child')
</script>
// Child.vue
<template>
<input @keyup.enter="onEnterPressed">
</template>
<script setup lang="ts">
const defineProps<{
childProp: string
}>()
const emits = defineEmits<{
(e: 'update:childProp', childProp: string): void
}>()
function onEnterPressed(e: Event) {
const someVal = 'sup'
emits('update:childProp', someVal)
}
</script>
Provide / Inject
- To make typing work, you gotta use the
InjectionKey<T>
. See here for details. - To update provided reactive props, make the parent component provide mutation functions as well. Always recommended to have the root (providing) component to be in charge of mutations.
Etc
- You can use
$event
,$router
,$route
,$slots
,$attrs
,$emit
in the template tag, but not in the script tag. ref
,reactive
,toRef
,toRefs
,computed
,watch
,watchEffect
are all invue
attrs
are basically all the stuff passed down to a child naturally from being an HTML element, but not actually a Vue prop. Ex)class
- You can use the normal
<script>
tag along with the<script setup>
. Two things you’ll have to do within the normal<script>
tag is settingname
andinheritAttrs
.
$keyword
equivalent in the script tag
See here for details. But basically:
import { useSlots, useAttrs } from 'vue
import { useRouter, useRoute } from 'vue-router'
const slots = useSlots()
const attrs = useAttrs()
const router = useRouter()
const route = useRoute()