Vue3 Api Expose
# Vue 3 `expose()` API: Controlling Component Public Interfaces
In Vue 3, the `expose()` function is a powerful utility within the Composition API. It allows developers to explicitly define and restrict which internal properties and methods of a component are accessible to parent components via template refs.
---
## Why Do We Need `expose()`?
In Vue 2, all properties and methods declared on a component instance were public by default. Any parent component using a `ref` to target a child component could access and modify its entire internal state. While convenient, this design introduced several issues:
1. **Security and Encapsulation Risks**: Internal helper methods or state variables could be accidentally accessed or mutated by parent components, leading to fragile code and unexpected side effects.
2. **Maintainability Challenges**: Without a clear boundary between public and private APIs, it was difficult to refactor a child component's internal logic because developers couldn't easily tell which properties were being relied upon by external parent components.
Vue 3 introduces the `expose()` function to solve these issues by giving developers precise control over a component's public interface.
---
## How to Use `expose()`
### Basic Syntax (Standard Composition API)
When using the standard `setup(props, context)` function, `expose` is available as a method on the `context` object.
```javascript
export default {
setup(props, context) {
const internalMethod = () => {
console.log('This is an internal method (private)');
};
const publicMethod = () => {
console.log('This is a public method');
};
// Explicitly expose only the publicMethod
context.expose({
publicMethod
});
// Return properties needed for the component's own template
return {
internalMethod
};
}
};
```
### Explanation
In the example above, we define two methods: `internalMethod` and `publicMethod`. By calling `context.expose({ publicMethod })`, only `publicMethod` is made accessible to parent components. `internalMethod` remains strictly private and encapsulated within the child component.
---
## Practical Examples
### 1. Parent-Child Component Communication
A common use case is when a parent component needs to trigger an action inside a child component (e.g., opening a modal, resetting a form, or playing a video).
#### Child Component (`ChildComponent.vue`)
```javascript
import { ref } from 'vue';
export default {
setup(props, context) {
const childMethod = () => {
console.log('Child method called successfully!');
};
// Expose the method to the parent
context.expose({
childMethod
});
return {};
}
};
```
#### Parent Component (`ParentComponent.vue`)
```javascript
import { ref, onMounted } from 'vue';
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
setup() {
// Create a template ref for the child component
const childRef = ref(null);
onMounted(() => {
if (childRef.value) {
// Call the exposed method from the child component
childRef.value.childMethod();
}
});
return {
childRef
};
}
};
```
---
### 2. Building Component Libraries
When developing reusable component libraries, maintaining a clean public API is critical. You want to hide complex internal states and only expose stable, documented APIs.
```javascript
import { ref } from 'vue';
export default {
setup(props, context) {
const internalState = ref('internal state');
const publicState = ref('public state');
const publicMethod = () => {
console.log('Public method called');
};
// Expose only the public state and method
context.expose({
publicState,
publicMethod
});
// internalState is returned only for local template rendering
return {
internalState
};
}
};
```
---
## Modern Alternative: `defineExpose` in `
```
---
## Key Considerations
1. **Multiple Calls to `expose()`**: If you call `expose()` multiple times within a component, only the properties specified in the **last** call will be exposed.
2. **Template Refs Integration**: To access exposed properties in a parent component, you must bind the child component to a template `ref` and access them via `.value` (e.g., `childRef.value.exposedMethod()`).
3. **Closed by Default in `
YouTip