### Install vue-property-decorator
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/README.md
Install the library using npm.
```bash
npm i -S vue-property-decorator
```
--------------------------------
### Basic @Provide Example
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Demonstrates how to provide a message from a parent component to its descendants.
```typescript
import { Vue, Component, Provide, Inject } from 'vue-property-decorator'
@Component
export class ParentComponent extends Vue {
@Provide() message = 'Hello from parent!'
}
```
--------------------------------
### Install vue-property-decorator
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/INDEX.md
Install the necessary packages for vue-property-decorator, including Vue, vue-class-component, TypeScript, and reflect-metadata.
```bash
npm install vue-property-decorator vue vue-class-component
npm install -D typescript reflect-metadata
```
--------------------------------
### Example Usage of InjectOptions
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/types.md
Demonstrates injecting dependencies with custom keys and default values using @Inject.
```typescript
@Component
export class MyComponent extends Vue {
// Inject with custom key and default
@Inject({ from: 'userService', default: null })
userService!: any
// Inject with symbol key and default
@Inject({ from: serviceSymbol, default: {} })
service!: any
}
```
--------------------------------
### Basic PropSync Usage
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/PropSync.md
Demonstrates the basic setup for @PropSync in a child component and its usage with the .sync modifier in a parent component.
```typescript
import { Vue, Component, PropSync } from 'vue-property-decorator'
@Component
export default class ChildComponent extends Vue {
@PropSync('name', { type: String })
syncedName!: string
}
```
```html
// ParentComponent.vue
```
--------------------------------
### Theme Provider Example
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Demonstrates how to provide a theme object to child components using the @Provide decorator and inject it using the @Inject decorator.
```typescript
@Component
class ThemeProvider extends Vue {
@Provide('theme')
theme = { primary: '#007bff', secondary: '#6c757d' }
}
@Component
class StyledComponent extends Vue {
@Inject('theme')
theme!: any
}
```
--------------------------------
### Install vue-property-decorator
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/configuration.md
Install vue-property-decorator as a peer dependency alongside vue-class-component. Also install vue-class-component and reflect-metadata as dev dependencies.
```bash
npm install --save vue-property-decorator
npm install --save-dev vue-class-component reflect-metadata
```
--------------------------------
### Basic VModel with String
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/VModel.md
Demonstrates a basic VModel setup for a string property. Use this for simple text inputs.
```typescript
import { Vue, Component, VModel } from 'vue-property-decorator'
@Component
export default class TextInputComponent extends Vue {
@VModel() value!: string
updateValue(newValue: string) {
this.value = newValue
}
}
```
```vue
Message: {{ message }}
```
--------------------------------
### Runtime Setup with Reflect Metadata
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/INDEX.md
Import 'reflect-metadata' once at your application's entry point. This is required for decorators to function correctly at runtime.
```typescript
import 'reflect-metadata' // Import once at app entry
import Vue from 'vue'
import App from './App.vue'
new Vue({ render: h => h(App) }).$mount('#app')
```
--------------------------------
### Vue Provide with String Key
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Example of using a string as a key for the @Provide decorator.
```typescript
import { Provide } from 'vue-property-decorator';
class MyComponent {
@Provide('myKey')
value = 'test'
}
```
--------------------------------
### package.json Scripts for Build and Development
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/configuration.md
Defines common npm scripts for building the project, running tests, starting the development server, and linting code.
```json
{
"scripts": {
"build": "tsc -p ./src/tsconfig.json && rollup -c",
"test": "jest",
"dev": "vue-cli-service serve",
"lint": "eslint --ext .ts,.tsx,.vue src"
}
}
```
--------------------------------
### Service Injection Example
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Illustrates providing multiple services like a logger and an API client using @Provide and injecting them into a data component with @Inject.
```typescript
@Component
class ServiceProvider extends Vue {
@Provide('logger')
logger = console
@Provide('api')
api = new APIClient()
}
@Component
class DataComponent extends Vue {
@Inject('logger')
logger!: Console
@Inject('api')
api!: APIClient
}
```
--------------------------------
### Basic @Inject Example
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Shows how a child component can inject and use a message provided by an ancestor.
```typescript
@Component
export class ChildComponent extends Vue {
@Inject() message!: string // Receives 'Hello from parent!'
}
```
--------------------------------
### Basic Vue Component Class Setup
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/configuration.md
Defines a Vue component using class syntax and decorators. Includes properties, props, lifecycle hooks, and methods.
```typescript
import { Vue, Component, Prop } from 'vue-property-decorator'
@Component
export default class MyComponent extends Vue {
// Properties
message = 'Hello'
// Prop
@Prop(String)
title!: string
// Lifecycle
mounted() {
console.log('Component mounted')
}
// Methods
greet() {
return `${this.message}, ${this.title}`
}
}
```
--------------------------------
### Setup Reflect-Metadata in Entry Point
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/configuration.md
Import 'reflect-metadata' once at the top of your main entry point file (e.g., main.ts) before any Vue components are defined to enable automatic type inference from decorators.
```typescript
import 'reflect-metadata'
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')
```
--------------------------------
### Prop Decorator Usage Examples
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Prop.md
Illustrates various ways to use the @Prop decorator, including simple type declarations, default values, multiple types, validation, and inference with reflect-metadata.
```APIDOC
## Usage Examples
### Simple type prop with constructor
```typescript
import { Vue, Component, Prop } from 'vue-property-decorator'
@Component
export default class MyComponent extends Vue {
@Prop(String)
readonly name!: string
@Prop(Number)
readonly age!: number
}
```
### Prop with default value
```typescript
@Component
export default class MyComponent extends Vue {
@Prop({ default: 'Guest' })
readonly name!: string
@Prop({ type: Number, default: 0 })
readonly count!: number
}
```
### Prop with multiple accepted types
```typescript
@Component
export default class MyComponent extends Vue {
@Prop([String, Number])
readonly value!: string | number
}
```
### Prop with validation
```typescript
@Component
export default class MyComponent extends Vue {
@Prop({
type: Number,
required: true,
validator: (value: number) => value > 0
})
readonly quantity!: number
}
```
### Using with reflect-metadata
```typescript
import 'reflect-metadata'
import { Vue, Component, Prop } from 'vue-property-decorator'
@Component
export default class MyComponent extends Vue {
@Prop()
readonly age!: number // Type automatically inferred as Number
}
```
### Parent component passing props
```typescript
```
--------------------------------
### Single Model Example
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Model.md
Illustrates a component with a single string v-model. Vue 2.x supports only one v-model per component directly.
```typescript
@Component
export default class SingleModelComponent extends Vue {
@Model('change', { type: String })
readonly value!: string
}
```
--------------------------------
### Complex Example: Form Field Component
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/VModel.md
A comprehensive example of a form field component with VModel, including input handling, blur events, and validation. This pattern is reusable for various form inputs.
```typescript
@Component
export default class FormField extends Vue {
@VModel({ type: String })
value!: string
errorMessage = ''
isTouched = false
onInput(event: Event) {
const target = event.target as HTMLInputElement
this.value = target.value
this.validate()
}
onBlur() {
this.isTouched = true
this.validate()
}
validate() {
if (this.value.length === 0) {
this.errorMessage = 'This field is required'
} else if (this.value.length < 3) {
this.errorMessage = 'Minimum 3 characters'
} else {
this.errorMessage = ''
}
}
get hasError() {
return this.isTouched && this.errorMessage.length > 0
}
}
```
```vue
```
```vue
```
--------------------------------
### PropSync with Reflect Metadata
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/PropSync.md
Example of using @PropSync when 'reflect-metadata' is enabled, allowing type inference from the TypeScript annotation.
```typescript
import 'reflect-metadata'
import { Vue, Component, PropSync } from 'vue-property-decorator'
@Component
export default class ChildComponent extends Vue {
@PropSync('count')
currentCount!: number // Type inferred from annotation
}
```
--------------------------------
### Webpack ts-loader Configuration
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/configuration.md
Example ts-loader configuration for Webpack, specifying the tsconfig.json file. This is relevant for projects not using Vue CLI.
```javascript
{
test: /\.tsx?$/,
use: [
{
loader: 'ts-loader',
options: {
configFile: 'tsconfig.json'
}
}
]
}
```
--------------------------------
### Complex Scenario with Multiple Synced Props
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/PropSync.md
An example showcasing the use of multiple @PropSync decorators within a single component to manage several two-way bound props.
```APIDOC
## Complex scenario with multiple synced props
### Description
This example illustrates how to use multiple `@PropSync` decorators within a single component to manage several two-way bound props simultaneously. Changes to `syncedEmail` or `syncedAge` will emit corresponding update events.
### Child Component Usage
```typescript
@Component
export default class FormComponent extends Vue {
@PropSync('email', { type: String, required: true })
syncedEmail!: string
@PropSync('age', { type: Number })
syncedAge!: number
onSubmit() {
// Changes to syncedEmail or syncedAge emit update events
this.syncedEmail = this.syncedEmail.toLowerCase()
this.syncedAge += 1
}
}
```
```
--------------------------------
### Complex Async Workflow with @Emit and Error Handling
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Emit.md
This example demonstrates a complex asynchronous operation where the @Emit decorator is used for success events, and manual $emit is used for error events. It also shows how to manage component state during async operations.
```typescript
@Component
export default class APIComponent extends Vue {
isLoading = false
@Emit('fetch-complete')
async fetchUserData(userId: number) {
this.isLoading = true
try {
const response = await fetch(`/api/users/${userId}`)
const user = await response.json()
this.isLoading = false
return user
} catch (error) {
this.isLoading = false
this.$emit('fetch-error', error)
throw error
}
}
}
```
```html
// Parent usage
processUser(userData)"
@fetch-error="error => handleError(error)"
/>
```
--------------------------------
### Basic Reactive Provide Example
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/ProvideReactive-InjectReactive.md
Use @ProvideReactive to make a property reactive and automatically update child components. The child component uses @InjectReactive to access this reactive property.
```typescript
import { Vue, Component, ProvideReactive, InjectReactive } from 'vue-property-decorator'
@Component
export class ParentComponent extends Vue {
@ProvideReactive() count = 0
increment() {
this.count++ // Child components automatically see this change
}
}
```
```typescript
@Component
export class ChildComponent extends Vue {
@InjectReactive() count!: number
created() {
// Will always have the latest value from parent
console.log(this.count)
}
}
```
--------------------------------
### Form Field Refs with Validation
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Ref.md
Access form input elements via refs to get their values and apply validation logic or styling. This example shows email and password validation.
```typescript
@Component
export default class FormValidation extends Vue {
@Ref('emailInput') readonly email!: HTMLInputElement
@Ref('passwordInput') readonly password!: HTMLInputElement
validateForm() {
const isEmailValid = this.validateEmail()
const isPasswordValid = this.validatePassword()
return isEmailValid && isPasswordValid
}
validateEmail() {
const value = this.email?.value || ''
const isValid = /^[^ - - - ]+@[^ - - - ]+.[^ - - - ]+$/.test(value)
this.email?.classList.toggle('error', !isValid)
return isValid
}
validatePassword() {
const value = this.password?.value || ''
const isValid = value.length >= 8
this.password?.classList.toggle('error', !isValid)
return isValid
}
submitForm() {
if (this.validateForm()) {
console.log('Form is valid, submitting...')
}
}
}
```
```vue
```
--------------------------------
### Provide Application Configuration
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Demonstrates providing a complex configuration object for application-wide use.
```typescript
interface AppConfig {
apiUrl: string
maxRetries: number
timeout: number
}
@Component
export class AppComponent extends Vue {
@Provide('appConfig')
config: AppConfig = {
apiUrl: 'https://api.example.com',
maxRetries: 3,
timeout: 5000
}
}
```
--------------------------------
### Watch Nested Path
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Watch.md
Watch a specific nested property within an array or object. This example watches the 'items' array itself.
```typescript
@Component
export default class ListComponent extends Vue {
items = [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
]
@Watch('items')
onItemsChanged() {
console.log('Items array changed')
}
}
```
--------------------------------
### With default values and reactivity
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/ProvideReactive-InjectReactive.md
Explains how to provide default values for injected reactive properties and how to update them reactively.
```APIDOC
## With default values and reactivity
### Settings Provider
```typescript
import { Vue, Component, ProvideReactive } from 'vue-property-decorator'
const settingsKey = Symbol('AppSettings')
@Component
export class SettingsProvider extends Vue {
@ProvideReactive(settingsKey)
settings = {
fontSize: 14,
darkMode: false,
notifications: true
}
updateSetting(key: string, value: any) {
this.settings[key] = value
}
}
```
### Settings Consumer
```typescript
import { Vue, Component, InjectReactive } from 'vue-property-decorator'
@Component
export class SettingsConsumer extends Vue {
@InjectReactive({
from: settingsKey,
default: { fontSize: 14, darkMode: false, notifications: true }
})
settings!: any
toggleDarkMode() {
this.settings.darkMode = !this.settings.darkMode
}
changeFontSize(size: number) {
this.settings.fontSize = size
}
}
```
```
--------------------------------
### Reactive state management
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/ProvideReactive-InjectReactive.md
Illustrates how to manage complex reactive state, such as theme, language, and user information, using a Symbol as a key for providing and injecting.
```APIDOC
## Reactive state management
### State Provider
```typescript
import { Vue, Component, ProvideReactive } from 'vue-property-decorator'
const stateKey = Symbol('appState')
@Component
export class StateProvider extends Vue {
@ProvideReactive(stateKey)
state = {
theme: 'light',
language: 'en',
user: null
}
setTheme(theme: string) {
this.state.theme = theme // Reactive update
}
setLanguage(language: string) {
this.state.language = language // Reactive update
}
}
```
### State Consumer
```typescript
import { Vue, Component, InjectReactive } from 'vue-property-decorator'
@Component
export class StateConsumer extends Vue {
@InjectReactive(stateKey)
state!: any
toggleTheme() {
const newTheme = this.state.theme === 'light' ? 'dark' : 'light'
// Parent's setTheme will be called
}
get currentLanguage() {
return this.state.language // Reactive
}
}
```
```
--------------------------------
### Vue Equivalent
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Prop.md
Demonstrates how the @Prop decorator usage translates to the standard Vue 'props' option in JavaScript.
```APIDOC
## Vue Equivalent
The following decorator usage:
```typescript
@Component
class MyComponent extends Vue {
@Prop(String) name!: string
@Prop({ default: 5 }) count!: number
}
```
Is equivalent to:
```javascript
export default {
props: {
name: { type: String },
count: { default: 5 }
}
}
```
```
--------------------------------
### Provide with Custom Keys
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Illustrates providing values using both Symbol keys and string keys for custom injection.
```typescript
const symbolKey = Symbol('customKey')
@Component
export class ParentComponent extends Vue {
@Provide(symbolKey)
secret = 'This is a secret'
@Provide('apiUrl')
apiUrl = 'https://api.example.com'
}
```
--------------------------------
### Vue @Model Decorator Example
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/README.md
Defines a model property for v-model binding. The first argument is the event name, and the second is the prop options.
```typescript
import { Vue, Component, Model } from 'vue-property-decorator'
@Component
export default class YourComponent extends Vue {
@Model('change', { type: Boolean }) readonly checked!: boolean
}
```
```javascript
export default {
model: {
prop: 'checked',
event: 'change',
},
props: {
checked: {
type: Boolean,
},
},
}
```
--------------------------------
### Vue @PropSync Decorator Example
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/README.md
Synchronizes a prop with a computed property, allowing two-way binding. The first argument to @PropSync is the prop name.
```typescript
import { Vue, Component, PropSync } from 'vue-property-decorator'
@Component
export default class YourComponent extends Vue {
@PropSync('name', { type: String }) syncedName!: string
}
```
```javascript
export default {
props: {
name: {
type: String,
},
},
computed: {
syncedName: {
get() {
return this.name
},
set(value) {
this.$emit('update:name', value)
},
},
},
}
```
--------------------------------
### Refs in Lifecycle Hooks
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Ref.md
Refs are guaranteed to be available in lifecycle hooks like `mounted`. Use them for DOM manipulation or setup after the component has been rendered.
```typescript
@Component
export default class LifecycleRefComponent extends Vue {
@Ref() readonly container!: HTMLDivElement
mounted() {
// Ref is available after component is mounted
console.log('Container:', this.container)
this.setupContainer()
}
setupContainer() {
this.container?.classList.add('initialized')
}
beforeDestroy() {
// Cleanup if needed
this.container?.classList.remove('initialized')
}
}
```
--------------------------------
### Vue Provide/Inject JavaScript Equivalent
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Shows the equivalent JavaScript implementation for the @Provide and @Inject decorator usage in Vue components.
```javascript
// ParentComponent
export default {
data() {
return {
msg: 'Hello'
}
},
provide() {
return {
message: this.msg
}
}
}
// ChildComponent
export default {
inject: {
message: 'message'
}
}
```
--------------------------------
### Accessing DOM Elements with Ref
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/INDEX.md
Use the Ref decorator to get a reference to a DOM element within a Vue component for direct manipulation.
```typescript
@Component
export class Form extends Vue {
@Ref() readonly input!: HTMLInputElement
submit() {
const value = this.input?.value
}
}
```
--------------------------------
### Vue Component with @Watch Decorator
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Watch.md
Example of using the @Watch decorator to observe changes in a component property. It demonstrates immediate and deep watching options.
```typescript
import Vue from 'vue'
import Component from 'vue-class-component'
@Component
class UserComponent extends Vue {
userName = ''
@Watch('userName', { immediate: true, deep: true })
onUserNameChanged(newValue: string, oldValue: string) {
console.log(newValue)
}
}
```
--------------------------------
### ThemeProvider
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/ProvideReactive-InjectReactive.md
Provides a reactive theme configuration using @ProvideReactive. Includes a method to update the theme.
```APIDOC
## ThemeProvider
### Description
Provides a reactive theme configuration using the @ProvideReactive decorator. Child components can inject this theme to style their elements accordingly.
### Methods
#### setTheme(newTheme: ThemeConfig)
Updates the current theme configuration with new values. The changes are reactive across all injected instances.
### Provided Properties
- **theme** (ThemeConfig): A reactive object containing theme properties like `primary`, `secondary`, and `background` colors.
```
--------------------------------
### Reactive service injection
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/ProvideReactive-InjectReactive.md
Shows how to inject reactive services, like a notification service, allowing components to interact with and receive updates from the service instance.
```APIDOC
## Reactive service injection
### Service Definition
```typescript
class NotificationService {
messages: string[] = []
addMessage(msg: string) {
this.messages.push(msg)
}
removeMessage(index: number) {
this.messages.splice(index, 1)
}
}
```
### Service Provider
```typescript
import { Vue, Component, ProvideReactive } from 'vue-property-decorator'
const serviceKey = Symbol('NotificationService')
@Component
export class AppComponent extends Vue {
@ProvideReactive(serviceKey)
service = new NotificationService()
notify(message: string) {
this.service.addMessage(message)
}
}
```
### Service Consumer
```typescript
import { Vue, Component, InjectReactive } from 'vue-property-decorator'
@Component
export class NotificationCenter extends Vue {
@InjectReactive(serviceKey)
service!: NotificationService
get messages() {
return this.service.messages // Reactive, updates when service changes
}
clearMessage(index: number) {
this.service.removeMessage(index)
}
}
```
```
--------------------------------
### Vue Provide/Inject Decorator Usage
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Demonstrates the usage of @Provide and @Inject decorators for dependency injection between parent and child Vue components.
```typescript
import { Component, Provide, Inject } from 'vue-property-decorator';
import Vue from 'vue';
@Component
class ParentComponent extends Vue {
@Provide('message')
msg = 'Hello'
}
@Component
class ChildComponent extends Vue {
@Inject('message')
message!: string
}
```
--------------------------------
### Vue Equivalent of @Prop Decorator Usage
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Prop.md
Shows the equivalent Vue JavaScript options object configuration for the provided @Prop decorator usage.
```javascript
export default {
props: {
name: { type: String },
count: { default: 5 }
}
}
```
--------------------------------
### Equivalent Vue Options API for ProvideReactive
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/ProvideReactive-InjectReactive.md
Shows the equivalent Vue.js options API implementation for providing reactive state, corresponding to the @ProvideReactive decorator.
```javascript
export default {
data() {
return {
count: 0
}
},
provide() {
return {
__reactiveInject__: this,
count: this.count
}
}
}
```
--------------------------------
### Dynamic Template Rendering with @Ref
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Ref.md
Use @Ref to get a typed reference to a DOM element for dynamic content manipulation. Ensure the element exists before accessing its properties.
```typescript
@Component
export default class DynamicRefComponent extends Vue {
@Ref() readonly content!: HTMLDivElement
updateContent(html: string) {
if (this.content) {
this.content.innerHTML = html
}
}
getContentHeight() {
return this.content?.offsetHeight || 0
}
scrollToTop() {
this.content?.scrollTo({ top: 0, behavior: 'smooth' })
}
}
```
--------------------------------
### Inject Application Configuration
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Shows how a component can inject and utilize the application configuration provided by an ancestor.
```typescript
@Component
export class APIClient extends Vue {
@Inject('appConfig')
config!: AppConfig
async fetch(endpoint: string) {
const url = `${this.config.apiUrl}${endpoint}`
// Use config
}
}
```
--------------------------------
### Vue Provide with Symbol Key
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Demonstrates using a Symbol as an injection key with the @Provide decorator, which is preferred for internal APIs to prevent naming conflicts.
```typescript
import { Provide } from 'vue-property-decorator';
const internalKey = Symbol('internal');
class MyComponent {
@Provide(internalKey)
value = 'secret'
}
```
--------------------------------
### VModel Decorator Usage
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/VModel.md
This example demonstrates how to use the @VModel decorator to create a typed property that supports two-way binding. The type of the 'value' property is inferred from the TypeScript annotation.
```APIDOC
## @VModel
### Description
The `@VModel` decorator is used to declare a property that supports two-way data binding using Vue's `v-model` directive. It automatically configures the component to accept a `value` prop and emit an `input` event, which is the standard convention for `v-model`.
### Usage
```typescript
import 'reflect-metadata'
import { Vue, Component, VModel } from 'vue-property-decorator'
@Component
export default class TypedVModelComponent extends Vue {
@VModel() // Type inferred from annotation
value!: number
}
```
### Vue Equivalent
The decorator usage is equivalent to the following Vue component options:
```javascript
export default {
model: {
prop: 'value',
event: 'input'
},
props: {
value: { type: String } // Type can be specified, e.g., { type: String }
},
computed: {
value: {
get() {
return this.value
},
set(value) {
this.$emit('input', value)
}
}
}
}
```
### Parent Component Usage
Parent components can bind to this component using the `v-model` directive:
```vue
```
### Comparison with other decorators
- **`@VModel`**: Fixed prop name ('value') and event name ('input'). Simplest for standard v-model usage.
- **`@Model`**: Custom prop and event names. Offers most flexibility.
- **`@ModelSync`**: Custom prop and event names, similar to `@Model` but with a computed property for direct modification.
```
--------------------------------
### Emitting Without Explicit Event Name
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Emit.md
Demonstrates emitting events using the default naming convention (kebab-case of method name) for methods that return values or have arguments.
```APIDOC
## Emitting without explicit event name
### Usage Example
```typescript
import { Vue, Component, Emit } from 'vue-property-decorator'
@Component
export default class ActionComponent extends Vue {
@Emit()
onClicked() {
// Method name converted: onClicked → on-clicked
return { timestamp: Date.now() }
}
@Emit()
userDataChanged() {
// userDataChanged → user-data-changed
return this.userData
}
}
```
```
--------------------------------
### Measure DOM Element with @Ref
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Ref.md
Get the dimensions of a DOM element using @Ref. This pattern is helpful for layout calculations or animations. Ensure the ref is correctly typed as an element.
```typescript
@Ref() readonly container!: HTMLDivElement
getWidth() {
return this.container?.clientWidth || 0
}
getHeight() {
return this.container?.clientHeight || 0
}
```
--------------------------------
### Inject with Symbol Keys for Type Safety
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Shows how to inject services using Symbol keys, ensuring type safety and avoiding key collisions.
```typescript
// ChildComponent
@Component
export class ChildComponent extends Vue {
@Inject(userServiceKey)
userService!: any
@Inject(authServiceKey)
authService!: any
created() {
const user = this.userService.getUser()
const authenticated = this.authService.isAuthenticated
}
}
```
--------------------------------
### Dropdown/Select Input Wrapper with @VModel
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/VModel.md
Implement a custom select or dropdown component using @VModel for easy integration with v-model. This example shows how to bind the selected option to the `value` prop.
```typescript
@Component
export default class SelectInput extends Vue {
@VModel({ type: String })
value!: string
options = ['A', 'B', 'C']
}
```
--------------------------------
### Emitting with Arguments and Return Value
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Emit.md
When a method has both a return value and arguments, the return value is emitted as the first argument, followed by the original method arguments.
```APIDOC
## Emitting with Arguments and Return Value
Original method arguments follow the return value
### Usage Example
```typescript
import { Vue, Component, Emit } from 'vue-property-decorator'
@Component
export default class FormComponent extends Vue {
@Emit()
submitForm(data: any) {
// Return value becomes first argument
return { success: true, timestamp: Date.now() }
}
}
```
```html
// Parent receives return value as first arg, followed by original args
handleSubmit(result, data)" />
```
```
--------------------------------
### Configure TypeScript for Decorators
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/INDEX.md
Enable experimental decorators and emit decorator metadata in your TypeScript configuration file.
```json
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
```
--------------------------------
### Reactive user context
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/ProvideReactive-InjectReactive.md
Demonstrates providing and injecting a reactive user context, enabling components to access and react to changes in user authentication status and profile information.
```APIDOC
## Reactive user context
### User Context Provider
```typescript
import { Vue, Component, ProvideReactive } from 'vue-property-decorator'
interface User {
id: number
name: string
role: string
}
const userContextKey = Symbol('UserContext')
@Component
export class AppComponent extends Vue {
@ProvideReactive(userContextKey)
userContext: User | null = null
async login(credentials: any) {
const user = await this.authenticateUser(credentials)
this.userContext = user // Reactive update to all children
}
logout() {
this.userContext = null // Reactive update
}
}
```
### User Context Consumers
```typescript
import { Vue, Component, InjectReactive } from 'vue-property-decorator'
@Component
export class AuthGuard extends Vue {
@InjectReactive(userContextKey)
userContext!: User | null
get isAuthenticated() {
return this.userContext !== null
}
get userName() {
return this.userContext?.name || 'Guest'
}
}
@Component
export class UserProfile extends Vue {
@InjectReactive(userContextKey)
userContext!: User | null
get role() {
return this.userContext?.role || 'visitor'
}
}
```
```
--------------------------------
### Vue @Prop Decorator Example
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/README.md
Defines component props using the @Prop decorator. Ensure default values are defined as shown; direct assignment like `@Prop() prop = 'default value'` is not supported.
```typescript
import { Vue, Component, Prop } from 'vue-property-decorator'
@Component
export default class YourComponent extends Vue {
@Prop(Number) readonly propA: number | undefined
@Prop({ default: 'default value' }) readonly propB!: string
@Prop([String, Boolean]) readonly propC: string | boolean | undefined
}
```
```javascript
export default {
props: {
propA: {
type: Number,
},
propB: {
default: 'default value',
},
propC: {
type: [String, Boolean],
},
},
}
```
--------------------------------
### Watch Different Paths with Different Handlers and Shared Handler
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Watch.md
Demonstrates watching distinct properties with their own handlers, as well as a shared handler that triggers for changes in either property.
```typescript
@Component
export default class DebugComponent extends Vue {
count = 0
message = ''
@Watch('count')
onCountChanged(newValue: number, oldValue: number) {
console.log(`Count: ${oldValue} → ${newValue}`)
}
@Watch('message')
onMessageChanged(newValue: string, oldValue: string) {
console.log(`Message: ${oldValue} → ${newValue}`)
}
@Watch('count')
@Watch('message')
onAnyChanged() {
console.log('Something changed!')
}
}
```
--------------------------------
### Reactive State Management with Symbols
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/ProvideReactive-InjectReactive.md
Demonstrates providing and injecting a complex reactive state object using a Symbol as a key. Changes to the state object are reactive.
```typescript
const stateKey = Symbol('appState')
@Component
export class StateProvider extends Vue {
@ProvideReactive(stateKey)
state = {
theme: 'light',
language: 'en',
user: null
}
setTheme(theme: string) {
this.state.theme = theme // Reactive update
}
setLanguage(language: string) {
this.state.language = language // Reactive update
}
}
```
```typescript
@Component
export class StateConsumer extends Vue {
@InjectReactive(stateKey)
state!: any
toggleTheme() {
const newTheme = this.state.theme === 'light' ? 'dark' : 'light'
// Parent's setTheme will be called
}
get currentLanguage() {
return this.state.language // Reactive
}
}
```
--------------------------------
### Equivalent Vue Options API for InjectReactive
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/ProvideReactive-InjectReactive.md
Illustrates the equivalent Vue.js options API implementation for injecting reactive state, corresponding to the @InjectReactive decorator.
```javascript
export default {
inject: {
__reactiveInject__: { from: '__reactiveInject__', default: {} }
},
computed: {
count() {
const obj = this.__reactiveInject__
return obj ? obj.count : undefined
}
}
}
```
--------------------------------
### Provide Reactive Theme Configuration
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/ProvideReactive-InjectReactive.md
Provides a reactive theme object using @ProvideReactive. This allows for dynamic theme changes that propagate to consuming components.
```typescript
interface ThemeConfig {
primary: string
secondary: string
background: string
}
const themeKey = Symbol('Theme')
@Component
export class ThemeProvider extends Vue {
@ProvideReactive(themeKey)
theme: ThemeConfig = {
primary: '#007bff',
secondary: '#6c757d',
background: '#ffffff'
}
setTheme(newTheme: ThemeConfig) {
Object.assign(this.theme, newTheme)
}
}
```
--------------------------------
### Vue Property Decorator File Structure
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/INDEX.md
Overview of the directory structure for the vue-property-decorator library, including source, compiled output, and test directories.
```tree
vue-property-decorator/
├── src/
│ ├── decorators/
│ │ ├── Prop.ts
│ │ ├── PropSync.ts
│ │ ├── Model.ts
│ │ ├── ModelSync.ts
│ │ ├── Watch.ts
│ │ ├── Emit.ts
│ │ ├── Provide.ts
│ │ ├── Inject.ts
│ │ ├── ProvideReactive.ts
│ │ ├── InjectReactive.ts
│ │ ├── Ref.ts
│ │ └── VModel.ts
│ ├── helpers/
│ │ ├── metadata.ts (reflect-metadata type inference)
│ │ └── provideInject.ts (provide/inject implementation)
│ └── index.ts (main entry point)
├── lib/ (compiled output)
├── tests/
├── package.json
└── README.md
```
--------------------------------
### Global State Management with ProvideReactive and InjectReactive
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/INDEX.md
Implement a simplified global state management pattern using ProvideReactive and InjectReactive decorators for dependency injection.
```typescript
const stateKey = Symbol('state')
@Component
export class Provider extends Vue {
@ProvideReactive(stateKey)
state = { count: 0 }
}
@Component
export class Consumer extends Vue {
@InjectReactive(stateKey)
state!: any
}
```
--------------------------------
### Watch with Immediate and Deep Options
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Watch.md
Combine `immediate: true` and `deep: true` to trigger the watcher immediately upon component creation and to observe nested property changes.
```typescript
@Component
export default class ConfigComponent extends Vue {
config = {
theme: 'light',
settings: {
fontSize: 14
}
}
@Watch('config', { immediate: true, deep: true })
onConfigChanged(newValue: any) {
console.log('Config updated:', newValue)
this.applyConfig(newValue)
}
applyConfig(config: any) {
// Apply configuration to the component
}
}
```
--------------------------------
### TodoProvider
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/ProvideReactive-InjectReactive.md
Provides a reactive list of todos using @ProvideReactive. Includes methods to add and toggle todos.
```APIDOC
## TodoProvider
### Description
Provides a reactive list of todos using the @ProvideReactive decorator. This allows child components to inject and react to changes in the todo list.
### Methods
#### addTodo(title: string)
Adds a new todo item to the reactive list.
#### toggleTodo(id: number)
Finds a todo by its ID and toggles its `completed` status. This change is reactive across all injected instances.
### Provided Properties
- **todos** (Todo[]): A reactive array of Todo objects. The `Todo` interface includes `id`, `title`, and `completed` properties.
```
--------------------------------
### Equivalent Vue Component without Decorators
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Emit.md
Shows the equivalent Vue component logic using direct $emit calls, illustrating the verbosity compared to the @Emit decorator.
```javascript
export default {
data() {
return {
count: 0
}
},
methods: {
increment() {
this.count++;
this.$emit('increment');
},
customMethod(value) {
const result = value * 2;
this.$emit('custom-event', result, value);
return result;
}
}
}
```
--------------------------------
### Vue @Ref Decorator vs. Native $refs
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Ref.md
Illustrates the equivalence between using the @Ref decorator and the native Vue $refs computed property.
```typescript
@Component
class FormComponent extends Vue {
@Ref() readonly input!: HTMLInputElement
@Ref('button') readonly submitBtn!: HTMLButtonElement
}
```
```javascript
export default {
computed: {
input: {
cache: false,
get() {
return this.$refs.input
}
},
submitBtn: {
cache: false,
get() {
return this.$refs.button
}
}
}
}
```
--------------------------------
### Inject and Use Provided Methods
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Demonstrates how a child component can inject and call methods provided by an ancestor.
```typescript
@Component
export class ConsumerComponent extends Vue {
@Inject('store')
store!: any
useStore() {
this.store.increment()
console.log(this.store.value)
}
}
```
--------------------------------
### Emitting with Multiple Arguments
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Emit.md
All arguments passed to the decorated method are forwarded to the emitted event, after the return value (if any).
```APIDOC
## Emitting with Multiple Arguments
Original arguments are forwarded
### Usage Example
```typescript
import { Vue, Component, Emit } from 'vue-property-decorator'
@Component
export default class DataComponent extends Vue {
@Emit()
processData(id: number, name: string) {
// Original arguments are forwarded
return { processed: true }
}
}
```
```html
// Parent receives: processed result, id, and name
handle(result, id, name)" />
```
```
--------------------------------
### @Provide / @Inject
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/CONTENTS.txt
Implements non-reactive dependency injection using Symbol or string keys, with support for default values and multi-level nesting.
```APIDOC
## @Provide / @Inject
### Description
Implements non-reactive dependency injection using Symbol or string keys, with support for default values and multi-level nesting.
### Method
Decorator
### Endpoint
N/A
### Parameters
#### Path Parameters
N/A
#### Query Parameters
N/A
#### Request Body
N/A
### Request Example
N/A
### Response
#### Success Response (200)
N/A
#### Response Example
N/A
### Notes
- Non-reactive dependency injection
- Symbol and string keys, default values
- Multi-level nesting patterns
- Source file location: API-REFERENCE/Provide-Inject.md (400 lines)
```
--------------------------------
### Inject with Custom Keys
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Demonstrates injecting values that were provided using custom Symbol or string keys.
```typescript
@Component
export class ChildComponent extends Vue {
@Inject(symbolKey)
secret!: string
@Inject('apiUrl')
apiUrl!: string
}
```
--------------------------------
### Provide Methods for Injection
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Illustrates providing methods from a parent component to be used by child components.
```typescript
@Component
export class StoreComponent extends Vue {
value = 0
increment() {
this.value++
}
@Provide('store')
getStore() {
return {
value: this.value,
increment: this.increment
}
}
}
```
--------------------------------
### Emitting Without Arguments
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Emit.md
Demonstrates how to emit an event when a method has no return value and no arguments, simply to signal an action or state change.
```APIDOC
## Emitting without arguments
### Usage Example
```typescript
import { Vue, Component, Emit } from 'vue-property-decorator'
@Component
export default class SimpleComponent extends Vue {
@Emit()
notifyReady() {
// No return value, no arguments
// Simply emits 'notify-ready' event
}
}
```
```html
// Parent
```
```
--------------------------------
### Provide with Default Values
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Shows how to provide a value that can be injected by child components.
```typescript
@Component
export class ParentComponent extends Vue {
@Provide('theme')
currentTheme = 'light'
}
```
--------------------------------
### Basic reactive provide and inject
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/ProvideReactive-InjectReactive.md
Demonstrates the fundamental usage of @ProvideReactive in a parent component and @InjectReactive in a child component to share a reactive count property.
```APIDOC
## Basic reactive provide and inject
### Parent Component
```typescript
import { Vue, Component, ProvideReactive } from 'vue-property-decorator'
@Component
export class ParentComponent extends Vue {
@ProvideReactive() count = 0
increment() {
this.count++ // Child components automatically see this change
}
}
```
### Child Component
```typescript
import { Vue, Component, InjectReactive } from 'vue-property-decorator'
@Component
export class ChildComponent extends Vue {
@InjectReactive() count!: number
created() {
// Will always have the latest value from parent
console.log(this.count)
}
}
```
```
--------------------------------
### @ProvideReactive / @InjectReactive
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/CONTENTS.txt
Implements reactive dependency injection, supporting deep reactivity, theme systems, and state management with performance considerations.
```APIDOC
## @ProvideReactive / @InjectReactive
### Description
Implements reactive dependency injection, supporting deep reactivity, theme systems, and state management with performance considerations.
### Method
Decorator
### Endpoint
N/A
### Parameters
#### Path Parameters
N/A
#### Query Parameters
N/A
#### Request Body
N/A
### Request Example
N/A
### Response
#### Success Response (200)
N/A
#### Response Example
N/A
### Notes
- Reactive dependency injection implementation
- Deep reactivity, theme systems, state management
- Performance and implementation details
- Source file location: API-REFERENCE/ProvideReactive-InjectReactive.md (516 lines)
```
--------------------------------
### Vue Provide with Class Key
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/Provide-Inject.md
Illustrates using a class or constructor as the injection key for the @Provide decorator.
```typescript
import { Provide } from 'vue-property-decorator';
class Service {}
class MyComponent {
@Provide(Service)
service = new Service()
}
```
--------------------------------
### ProvideReactive with Default Values
Source: https://github.com/kaorun343/vue-property-decorator/blob/master/_autodocs/api-reference/ProvideReactive-InjectReactive.md
Shows how to provide reactive settings with default values. @InjectReactive can also specify default values if the provided value is not found.
```typescript
const settingsKey = Symbol('AppSettings')
@Component
export class SettingsProvider extends Vue {
@ProvideReactive(settingsKey)
settings = {
fontSize: 14,
darkMode: false,
notifications: true
}
updateSetting(key: string, value: any) {
this.settings[key] = value
}
}
```
```typescript
@Component
export class SettingsConsumer extends Vue {
@InjectReactive({
from: settingsKey,
default: { fontSize: 14, darkMode: false, notifications: true }
})
settings!: any
toggleDarkMode() {
this.settings.darkMode = !this.settings.darkMode
}
changeFontSize(size: number) {
this.settings.fontSize = size
}
}
```