Now that you know all the communication tools in Vue, let's see how to combine them into advanced patterns - like a complete NOVA LAB communication system.
| Pattern | When to use | |---------|-----------| | Props | Passing data parent β child (1 level) | | Events | Communication child β parent (1 level) | | v-model | Two-way binding (forms, inputs) | | Provide/Inject | Deep communication (2+ levels) | | Pinia | Global application state |
Safe pattern - descendants cannot modify state directly:
1<!-- Provider -->
2<script setup>
3import { provide, ref, readonly } from 'vue'
4
5const state = ref({ theme: 'dark', lang: 'en' })
6
7provide('state', readonly(state))
8provide('updateState', (key, value) => {
9 state.value[key] = value
10})
11</script>
12
13<!-- Consumer -->
14<script setup>
15import { inject } from 'vue'
16
17const state = inject('state') // readonly
18const updateState = inject('updateState') // action
19
20updateState('theme', 'light') // OK - via action
21// state.value.theme = 'light' // Error - readonly!
22</script>Exposing component methods to the parent via ref:
1<!-- Child.vue -->
2<script setup>
3import { ref } from 'vue'
4
5const count = ref(0)
6const reset = () => { count.value = 0 }
7const validate = () => count.value > 0
8
9defineExpose({ reset, validate })
10</script>
11
12<!-- Parent.vue -->
13<script setup>
14import { ref } from 'vue'
15
16const childRef = ref(null)
17
18const handleReset = () => {
19 childRef.value.reset()
20 const isValid = childRef.value.validate()
21}
22</script>
23
24<template>
25 <Child ref="childRef" />
26 <button @click="handleReset">Reset Child</button>
27</template>1App (provide: global state)
2 βββ Layout
3 βββ Header (inject: theme, user)
4 β βββ Avatar (props: user.avatar)
5 β βββ emit('click') β Header
6 βββ Content
7 βββ Page (props from router)
8 βββ Form (v-model: data)
9 βββ emit('submit') β Page β API