Vue 3 bits
Published: 2024-03-25 08:52:24

##1. Computed property in vue 3

In the Vue 3 Composition API, the computed function is used to define a reactive computed property. This means the property's value is automatically recalculated when its reactive dependencies change. The computed function takes a getter function as an argument, and the return value of this getter function is the computed property's value.

Let me explain really simple,

You have this code

```
const author = reactive({
  name: 'John Doe',
  books: [
    'Vue 2 - Advanced Guide',
    'Vue 3 - Basic Guide',
    'Vue 4 - The Mystery'
  ]
})
```

And this code

```
<span>{{ author.books.length > 0 ? 'Yes' : 'No' }}</span>
```

If we need to do use `{{ author.books.length > 0 ? 'Yes' : 'No' }}` inside multiple places, the calculation will happen everywhere. But we can use computed and use like this instead,

```
const publishedBooksMessage = computed(() => {
  return author.books.length > 0 ? 'Yes' : 'No'
})

<span>{{ publishedBooksMessage }}</span>

```
The computation inside computed(() => ...) is **cached and only re-evaluated when its dependencies change**. In this case, it's **only recalculated when author.books changes**. If author.books doesn't change, Vue uses the cached result instead of recalculating it, which is more efficient than evaluating the condition on every render.

If we use like this

```
let publishedBooksMessage =  author.books.length > 0 ? 'Yes' : 'No'
```

This will not change when `author.books` changes and hence not reactive. 

##2. Emits
In Vue.js, the emit function is used for child components to send custom events to their parent components. This mechanism allows child components to communicate with their parents, enabling a child to notify the parent of changes or user actions without directly manipulating the parent's state.

Very simply Emit is used to get the changes (events) from child components to parent components. Let us see an example.

**Child Component (ChildComponent.vue)**

```
<template>
  <button @click="emitEvent">Click Me</button>
</template>

<script setup>
import { defineEmits } from 'vue';

// Define which events this component can emit
const emit = defineEmits(['custom-event']);

// Method to emit the event
const emitEvent = () => {
  emit('custom-event', 'Hello from ChildComponent');
};
</script>
```

Here we pass click event with 'Hello from ChildComponent' parameter.

**Parent Component (ParentComponent.vue)**

```
<template>
  <div>
    <ChildComponent @custom-event="handleCustomEvent" />
  </div>
</template>

<script setup>
import { defineComponent } from 'vue';
import ChildComponent from './ChildComponent.vue';

defineComponent({
  components: {
    ChildComponent
  }
});

// Method to handle the custom event
const handleCustomEvent = (message) => {
  console.log('Event received from ChildComponent:', message);
  // Output will be: Event received from ChildComponent: Hello from ChildComponent
};
</script>
```

Here we have console logging the message every time the button gets clicked inside child.

v-model is a wonderful technic which used to two way bind data. We can use v-model also with emit. This is how we does that.

**Child Component (CustomInput.vue)**

```
<template>
  <input 
    :value="modelValue" 
    @input="$emit('update:modelValue', $event.target.value)"
  >
</template>

<script setup>
import { defineProps } from 'vue';

const props = defineProps({
  modelValue: String
});
</script>
```

Here it is the emit event is **'update:modelValue'**. But unlike previous example you don't need to call it. It will automatically get called and v-model bound value (inputValue in parent) will be auto updated.

**Parent Component**

```
<template>
  <div>
    <CustomInput v-model="inputValue" />
    <p>Input value: {{ inputValue }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import CustomInput from './CustomInput.vue';

const inputValue = ref('');
</script>
```