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
toRefa 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
refwith primitive types likestringandnumberbut not withreactive - You access
refs byrefObj.valueandreactives byreactiveObj - Everything that belonged in the
datapart before the Composition API should be wrapped withreforreactive. (Unless they’re nonchanging in value.)
Computed / Watch
See details here.
watchwatches for a specific set of changes, and runs a function.- With
watchyou can also get the prev and new value. - You can watch
reflike a normal variable, but you gotta use() => reactiveObjinstead for reactive objects. watchEffectwatches for all change in every variable used in its function.watchEffectis kinda more likecomputedexcept it’s purpose is not to to get or set a variable.computedwith a single arrow function creates a getter (so immutable). If you give it instead an object withgetandset, it will be writable.- If you store
watchandwatchEffectin a variable namedmyVarfor example, you can stop its watch behavior by callingmyVar(). - There exists,
onTrackandonTriggerfor 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-modelis a syntactic sugar: you can always do the same thing with regular propping and emitting.- Basically, if you use the vanilla
v-modelas is, the name of the prop and the event will have to bemodelValueandupdate:modelValue. - If you give it a name like
v-model:childProp, it will bechildPropandupdate:childProp. - You can use multiple
v-models with a child component; just give it different names. - Remember,
v-modelneeds to be used withreforreactivevariable
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,$emitin the template tag, but not in the script tag. ref,reactive,toRef,toRefs,computed,watch,watchEffectare all invueattrsare 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 settingnameandinheritAttrs.
$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()