@mario9/tiptap-editor 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -1
- package/package.json +8 -9
package/README.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
基于 Tiptap + Vue 3 的富文本编辑器组件,支持 Feature Plugin 架构,消费方可按需引入功能模块实现 tree-shaking。
|
|
4
4
|
|
|
5
|
+
## 效果预览
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
5
13
|
## 安装
|
|
6
14
|
|
|
7
15
|
```bash
|
|
@@ -57,6 +65,59 @@ const content = ref('')
|
|
|
57
65
|
</template>
|
|
58
66
|
```
|
|
59
67
|
|
|
68
|
+
## 常见场景
|
|
69
|
+
|
|
70
|
+
### 最小化配置
|
|
71
|
+
|
|
72
|
+
只引入用到的 feature,未引入的模块不会进入消费方 bundle:
|
|
73
|
+
|
|
74
|
+
```vue
|
|
75
|
+
<TiptapEditor
|
|
76
|
+
v-model="content"
|
|
77
|
+
:features="[UndoRedoFeature, TextStyleFeature]"
|
|
78
|
+
/>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+

|
|
82
|
+
|
|
83
|
+
### 只读模式
|
|
84
|
+
|
|
85
|
+
```vue
|
|
86
|
+
<TiptapEditor v-model="content" :readonly="true" />
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`readonly` 时工具栏隐藏,编辑器不可编辑,图片控件仅保留下载,数学公式不可点击编辑。
|
|
90
|
+
|
|
91
|
+
### 获取 / 设置内容
|
|
92
|
+
|
|
93
|
+
`v-model` 绑定的是 HTML 字符串,直接读写即可:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
const content = ref('<p>初始内容</p>')
|
|
97
|
+
|
|
98
|
+
// 读取当前内容
|
|
99
|
+
console.log(content.value)
|
|
100
|
+
|
|
101
|
+
// 程序化设置内容
|
|
102
|
+
content.value = '<h1>新标题</h1><p>新内容</p>'
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 工具栏顺序
|
|
106
|
+
|
|
107
|
+
`features` 数组的顺序即工具栏按钮的顺序,用 `SeparatorFeature` 插入分隔符:
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
:features="[
|
|
111
|
+
UndoRedoFeature, // 撤销重做
|
|
112
|
+
SeparatorFeature, // ——
|
|
113
|
+
TextStyleFeature, // 粗体/斜体/下划线/删除线/链接
|
|
114
|
+
TextAlignFeature, // 对齐
|
|
115
|
+
SeparatorFeature, // ——
|
|
116
|
+
TableFeature, // 表格
|
|
117
|
+
ImageFeature, // 图片
|
|
118
|
+
]"
|
|
119
|
+
```
|
|
120
|
+
|
|
60
121
|
## Props
|
|
61
122
|
|
|
62
123
|
| 属性 | 类型 | 默认值 | 说明 |
|
|
@@ -102,7 +163,9 @@ const myUpload: UploadFn = async (file) => {
|
|
|
102
163
|
|
|
103
164
|
## 自定义 Feature Plugin
|
|
104
165
|
|
|
105
|
-
实现 `FeaturePlugin`
|
|
166
|
+
实现 `FeaturePlugin` 接口即可创建自定义功能插件。
|
|
167
|
+
|
|
168
|
+
### 基础示例
|
|
106
169
|
|
|
107
170
|
```typescript
|
|
108
171
|
import type { FeaturePlugin } from '@mario9/tiptap-editor'
|
|
@@ -118,6 +181,55 @@ export const MyFeature: FeaturePlugin = {
|
|
|
118
181
|
}
|
|
119
182
|
```
|
|
120
183
|
|
|
184
|
+
### 含浮层和状态共享的完整示例
|
|
185
|
+
|
|
186
|
+
如果 feature 需要一个持久渲染的浮层(如对话框),并且工具栏按钮需要触发它,使用 `controlComponent` + `ctx.provide`:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import { ref, defineComponent, h } from 'vue'
|
|
190
|
+
import type { FeaturePlugin } from '@mario9/tiptap-editor'
|
|
191
|
+
import MyExtension from './MyExtension'
|
|
192
|
+
import MyToolbarButton from './MyToolbarButton.vue'
|
|
193
|
+
import MyControlPanel from './MyControlPanel.vue'
|
|
194
|
+
|
|
195
|
+
export const MyFeature: FeaturePlugin = {
|
|
196
|
+
name: 'my-feature',
|
|
197
|
+
|
|
198
|
+
install(ctx) {
|
|
199
|
+
// per-instance 状态(多个编辑器实例互不干扰)
|
|
200
|
+
const isOpen = ref(false)
|
|
201
|
+
const openPanel = () => { isOpen.value = true }
|
|
202
|
+
|
|
203
|
+
// 通过 provide 共享给工具栏按钮
|
|
204
|
+
ctx.provide('openMyPanel', openPanel)
|
|
205
|
+
|
|
206
|
+
// 闭包组件,捕获 per-instance 状态
|
|
207
|
+
const ControlWrapper = defineComponent({
|
|
208
|
+
setup: () => () => h(MyControlPanel, {
|
|
209
|
+
visible: isOpen.value,
|
|
210
|
+
'onUpdate:visible': (v: boolean) => { isOpen.value = v },
|
|
211
|
+
}),
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
extensions: [MyExtension],
|
|
216
|
+
controlComponent: ControlWrapper, // 渲染在编辑器内容区之后
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
|
|
220
|
+
toolbarComponent: MyToolbarButton,
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
工具栏按钮通过 `inject` 获取共享函数:
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
// MyToolbarButton.vue
|
|
228
|
+
import { inject } from 'vue'
|
|
229
|
+
|
|
230
|
+
const openMyPanel = inject<() => void>('openMyPanel')
|
|
231
|
+
```
|
|
232
|
+
|
|
121
233
|
`install()` 接收 `PluginInstallContext`(含 `readonly`、`provide`、`upload`),返回 `{ extensions, controlComponent? }`。
|
|
122
234
|
|
|
123
235
|
## 内置功能(始终启用)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mario9/tiptap-editor",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "基于 Tiptap + Vue 3 的富文本编辑器组件。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/tiptap-editor.umd.cjs",
|
|
@@ -43,6 +43,12 @@
|
|
|
43
43
|
"files": [
|
|
44
44
|
"dist"
|
|
45
45
|
],
|
|
46
|
+
"scripts": {
|
|
47
|
+
"dev": "vite",
|
|
48
|
+
"build": "vue-tsc -b && vite build",
|
|
49
|
+
"build:lib": "vue-tsc -b && vite build --mode lib",
|
|
50
|
+
"preview": "vite preview"
|
|
51
|
+
},
|
|
46
52
|
"peerDependencies": {
|
|
47
53
|
"@tiptap/core": "^3.22.5",
|
|
48
54
|
"@tiptap/extension-bubble-menu": "^3.22.5",
|
|
@@ -67,7 +73,6 @@
|
|
|
67
73
|
"lowlight": "^3.3.0",
|
|
68
74
|
"vue": "^3.5.0"
|
|
69
75
|
},
|
|
70
|
-
"dependencies": {},
|
|
71
76
|
"devDependencies": {
|
|
72
77
|
"@types/node": "^24.10.1",
|
|
73
78
|
"@vitejs/plugin-vue": "^6.0.2",
|
|
@@ -79,11 +84,5 @@
|
|
|
79
84
|
"vite": "^7.3.1",
|
|
80
85
|
"vite-plugin-dts": "^4.5.4",
|
|
81
86
|
"vue-tsc": "^3.1.5"
|
|
82
|
-
},
|
|
83
|
-
"scripts": {
|
|
84
|
-
"dev": "vite",
|
|
85
|
-
"build": "vue-tsc -b && vite build",
|
|
86
|
-
"build:lib": "vue-tsc -b && vite build --mode lib",
|
|
87
|
-
"preview": "vite preview"
|
|
88
87
|
}
|
|
89
|
-
}
|
|
88
|
+
}
|