EwVueComponent API
Overview
EwVueComponent is a powerful Vue 3 dynamic component wrapper that supports dynamic switching between multiple component types, including HTML tags, Vue components, async components, and component objects.
Basic Usage
vue
<!-- HTML tag -->
<EwVueComponent is="div" />
<!-- Vue component -->
<EwVueComponent :is="MyComponent" />
<!-- Component object -->
<EwVueComponent :is="componentObject" />
<!-- Async component -->
<EwVueComponent :is="asyncComponent" />
Props
is
- Type:
string | Component | ComponentObject | (() => Promise<Component>)
- Required: Yes
- Description: The component type to render
vue
<template>
<!-- String component (HTML tag) -->
<EwVueComponent is="div" />
<!-- Vue component -->
<EwVueComponent :is="MyComponent" />
<!-- Component object -->
<EwVueComponent :is="componentObject" />
<!-- Async component -->
<EwVueComponent :is="asyncComponent" />
</template>
<script setup>
import { ref } from 'vue'
import { EwVueComponent } from 'ew-vue-component'
// Vue component
const MyComponent = {
name: 'MyComponent',
template: '<div>Hello World</div>'
}
// Component object
const componentObject = {
render() {
return h('div', 'Hello from render function')
}
}
// Async component
const asyncComponent = () => import('./MyAsyncComponent.vue')
</script>
fallback
- Type:
string | Component | ComponentObject
- Default:
undefined
- Description: Fallback component to use when the main component fails to load
vue
<template>
<EwVueComponent
:is="currentComponent"
fallback="div"
>
<template #default>
<p>Main content</p>
</template>
</EwVueComponent>
</template>
<script setup>
import { ref } from 'vue'
import { EwVueComponent } from 'ew-vue-component'
const currentComponent = ref('UnstableComponent')
</script>
errorComponent
- Type:
string | Component | ComponentObject
- Default:
undefined
- Description: Custom error component
vue
<template>
<EwVueComponent
:is="currentComponent"
:error-component="ErrorComponent"
/>
</template>
<script setup>
import { ref, h } from 'vue'
import { EwVueComponent } from 'ew-vue-component'
const currentComponent = ref('BrokenComponent')
const ErrorComponent = {
render() {
return h('div', { class: 'error' }, [
h('h3', 'Component Loading Failed'),
h('p', 'Please try again later')
])
}
}
</script>
cache
- Type:
boolean
- Default:
false
- Description: Whether to enable component caching
cacheKey
- Type:
string
- Default:
''
- Description: Custom cache key
cacheTtl
- Type:
number
- Default:
300000
(5 minutes) - Description: Cache time-to-live in milliseconds
vue
<template>
<EwVueComponent
:is="currentComponent"
:cache="true"
cache-key="my-component"
:cache-ttl="600000"
/>
</template>
plugins
- Type:
Plugin[]
- Default:
[]
- Description: Array of plugins to use
vue
<template>
<EwVueComponent
:is="currentComponent"
:plugins="[logPlugin, performancePlugin]"
/>
</template>
Props and Attrs Forwarding
EwVueComponent automatically forwards all props (except is
, fallback
, errorComponent
, cache
, cacheKey
, cacheTtl
, plugins
) and attrs to the target component:
vue
<template>
<EwVueComponent
:is="currentComponent"
:title="title"
:count="count"
:disabled="disabled"
class="my-component"
data-testid="test-component"
@click="handleClick"
@input="handleInput"
/>
</template>
<script setup>
import { ref } from 'vue'
import { EwVueComponent } from 'ew-vue-component'
const currentComponent = ref('button')
const title = ref('Click me')
const count = ref(0)
const disabled = ref(false)
const handleClick = () => {
count.value++
}
const handleInput = (value) => {
console.log('Input:', value)
}
</script>
Slot Forwarding
EwVueComponent supports all types of slot forwarding:
vue
<template>
<EwVueComponent :is="currentComponent">
<!-- Default slot -->
<template #default>
<p>Default content</p>
</template>
<!-- Named slots -->
<template #header>
<h2>Header content</h2>
</template>
<!-- Scoped slots -->
<template #item="{ data, index }">
<div class="item">
{{ index + 1 }}. {{ data.title }}
</div>
</template>
</EwVueComponent>
</template>
<script setup>
import { ref } from 'vue'
import { EwVueComponent } from 'ew-vue-component'
const currentComponent = ref('ListItem')
</script>
Event Forwarding
All events are automatically forwarded to the target component:
vue
<template>
<EwVueComponent
:is="currentComponent"
@click="handleClick"
@input="handleInput"
@change="handleChange"
@submit="handleSubmit"
/>
</template>
<script setup>
import { ref } from 'vue'
import { EwVueComponent } from 'ew-vue-component'
const currentComponent = ref('input')
const handleClick = (event) => {
console.log('Click event:', event)
}
const handleInput = (event) => {
console.log('Input event:', event.target.value)
}
const handleChange = (event) => {
console.log('Change event:', event.target.value)
}
const handleSubmit = (event) => {
console.log('Submit event:', event)
event.preventDefault()
}
</script>
Events
error
- Type:
(error: Error) => void
- Description: Triggered when component rendering encounters an error
vue
<template>
<EwVueComponent
:is="currentComponent"
@error="handleError"
/>
</template>
<script setup>
import { ref } from 'vue'
import { EwVueComponent } from 'ew-vue-component'
const currentComponent = ref('BrokenComponent')
const handleError = (error) => {
console.error('Component error:', error)
// Handle error here, such as showing error message, reporting error, etc.
}
</script>
Component Types
HTML Tags
vue
<template>
<EwVueComponent is="div" class="container">
<p>This is a div element</p>
</EwVueComponent>
</template>
Vue Components
vue
<template>
<EwVueComponent :is="MyComponent" :title="title" />
</template>
<script setup>
import { ref } from 'vue'
import { EwVueComponent } from 'ew-vue-component'
import MyComponent from './MyComponent.vue'
const title = ref('Hello World')
</script>
Component Objects
vue
<template>
<EwVueComponent :is="componentObject" />
</template>
<script setup>
import { ref, h } from 'vue'
import { EwVueComponent } from 'ew-vue-component'
const componentObject = ref({
render() {
return h('div', { class: 'custom-component' }, 'Dynamically created component')
}
})
</script>
Async Components
vue
<template>
<EwVueComponent :is="asyncComponent" />
</template>
<script setup>
import { ref } from 'vue'
import { EwVueComponent } from 'ew-vue-component'
const asyncComponent = ref(() => import('./AsyncComponent.vue'))
</script>
Error Handling
Basic Error Handling
vue
<template>
<EwVueComponent
:is="currentComponent"
@error="handleError"
/>
</template>
<script setup>
import { ref } from 'vue'
import { EwVueComponent } from 'ew-vue-component'
const currentComponent = ref('BrokenComponent')
const handleError = (error) => {
console.error('Component error:', error)
// Fallback to safe component
currentComponent.value = 'div'
}
</script>
Using Fallback Components
vue
<template>
<EwVueComponent
:is="currentComponent"
:fallback="FallbackComponent"
/>
</template>
<script setup>
import { ref, h } from 'vue'
import { EwVueComponent } from 'ew-vue-component'
const currentComponent = ref('BrokenComponent')
const FallbackComponent = {
render() {
return h('div', { class: 'fallback' }, 'Fallback content')
}
}
</script>
Custom Error Components
vue
<template>
<EwVueComponent
:is="currentComponent"
:error-component="ErrorComponent"
/>
</template>
<script setup>
import { ref, h } from 'vue'
import { EwVueComponent } from 'ew-vue-component'
const currentComponent = ref('BrokenComponent')
const ErrorComponent = {
props: ['error', 'retry'],
render() {
return h('div', { class: 'error-boundary' }, [
h('h3', 'Something went wrong'),
h('p', this.error?.message || 'Unknown error'),
h('button', { onClick: this.retry }, 'Retry')
])
}
}
</script>
Performance Features
Caching
vue
<template>
<EwVueComponent
:is="currentComponent"
:cache="true"
:cache-key="cacheKey"
:cache-ttl="600000"
/>
</template>
<script setup>
import { ref, computed } from 'vue'
import { EwVueComponent } from 'ew-vue-component'
const currentComponent = ref(() => import('./HeavyComponent.vue'))
const componentId = ref('heavy-1')
const cacheKey = computed(() => `heavy-component-${componentId.value}`)
</script>
Performance Monitoring
vue
<template>
<EwVueComponent
:is="currentComponent"
:plugins="[performancePlugin]"
/>
</template>
<script setup>
import { ref } from 'vue'
import { EwVueComponent } from 'ew-vue-component'
const currentComponent = ref('div')
const performancePlugin = {
name: 'performance',
beforeRender(component, props, context) {
performance.mark('component-render-start')
},
afterRender(component, props, context) {
performance.mark('component-render-end')
performance.measure('component-render', 'component-render-start', 'component-render-end')
}
}
</script>
TypeScript Support
EwVueComponent is fully written in TypeScript and provides complete type definitions:
typescript
import { EwVueComponent } from 'ew-vue-component'
import type { ComponentType, Plugin } from 'ew-vue-component'
// Type-safe component usage
const MyComponent: ComponentType = {
render() {
return h('div', 'Typed component')
}
}
// Type-safe plugin
const myPlugin: Plugin = {
name: 'my-plugin',
beforeRender(component, props, context) {
// Fully typed context
context.utils.log('Rendering component')
}
}