format: apply repo prettier (3.8.1) to the folded skills tree
963 markdown files reformatted with the repository's pinned prettier so pnpm format:check covers the folded tree like every other repo file. The formatter's embedded-language pass also normalized code fences (TS semicolons, closed HTML tags in examples, lowercased CSS hex colors, one renumbered list that skipped an index). Alphanumeric token deltas vs the fold commit were audited file-by-file; all are formatter-equivalent markup normalizations plus the four sanitized skills.
This commit is contained in:
+64
-60
@@ -18,76 +18,74 @@ A Vue plugin must be either an object with an `install()` method, or a function
|
||||
|
||||
```typescript
|
||||
// plugins/myPlugin.ts
|
||||
import type { App } from 'vue'
|
||||
import type { App } from 'vue';
|
||||
|
||||
interface PluginOptions {
|
||||
prefix?: string
|
||||
debug?: boolean
|
||||
prefix?: string;
|
||||
debug?: boolean;
|
||||
}
|
||||
|
||||
const myPlugin = {
|
||||
install(app: App, options: PluginOptions = {}) {
|
||||
const { prefix = 'my', debug = false } = options
|
||||
const { prefix = 'my', debug = false } = options;
|
||||
|
||||
if (debug) {
|
||||
console.log('Installing myPlugin with prefix:', prefix)
|
||||
console.log('Installing myPlugin with prefix:', prefix);
|
||||
}
|
||||
|
||||
app.provide('myPlugin', { prefix })
|
||||
}
|
||||
}
|
||||
app.provide('myPlugin', { prefix });
|
||||
},
|
||||
};
|
||||
|
||||
export default myPlugin
|
||||
export default myPlugin;
|
||||
|
||||
// Usage
|
||||
app.use(myPlugin, { prefix: 'custom', debug: true })
|
||||
app.use(myPlugin, { prefix: 'custom', debug: true });
|
||||
```
|
||||
|
||||
### Function as install (alternative)
|
||||
|
||||
```typescript
|
||||
// plugins/simplePlugin.ts
|
||||
import type { App } from 'vue'
|
||||
import type { App } from 'vue';
|
||||
|
||||
function simplePlugin(app: App, options?: { message: string }) {
|
||||
app.config.globalProperties.$greet = () => {
|
||||
return options?.message ?? 'Hello!'
|
||||
}
|
||||
return options?.message ?? 'Hello!';
|
||||
};
|
||||
}
|
||||
|
||||
export default simplePlugin
|
||||
export default simplePlugin;
|
||||
|
||||
// Usage
|
||||
app.use(simplePlugin, { message: 'Welcome!' })
|
||||
app.use(simplePlugin, { message: 'Welcome!' });
|
||||
```
|
||||
|
||||
### Factory function pattern (most flexible)
|
||||
|
||||
```typescript
|
||||
// plugins/configuredPlugin.ts
|
||||
import type { App, Plugin } from 'vue'
|
||||
import type { App, Plugin } from 'vue';
|
||||
|
||||
interface I18nOptions {
|
||||
locale: string
|
||||
messages: Record<string, Record<string, string>>
|
||||
fallbackLocale?: string
|
||||
locale: string;
|
||||
messages: Record<string, Record<string, string>>;
|
||||
fallbackLocale?: string;
|
||||
}
|
||||
|
||||
export function createI18n(options: I18nOptions): Plugin {
|
||||
return {
|
||||
install(app: App) {
|
||||
// Options are captured in closure - no need to pass through app.use()
|
||||
const { locale, messages, fallbackLocale = 'en' } = options
|
||||
const { locale, messages, fallbackLocale = 'en' } = options;
|
||||
|
||||
const translate = (key: string): string => {
|
||||
return messages[locale]?.[key]
|
||||
?? messages[fallbackLocale]?.[key]
|
||||
?? key
|
||||
}
|
||||
return messages[locale]?.[key] ?? messages[fallbackLocale]?.[key] ?? key;
|
||||
};
|
||||
|
||||
app.provide('i18n', { translate, locale })
|
||||
}
|
||||
}
|
||||
app.provide('i18n', { translate, locale });
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Usage - options passed to factory, not app.use()
|
||||
@@ -95,11 +93,11 @@ const i18n = createI18n({
|
||||
locale: 'fr',
|
||||
messages: {
|
||||
en: { hello: 'Hello' },
|
||||
fr: { hello: 'Bonjour' }
|
||||
}
|
||||
})
|
||||
fr: { hello: 'Bonjour' },
|
||||
},
|
||||
});
|
||||
|
||||
app.use(i18n) // No second argument needed
|
||||
app.use(i18n); // No second argument needed
|
||||
```
|
||||
|
||||
## Common Plugin Capabilities
|
||||
@@ -108,31 +106,31 @@ app.use(i18n) // No second argument needed
|
||||
const fullFeaturedPlugin = {
|
||||
install(app: App, options: PluginOptions) {
|
||||
// 1. Register global components
|
||||
app.component('MyButton', MyButtonComponent)
|
||||
app.component('MyInput', MyInputComponent)
|
||||
app.component('MyButton', MyButtonComponent);
|
||||
app.component('MyInput', MyInputComponent);
|
||||
|
||||
// 2. Register global directives
|
||||
app.directive('focus', focusDirective)
|
||||
app.directive('focus', focusDirective);
|
||||
|
||||
// 3. Provide injectable values (recommended)
|
||||
app.provide('pluginConfig', options)
|
||||
app.provide('pluginConfig', options);
|
||||
|
||||
// 4. Add global properties (use sparingly)
|
||||
app.config.globalProperties.$myHelper = helperFunction
|
||||
app.config.globalProperties.$myHelper = helperFunction;
|
||||
|
||||
// 5. Add global mixins (avoid if possible)
|
||||
app.mixin({
|
||||
created() {
|
||||
// Runs for every component
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
|
||||
// 6. Custom error handling
|
||||
app.config.errorHandler = (err, vm, info) => {
|
||||
// Handle errors
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## TypeScript: Plugin Type
|
||||
@@ -140,25 +138,25 @@ const fullFeaturedPlugin = {
|
||||
Use the `Plugin` type for proper typing:
|
||||
|
||||
```typescript
|
||||
import type { App, Plugin } from 'vue'
|
||||
import type { App, Plugin } from 'vue';
|
||||
|
||||
// With options type parameter
|
||||
interface MyOptions {
|
||||
apiKey: string
|
||||
apiKey: string;
|
||||
}
|
||||
|
||||
const myPlugin: Plugin<[MyOptions]> = {
|
||||
install(app: App, options: MyOptions) {
|
||||
// options is typed as MyOptions
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Without options
|
||||
const simplePlugin: Plugin = {
|
||||
install(app: App) {
|
||||
// No options expected
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Common Mistakes
|
||||
@@ -168,16 +166,22 @@ const simplePlugin: Plugin = {
|
||||
```typescript
|
||||
// BAD - This is just an object, not a plugin
|
||||
const notAPlugin = {
|
||||
doSomething() { /* ... */ }
|
||||
}
|
||||
app.use(notAPlugin) // Error or silent failure
|
||||
doSomething() {
|
||||
/* ... */
|
||||
},
|
||||
};
|
||||
app.use(notAPlugin); // Error or silent failure
|
||||
|
||||
// GOOD
|
||||
const actualPlugin = {
|
||||
install(app) {
|
||||
app.provide('service', { doSomething() { /* ... */ } })
|
||||
}
|
||||
}
|
||||
app.provide('service', {
|
||||
doSomething() {
|
||||
/* ... */
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Forgetting to use the app parameter
|
||||
@@ -186,18 +190,18 @@ const actualPlugin = {
|
||||
// BAD - Does nothing
|
||||
const uselessPlugin = {
|
||||
install(app, options) {
|
||||
const service = createService(options)
|
||||
const service = createService(options);
|
||||
// Forgot to register anything with app!
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// GOOD
|
||||
const usefulPlugin = {
|
||||
install(app, options) {
|
||||
const service = createService(options)
|
||||
app.provide('service', service) // Actually makes it available
|
||||
}
|
||||
}
|
||||
const service = createService(options);
|
||||
app.provide('service', service); // Actually makes it available
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
Reference in New Issue
Block a user