Vue Quick Notes

Quick notes for dummies. Using <script setup lang="ts">.

Table of contents
  1. Props
    1. To use props in child component
      1. Without default values
      2. With default values
  2. Ref / Reactive
  3. Computed / Watch
  4. Event / Emits
    1. To use emits
  5. v-model
    1. Parent-Child usage example
  6. Provide / Inject
  7. Etc
    1. $keyword equivalent in the script tag

Props

  1. Props are reactive by default
  2. You don’t explicitly import defineProps; it is a compiler macro for <script setup>
  3. If you don’t pass optional props, they have a value of undefined
  4. In the template, you can access the props without having to do props.someVarName, just use someVarName.
  5. Even if you toRef a prop, they will not become a copy. If you modify the toRef-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

  1. You can use ref with primitive types like string and number but not with reactive
  2. You access refs by refObj.value and reactives by reactiveObj
  3. Everything that belonged in the data part before the Composition API should be wrapped with ref or reactive. (Unless they’re nonchanging in value.)

Computed / Watch

See details here.

  1. watch watches for a specific set of changes, and runs a function.
  2. With watch you can also get the prev and new value.
  3. You can watch ref like a normal variable, but you gotta use () => reactiveObj instead for reactive objects.
  4. watchEffect watches for all change in every variable used in its function.
  5. watchEffect is kinda more like computed except it’s purpose is not to to get or set a variable.
  6. computed with a single arrow function creates a getter (so immutable). If you give it instead an object with get and set, it will be writable.
  7. If you store watch and watchEffect in a variable named myVar for example, you can stop its watch behavior by calling myVar().
  8. There exists, onTrack and onTrigger 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

  1. Syntax changed since Vue2, see here for details.
  2. v-model is a syntactic sugar: you can always do the same thing with regular propping and emitting.
  3. Basically, if you use the vanilla v-model as is, the name of the prop and the event will have to be modelValue and update:modelValue.
  4. If you give it a name like v-model:childProp, it will be childProp and update:childProp.
  5. You can use multiple v-models with a child component; just give it different names.
  6. Remember, v-model needs to be used with ref or reactive 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

  1. To make typing work, you gotta use the InjectionKey<T>. See here for details.
  2. 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

  1. You can use $event, $router, $route, $slots, $attrs, $emit in the template tag, but not in the script tag.
  2. ref, reactive, toRef, toRefs, computed, watch, watchEffect are all in vue
  3. 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
  4. 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 setting name and inheritAttrs.

$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()