YouTip LogoYouTip

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 `