\n\n\n```\n\n```vue\n\n\n\n\n```\n\n#### 2. В обычной функции `setup()` (Options API style)\nВ этом случае `defineExpose` используется внутри функции `setup()`.\n\n```javascript\nimport { ref } from 'vue'\n\nexport default {\n setup() {\n const internalState = ref('secret')\n const exposedState = ref('open')\n const exposedFunction = () => console.log('Exposed!')\n\n defineExpose({\n exposedState,\n exposedFunction\n })\n\n return {\n // Возвращаемые здесь свойства также доступны в шаблоне,\n // но НЕ автоматически доступны родителю через ref.\n // Для родителя доступны только свойства в defineExpose.\n exposedState\n }\n }\n}\n```\n\n### Ключевые моменты и различия с Vue 2\n\n* **Явность вместо автоматизма:** В Vue 2 любой метод из `methods` можно было вызвать из родителя. В Vue 3 с Composition API требуется явное объявление через `defineExpose`. Это улучшает **инкапсуляцию** и снижает риск случайных зависимостей.\n* **Не заменяет Props и Events:** `defineExpose` предназначен для редких случаев, когда требуется прямой доступ к внутренностям компонента (например, для управления фокусом, запуска специфических внутренних методов). Основным способом взаимодействия остаются **Props** (для передачи данных \"вниз\") и **Events** (для передачи данных \"вверх\").\n* **Типизация с TypeScript:** При использовании TypeScript можно явно типизировать экспортированные свойства, что улучшает безопасность кода.\n* **Аналог в Options API:** В Options API Vue 3 аналогичную роль играет опция **`expose`**, принимающая массив строк-имен свойств для экспорта.\n\n```javascript\n// Options API Vue 3 - аналог defineExpose\nexport default {\n expose: ['publicMethod', 'publicData'], // только эти свойства будут открыты\n data() { return { privateData: 'hidden' } },\n methods: {\n publicMethod() { /* ... */ },\n privateMethod() { /* ... */ }\n }\n}\n```\n\n### Когда использовать `defineExpose`?\n\n* **Интеграция с внешними библиотеками:** Когда сторонний инструмент требует прямой ссылки на DOM элемент или метод компонента.\n* **Сложные интерактивные компоненты:** Например, компонент модального окна, где родителю нужно вызывать методы `open()` или `close()` напрямую.\n* **Управление фокусом или состоянием UI:** Когда родитель должен напрямую вызвать `focus()` на элементе внутри дочернего компонента.\n* **Тестирование:** Для предоставления специфических методов или данных для модульных тестов.\n\n### Пример с TypeScript\n\n```typescript\n\n```\n\n**В заключение:** `defineExpose` в Vue 3 является важным инструментом для **контролируемого нарушения инкапсуляции**, позволяя компонентам безопасно и явно определять свой публичный API, доступный через `ref`. Это переход от имплицитного поведения Vue 2 к более явному и предсказуемому управлению взаимодействием между компонентами, что особенно ценно в крупных и сложных приложениях.","dateCreated":"2026-04-06T23:29:32.596681","upvoteCount":0,"author":{"@type":"Person","name":"deepseek-v3.2"}}}}
← Назад к вопросам

Что такое defineExpose во Vue 3?

1.7 Middle🔥 171 комментариев
#Vue.js

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое defineExpose в Vue 3?

defineExpose — это композиционный API, введенный в Vue 3 для контроля над тем, какие свойства и методы компонента становятся доступными его родителю. Это ключевой механизм для управления "публичным интерфейсом" компонента, особенно в контексте использования ref для получения прямого доступа к его внутренним свойствам.

Основная цель и контекст использования

В Vue 3, когда родительский компонент создает ссылку (ref) на дочерний компонент, он может получить доступ к его:

  • Публичным свойствам (например, объявленным в props или возвращаемым из setup()).
  • Экспортированным через defineExpose свойствам и методам.

Без использования defineExpose, все переменные и методы, объявленные в setup() или <script setup>, по умолчанию являются закрытыми (private) для компонента. Родитель не может получить к ним прямой доступ через ref. Это принципиальное отличие от Vue 2, где все методы и свойства компонента, объявленные в methods, data, computed и т.д., были автоматически доступны родителю.

Таким образом, defineExpose служит мостом, позволяющим компоненту явно указать, что он "открывает" для внешнего мира.

Практическое применение: <script setup> и обычный setup()

defineExpose можно использовать в двух основных синтаксисах:

1. В <script setup> (синтаксический сахар)

В этом синтаксисе все объявленные переменные и функции по умолчанию закрыты. defineExpose — единственный способ их открыть.

<!-- ChildComponent.vue -->
<script setup>
import { ref } from 'vue'

// Эти свойства закрыты для родителя
const privateCounter = ref(0)
const incrementPrivate = () => { privateCounter.value++ }

// Эти свойства мы хотим сделать публичными
const publicCounter = ref(0)
const publicMethod = () => { 
  publicCounter.value++
  console.log('Public method called')
}

// Используем defineExpose для экспорта
defineExpose({
  publicCounter,
  publicMethod
})
</script>

<template>
  <div>Child Component</div>
</template>
<!-- ParentComponent.vue -->
<script setup>
import { ref, onMounted } from 'vue'
import ChildComponent from './ChildComponent.vue'

const childRef = ref(null)

onMounted(() => {
  // Доступ только к экспортированным свойствам:
  console.log(childRef.value?.publicCounter) // Работает
  childRef.value?.publicMethod() // Работает
  
  // Попытка доступа к закрытым свойствам:
  console.log(childRef.value?.privateCounter) // undefined
  childRef.value?.incrementPrivate() // TypeError
})
</script>

<template>
  <ChildComponent ref="childRef" />
</template>

2. В обычной функции setup() (Options API style)

В этом случае defineExpose используется внутри функции setup().

import { ref } from 'vue'

export default {
  setup() {
    const internalState = ref('secret')
    const exposedState = ref('open')
    const exposedFunction = () => console.log('Exposed!')

    defineExpose({
      exposedState,
      exposedFunction
    })

    return {
      // Возвращаемые здесь свойства также доступны в шаблоне,
      // но НЕ автоматически доступны родителю через ref.
      // Для родителя доступны только свойства в defineExpose.
      exposedState
    }
  }
}

Ключевые моменты и различия с Vue 2

  • Явность вместо автоматизма: В Vue 2 любой метод из methods можно было вызвать из родителя. В Vue 3 с Composition API требуется явное объявление через defineExpose. Это улучшает инкапсуляцию и снижает риск случайных зависимостей.
  • Не заменяет Props и Events: defineExpose предназначен для редких случаев, когда требуется прямой доступ к внутренностям компонента (например, для управления фокусом, запуска специфических внутренних методов). Основным способом взаимодействия остаются Props (для передачи данных "вниз") и Events (для передачи данных "вверх").
  • Типизация с TypeScript: При использовании TypeScript можно явно типизировать экспортированные свойства, что улучшает безопасность кода.
  • Аналог в Options API: В Options API Vue 3 аналогичную роль играет опция expose, принимающая массив строк-имен свойств для экспорта.
// Options API Vue 3 - аналог defineExpose
export default {
  expose: ['publicMethod', 'publicData'], // только эти свойства будут открыты
  data() { return { privateData: 'hidden' } },
  methods: {
    publicMethod() { /* ... */ },
    privateMethod() { /* ... */ }
  }
}

Когда использовать defineExpose?

  • Интеграция с внешними библиотеками: Когда сторонний инструмент требует прямой ссылки на DOM элемент или метод компонента.
  • Сложные интерактивные компоненты: Например, компонент модального окна, где родителю нужно вызывать методы open() или close() напрямую.
  • Управление фокусом или состоянием UI: Когда родитель должен напрямую вызвать focus() на элементе внутри дочернего компонента.
  • Тестирование: Для предоставления специфических методов или данных для модульных тестов.

Пример с TypeScript

<script setup lang="ts">
import { ref } from 'vue'

const count = ref(0)
const validateInput = () => { /* ... */ }

// Типизация экспортированного интерфейса
defineExpose({
  count: count as Ref<number>,
  validateInput: validateInput as () => boolean
})
</script>

В заключение: defineExpose в Vue 3 является важным инструментом для контролируемого нарушения инкапсуляции, позволяя компонентам безопасно и явно определять свой публичный API, доступный через ref. Это переход от имплицитного поведения Vue 2 к более явному и предсказуемому управлению взаимодействием между компонентами, что особенно ценно в крупных и сложных приложениях.

Что такое defineExpose во Vue 3? | PrepBro