Appearance
插件开发
本章节介绍如何开发和使用速构平台插件。
什么是插件
插件是一种扩展框架功能的方式,可以:
- 添加全局组件
- 添加全局方法或属性
- 添加全局指令
- 配置全局选项
- 注入组件选项
创建插件
插件结构
一个插件可以是一个对象,包含 install 方法:
ts
const myPlugin = {
install(app, options) {
// 插件逻辑
}
}也可以是一个函数(该函数会被当作 install 方法):
ts
function myPlugin(app, options) {
// 插件逻辑
}插件示例
示例 1:全局组件插件
ts
// plugins/global-components.ts
import Button from '../components/Button'
import Input from '../components/Input'
export default {
install(app) {
app.component('MyButton', Button)
app.component('MyInput', Input)
}
}示例 2:全局方法插件
ts
// plugins/notify.ts
export default {
install(app) {
app.config.globalProperties.$notify = (message: string, type = 'info') => {
// 通知逻辑
console.log(`[${type}] ${message}`)
}
}
}示例 3:带配置的插件
ts
// plugins/i18n.ts
export interface I18nOptions {
locale: string
messages: Record<string, Record<string, string>>
}
export default {
install(app, options: I18nOptions) {
const { locale, messages } = options
app.config.globalProperties.$t = (key: string) => {
return messages[locale]?.[key] || key
}
app.provide('i18n', {
locale,
messages,
setLocale(newLocale: string) {
// 切换语言
}
})
}
}示例 4:指令插件
ts
// plugins/directives.ts
export default {
install(app) {
// 自动聚焦指令
app.directive('focus', {
mounted(el) {
el.focus()
}
})
// 点击外部指令
app.directive('click-outside', {
mounted(el, binding) {
el._clickOutside = (event: Event) => {
if (!(el === event.target || el.contains(event.target))) {
binding.value(event)
}
}
document.addEventListener('click', el._clickOutside)
},
unmounted(el) {
document.removeEventListener('click', el._clickOutside)
}
})
}
}使用插件
全局注册
ts
// main.ts
import { createApp } from 'your-framework'
import App from './App'
import globalComponents from './plugins/global-components'
import notify from './plugins/notify'
import i18n from './plugins/i18n'
const app = createApp(App)
// 使用插件(带配置)
app.use(i18n, {
locale: 'zh-CN',
messages: {
'zh-CN': {
hello: '你好',
world: '世界'
},
'en-US': {
hello: 'Hello',
world: 'World'
}
}
})
// 使用插件(无配置)
app.use(globalComponents)
app.use(notify)
app.mount('#app')在组件中使用插件功能
vue
<template>
<div>
<MyButton @click="showNotify">点击我</MyButton>
<p>{{ $t('hello') }}</p>
<input v-focus type="text" />
</div>
</template>
<script setup lang="ts">
import { inject, getCurrentInstance } from 'your-framework'
const instance = getCurrentInstance()
const showNotify = () => {
instance?.proxy?.$notify('操作成功!', 'success')
}
// 使用 inject 获取插件提供的数据
const i18n = inject('i18n')
</script>插件开发最佳实践
1. 提供 TypeScript 类型支持
ts
// plugins/notify.ts
import type { App } from 'your-framework'
declare module 'your-framework' {
interface ComponentCustomProperties {
$notify: (message: string, type?: string) => void
}
}
export default {
install(app: App) {
// 实现
}
}2. 避免重复安装
ts
export default {
install(app) {
if (this.installed) return
this.installed = true
// 插件逻辑
}
}3. 提供插件版本信息
ts
export const PLUGIN_VERSION = '1.0.0'
export default {
install(app) {
app.config.globalProperties.$pluginVersion = PLUGIN_VERSION
}
}4. 合理使用 Provide / Inject
ts
// 插件中 provide 数据
export default {
install(app, options) {
app.provide('plugin-options', options)
}
}
// 组件中 inject 使用
import { inject } from 'your-framework'
const options = inject('plugin-options')发布插件
准备 package.json
json
{
"name": "your-plugin-name",
"version": "1.0.0",
"description": "插件描述",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"types": "dist/index.d.ts",
"files": ["dist"],
"peerDependencies": {
"your-framework": "^1.0.0"
}
}构建输出
确保输出以下格式:
- CommonJS: 用于 Node.js 环境
- ES Module: 用于现代打包工具(支持 Tree Shaking)
- TypeScript 类型声明: 提供类型支持
下一步
- 查看更多开发建议:最佳实践
- 解决开发中遇到的问题:常见问题