1. Organize Your Code into Logical Sections

Structure your component script into clear sections to improve readability. A common approach is to group related logic together.
Example Structure:

<script setup>
// 1. Imports
import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'

// 2. Reactive State
const count = ref(0)
const name = ref('')

// 3. Computed Properties
const doubledCount = computed(() => count.value * 2)

// 4. Functions / Methods
function increment() {
  count.value++
}

// 5. Lifecycle Hooks
onMounted(() => {
  console.log('Component mounted')
})

// 6. Watchers
watch(count, (newValue, oldValue) => {
  console.log(`Count changed from ${oldValue} to ${newValue}`)
})
</script>

---

2. Use script setup Syntax

The <script setup> syntax is the recommended way to write Composition API components. It provides a more concise and intuitive syntax.
Example:

<script setup>
const message = ref('Hello, Vue 3!')
</script>

<template>
  <p>{{ message }}</p>
</template>

---

3. Use Descriptive Variable and Function Names

Choose meaningful names for variables, functions, and computed properties to make your code self-documenting.
Example:
// Bad
const x = ref(0)

// Good
const userCount = ref(0)

---

4. Extract Reusable Logic into Composables
   Move reusable logic into composables (custom hooks) to keep your components clean and promote code reuse.
   Example Composable:

// composables/useCounter.js
import { ref } from 'vue'

export function useCounter(initialValue = 0) {
const count = ref(initialValue)

function increment() {
count.value++
}

function reset() {
count.value = initialValue
}

return {
count,
increment,
reset,
}
}

Usage in a Component:

<script setup>
import { useCounter } from '~/composables/useCounter'

const { count, increment } = useCounter()
</script>

<template>
  <p>Count: {{ count }}</p>
  <button @click="increment">Increment</button>
</template>

---

5. Use ref for Primitive Values and reactive for Objects

   - Use ref for primitive values (e.g., numbers, strings, booleans).
   - Use reactive for objects or arrays.

Example:
const count = ref(0) // Primitive value
const user = reactive({ name: 'John', age: 30 }) // Object

---

6. Use Computed Properties for Derived State

Use computed to create reactive properties that depend on other state. This ensures the derived state is always up-to-date.
Example:
const firstName = ref('John')
const lastName = ref('Doe')

const fullName = computed(() => `${firstName.value} ${lastName.value}`)

---

7. Use Watchers Sparingly

Watchers (watch and watchEffect) are powerful but can make your code harder to understand if overused. Prefer computed properties or event-driven updates where possible.
Example:
watch(count, (newValue, oldValue) => {
console.log(`Count changed from ${oldValue} to ${newValue}`)
})

---

8. Group Related Logic Together

Keep related reactive state, computed properties, and functions together to make your code easier to follow.
Example:
// User-related logic
const user = reactive({ name: 'John', age: 30 })
const isAdult = computed(() => user.age >= 18)
function updateUser(newName) {
  user.name = newName
}

-----------

9. Use Lifecycle Hooks for Side Effects

Use lifecycle hooks (onMounted, onUnmounted, etc.) for side effects like fetching data or setting up event listeners.
Example:
onMounted(() => {
  console.log('Component mounted')
  fetchData()
})

onUnmounted(() => {
  console.log('Component unmounted')
  cleanup()
})

----------------

10. Use TypeScript for Better Type Safety
If your project uses TypeScript, leverage it to add type safety to your components.
Example:
<script setup lang="ts">
interface User {
  name: string
  age: number
}

const user = ref<User>({ name: 'John', age: 30 })
</script>

--------------

11. Keep Templates Clean

Avoid putting too much logic in your template. Instead, move complex logic into the script or composables.
Example:
<template>
  <div>
    <p>{{ fullName }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script setup>
const firstName = ref('John')
const lastName = ref('Doe')
const fullName = computed(() => `${firstName.value} ${lastName.value}`)

function increment() {
  // Logic here
}
</script>

------------

12. Use provide and inject for Prop Drilling
Avoid prop drilling by using provide and inject to share state across deeply nested components.
Example:
// Parent component
import { provide, ref } from 'vue'

const theme = ref('dark')
provide('theme', theme)

// Child component
import { inject } from 'vue'

const theme = inject('theme')

-----------------

13. Use v-model for Two-Way Binding

Use v-model to simplify two-way binding between parent and child components.
Example:
<!-- Parent component -->
<template>
  <ChildComponent v-model:name="userName" />
</template>

<script setup>
const userName = ref('John')
</script>

<!-- Child component -->
<template>
  <input :value="name" @input="$emit('update:name', $event.target.value)" />
</template>

<script setup>
defineProps(['name'])
defineEmits(['update:name'])
</script>

----------

14. Use defineProps and defineEmits for TypeScript Support

When using TypeScript, use defineProps and defineEmits to define props and emits with type safety.
Example:
<script setup lang="ts">
const props = defineProps<{
  title: string
  count: number
}>()

const emit = defineEmits<{
  (event: 'update:count', value: number): void
}>()
</script>

-------------

15. Use Scoped Styles

Use scoped styles (<style scoped>) to ensure styles are component-specific and don’t leak into other components.
Example:
<style scoped>
.button {
  background-color: blue;
}
</style>

------------------

16. Use Environment Variables

Use environment variables for configuration (e.g., API URLs) to keep your code flexible and secure.
Example:
const apiUrl = import.meta.env.VITE_API_URL

-------------

17. Write Unit Tests

Write unit tests for your components and composables to ensure they work as expected.
Example:
import { render } from '@testing-library/vue'
import MyComponent from '@/components/MyComponent.vue'

test('renders correctly', () => {
  const { getByText } = render(MyComponent)
  expect(getByText('Hello, Vue 3!')).toBeInTheDocument()
})