Skip to content

Instantly share code, notes, and snippets.

@jbollman7
Created January 21, 2023 17:46
Show Gist options
  • Save jbollman7/56f2dfa984558ab859fe2e1326e5dd88 to your computer and use it in GitHub Desktop.
Save jbollman7/56f2dfa984558ab859fe2e1326e5dd88 to your computer and use it in GitHub Desktop.
Vue-quick-notes

Vue

API Styles

  • Options API
  • Composition API

Declarative Rendering

SFC (Single-File Component) or Html mode. SFC is what most use when they use Vue with a build step

SFC is when HTML, css, and js are in a single file, .vue file

  • declarative rendering: using a template syntax that extends HTML - core feature of Vue.

  • State that can trigger updates when changed are considered reactive - reactive state is held in compoenents.

You can declare reactive state using the data component option.

export default {
  data() {
    return {
      message: 'Hello World!'
    }
  }
}

The message prop will be available in the template. <h1>{{ message }}</h1>

BTW, we can use any JS expression

<h1>{{ message.split('').reverse().join('') }}</h1>

Attribute Bindings

  • In Vue, mustaches are only used for text interpolation.
    • To bind an attribute to a dynamiv value use the v-bind directive
    • <div v-bind:id="dynamicId"></div>

A directive is a special attribute that starts with v- prefix.

  • Whatever is after the colon is the 'arg'. in this case 'id'

Because v-bind: is used the most, the shorthand is below <div :id="dynamicId"></div>

Event Listeners

  • Listen to DOM events using the v-on directive
<button v-on:click="increment">{{ count }}</button>
  • Because of the frequent use of listening to DOM events, below is the shorthand
<button @click="increment">{{ count }}</button>

@ is the event listener shorthand.

export default {
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment() {
      // update component state
      this.count++
    }
  }
}
  • Inside a method, we can access the component instance using this. The component instance exposes the data properties declared BY data. Update the state by mutating these properties.

Form Bindings

  • Using v-bind and v-on together, we can create two-way bindings on form input elements.
<input :value="text" @input="onInput">
methods: {
  onInput(e) {
    // a v-on handler receives the native DOM event
    // as the argument.
    this.text = e.target.value
  }
}

Two way binding easier syntax

<input v-model="text">

  • v-model auto syncs the value with the bound state
  • v-model works not only on text inputs but also on checkboxes, radio, select dropdowns

Conditional Rendering

  • Using the v-if directive to conditionally render an element
    • Also we can use v-else and v-else-if

List Rendering

  • use the v-for directive to render a list of elements based on a source array:
<ul>
  <li v-for="todo in todos" :key="todo.id">
    {{ todo.text }}
  </li>
</ul>
  • the key allows Vue to accurately move each li to match the position of its corresponding object in the array.

Computed Property

  • Computed property is a property that is reactively computed from other properties using the computed option.
  • A computed property tracks other reactive state used in its computation as dependencies,
    • it caches the result and automatically updates it when its depenendies change.

Lifecycle and Template Refs

  • There will be cases where we need to manually update the DOM.
  • a template ref, is a reference to an element in the template, we can reference it using the special ref attribute
<p ref="p">hello</p>

The element will be exposed on this.$refs as this.$refs.p. You can only access it ** after the component is mounted **

To run the code after mount, we use the mounted option

export default {
  mounted() {
    // component is now mounted.
  }
}

This is what a lifecycle hook.

  • Lifecycle hooks allow us to register a callback to be called AT certain times of the components lifecycle.
  • other hooks are created, and updated

Watchers

  • Watchers perform 'side effects' reatively, ie logging a number to the console wien it changes
export default {
  data() {
    return {
      count: 0
    }
  },
  watch: {
    count(newCount) {
      // yes, console.log() is a side effect
      console.log(`new count is: ${newCount}`)
    }
  }
}

Above, we are using the watch option to change the count property.

  • Watch callback is called WHEN count changes, AND receives the new value as the argument

A better example would be fetching new data when an ID changes.

<script>
export default {
  data() {
    return {
      todoId: 1,
      todoData: null
    }
  },
  methods: {
    async fetchData() {
      this.todoData = null
      const res = await fetch(
        `https://jsonplaceholder.typicode.com/todos/${this.todoId}`
      )
      this.todoData = await res.json()
    }
  },
  mounted() {
    this.fetchData()
  },
  watch: {
    todoId() {
      this.fetchData()
    }
  }
}
</script>

<template>
  <p>Todo id: {{ todoId }}</p>
  <button @click="todoId++">Fetch next todo</button>
  <p v-if="!todoData">Loading...</p>
  <pre v-else>{{ todoData }}</pre>
</template>
  1. My understanding the above. The button, increments todoId, with a simple ++.
  2. the watch is pointed only at that property, It notices a change, and then will fire fetchData.
  3. fetchData is called, and utilizes that updated property.

Components

In Real SPA apps, there are nested components

  • A parent component CAN render another component in its template AS a child component. * To use a child component, Import the component
import ChildComp from './ChildComp.vue'

expore default {
  components: {
    ChildComp
  }
}

You must also register the component using the components option.

Then we can use the component in the template as <ChildComp />

Props

  • A child component can accept input from the parent via props. * First it needs to DECLARE the props it accepts.
// in child component
export default {
  props: {
    msg: String
  }
}

Emits

A child component can also emit events to the parent.

export default {
  // declare emitted events
  emits: ['response'],
  created() {
    // emit with argument
    this.$emit('response', 'hello from child')
  }
}

The first arg to this.$emit() is the event name. Additional args are passed on to the event listener

** The parent can LISTEN to child-emitted events using v-on**

<ChildComp @response="(msg) => childMsg = msg" />

Here the handler receives the extra arg from the child emit call AND assigns it to local state

SLots

Parent component passing down template framents to the child via slots

<ChildComp>
  This is some slot content!
</ChildComp>

In the child component, it can render the slot conent from the parent using the <slot> element as outlet

<!-- in child template -->
<slot/>

Content inside the slot outlet will be treated as ** fallback ** content: it will be displayed if the parent did NOT pass down any slot conent <slot>Fallback content</slot>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment