mod: rebuild editor
This commit is contained in:
parent
f944b4cc1a
commit
07ce954a2d
86
src/components/wang-editor/Title.vue
Normal file
86
src/components/wang-editor/Title.vue
Normal file
|
@ -0,0 +1,86 @@
|
|||
<script setup lang="ts">
|
||||
import { onBeforeMount, ref } from 'vue'
|
||||
import WangEditor from '@/components/wang-editor/WangEditor.vue'
|
||||
import KUNGalgameFooter from '@/components/KUNGalgameFooter.vue'
|
||||
|
||||
// 导入编辑帖子的 store
|
||||
import { useKUNGalgameEditStore } from '@/store/modules/edit'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
// 导入防抖函数
|
||||
import { debounce } from '@/utils/debounce'
|
||||
|
||||
const topicData = storeToRefs(useKUNGalgameEditStore())
|
||||
|
||||
// 话题标题的文字
|
||||
const topicTitle = ref('')
|
||||
// 标题的最大长度
|
||||
const maxInputLength = 40
|
||||
|
||||
onBeforeMount(() => {
|
||||
if (topicData.isSave.value) {
|
||||
topicTitle.value = topicData.title.value
|
||||
}
|
||||
})
|
||||
|
||||
// 处理用户输入
|
||||
const handelInput = () => {
|
||||
// 标题不能超过 40 字
|
||||
if (topicTitle.value.length > maxInputLength) {
|
||||
topicTitle.value = topicTitle.value.slice(0, maxInputLength)
|
||||
}
|
||||
|
||||
// 用户输入了纯空格
|
||||
if (topicTitle.value.trim() === '') {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建一个防抖处理函数
|
||||
const debouncedInput = debounce(() => {
|
||||
// 过滤 xss
|
||||
topicData.title.value = topicTitle.value
|
||||
}, 300)
|
||||
|
||||
// 调用防抖处理函数,会在延迟时间内只执行一次更新操作
|
||||
debouncedInput()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 话题的标题 -->
|
||||
<div class="title">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="请输入话题的标题(40字以内)"
|
||||
v-model="topicTitle"
|
||||
@input="handelInput"
|
||||
:maxlength="maxInputLength"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 话题的发布标题 */
|
||||
.title {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 话题标题的输入框 */
|
||||
.title input {
|
||||
color: var(--kungalgame-font-color-2);
|
||||
/* 距离外轮廓的距离 */
|
||||
padding: 7px;
|
||||
/* 内边距盒子 */
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
/* 标题输入字体大小 */
|
||||
font-size: 40px;
|
||||
border: none;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* 标题输入框 focus 之后的样式 */
|
||||
.title input:focus {
|
||||
box-shadow: 0px 0px 5px var(--kungalgame-blue-4);
|
||||
}
|
||||
</style>
|
|
@ -2,14 +2,32 @@
|
|||
编辑器实例共用组件
|
||||
-->
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
defineAsyncComponent,
|
||||
onBeforeMount,
|
||||
onBeforeUnmount,
|
||||
ref,
|
||||
shallowRef,
|
||||
} from 'vue'
|
||||
// 编辑器本体配置
|
||||
import '@wangeditor/editor/dist/css/style.css'
|
||||
import '@/styles/editor/editor.scss'
|
||||
import { IDomEditor } from '@wangeditor/editor'
|
||||
import { onBeforeMount, onBeforeUnmount, ref, shallowRef } from 'vue'
|
||||
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
|
||||
import { IDomEditor, IEditorConfig } from '@wangeditor/editor'
|
||||
import { Editor } from '@wangeditor/editor-for-vue'
|
||||
|
||||
// 编辑器菜单配置
|
||||
import { IToolbarConfig } from '@wangeditor/editor'
|
||||
import { Toolbar } from '@wangeditor/editor-for-vue'
|
||||
|
||||
// 导入标题
|
||||
const Title = defineAsyncComponent(
|
||||
() => import('@/components/wang-editor/Title.vue')
|
||||
)
|
||||
|
||||
// 导入编辑帖子的 store
|
||||
import { useKUNGalgameEditStore } from '@/store/modules/edit'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
// 导入过滤 xss 的工具
|
||||
import DOMPurify from 'dompurify'
|
||||
// 导入防抖函数
|
||||
|
@ -18,7 +36,12 @@ import { debounce } from '@/utils/debounce'
|
|||
const topicData = storeToRefs(useKUNGalgameEditStore())
|
||||
|
||||
// 定义父组件传参
|
||||
const props = defineProps(['height', 'isShowToolbar', 'isShowAdvance'])
|
||||
const props = defineProps<{
|
||||
height: number
|
||||
isShowToolbar: boolean
|
||||
isShowAdvance: boolean
|
||||
isShowTitle: boolean
|
||||
}>()
|
||||
|
||||
// 自定义编辑区域高度
|
||||
const editorHeight = `height: ${props.height}px`
|
||||
|
@ -32,7 +55,7 @@ const valueHtml = ref('')
|
|||
const textCount = ref(0)
|
||||
|
||||
// 编辑器相关配置
|
||||
const editorConfig = {
|
||||
const editorConfig: Partial<IEditorConfig> = {
|
||||
placeholder: 'Moe Moe Moe!',
|
||||
readOnly: false,
|
||||
MENU_CONF: {
|
||||
|
@ -53,7 +76,18 @@ const editorConfig = {
|
|||
},
|
||||
}
|
||||
|
||||
const handleCreated = (editor: IDomEditor) => {}
|
||||
const keys: string[] = []
|
||||
|
||||
// 工具栏相关配置
|
||||
const toolbarConfig: Partial<IToolbarConfig> = {
|
||||
excludeKeys: ['uploadVideo'].concat(keys),
|
||||
}
|
||||
|
||||
const handleCreated = (editor: IDomEditor) => {
|
||||
console.log(editor.getAllMenuKeys())
|
||||
|
||||
editorRef.value = editor // 记录 editor 实例,重要!
|
||||
}
|
||||
|
||||
// 挂载之前载入数据,如果不保存,则不载入
|
||||
onBeforeMount(() => {
|
||||
|
@ -92,9 +126,11 @@ const handleChange = (editor: IDomEditor) => {
|
|||
<Toolbar
|
||||
class="toolbar-container"
|
||||
:editor="editorRef"
|
||||
:defaultConfig="toolbarConfig"
|
||||
:mode="$props.isShowAdvance ? 'default' : 'simple'"
|
||||
v-show="props.isShowToolbar"
|
||||
/>
|
||||
<Title />
|
||||
<Editor
|
||||
:style="editorHeight"
|
||||
v-model="valueHtml"
|
||||
|
@ -109,16 +145,11 @@ const handleChange = (editor: IDomEditor) => {
|
|||
<style lang="scss" scoped>
|
||||
/* 编辑器的样式 */
|
||||
.editor—wrapper {
|
||||
/* 编辑器的 border */
|
||||
border: 1px solid var(--kungalgame-blue-4);
|
||||
box-sizing: border-box;
|
||||
/* 编辑器的宽度 */
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
z-index: 1008; /* 按需定义 */
|
||||
}
|
||||
.toolbar-container {
|
||||
border-bottom: 1px solid var(--kungalgame-blue-4);
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.count {
|
||||
|
@ -128,7 +159,7 @@ const handleChange = (editor: IDomEditor) => {
|
|||
align-items: center;
|
||||
justify-content: end;
|
||||
color: var(--kungalgame-font-color-0);
|
||||
background-color: var(--kungalgame-white);
|
||||
background-color: var(--kungalgame-white-9);
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
62
src/components/wang-editor/key.js
Normal file
62
src/components/wang-editor/key.js
Normal file
|
@ -0,0 +1,62 @@
|
|||
;[
|
||||
'bold',
|
||||
'underline',
|
||||
'italic',
|
||||
'through',
|
||||
'code',
|
||||
'sub',
|
||||
'sup',
|
||||
'clearStyle',
|
||||
'color',
|
||||
'bgColor',
|
||||
'fontSize',
|
||||
'fontFamily',
|
||||
'indent',
|
||||
'delIndent',
|
||||
'justifyLeft',
|
||||
'justifyRight',
|
||||
'justifyCenter',
|
||||
'justifyJustify',
|
||||
'lineHeight',
|
||||
'insertImage',
|
||||
'deleteImage',
|
||||
'editImage',
|
||||
'viewImageLink',
|
||||
'imageWidth30',
|
||||
'imageWidth50',
|
||||
'imageWidth100',
|
||||
'divider',
|
||||
'emotion',
|
||||
'insertLink',
|
||||
'editLink',
|
||||
'unLink',
|
||||
'viewLink',
|
||||
'codeBlock',
|
||||
'blockquote',
|
||||
'headerSelect',
|
||||
'header1',
|
||||
'header2',
|
||||
'header3',
|
||||
'header4',
|
||||
'header5',
|
||||
'todo',
|
||||
'redo',
|
||||
'undo',
|
||||
'fullScreen',
|
||||
'enter',
|
||||
'bulletedList',
|
||||
'numberedList',
|
||||
'insertTable',
|
||||
'deleteTable',
|
||||
'insertTableRow',
|
||||
'deleteTableRow',
|
||||
'insertTableCol',
|
||||
'deleteTableCol',
|
||||
'tableHeader',
|
||||
'tableFullWidth',
|
||||
'insertVideo',
|
||||
'uploadVideo',
|
||||
'editVideoSize',
|
||||
'uploadImage',
|
||||
'codeSelectLang',
|
||||
]
|
|
@ -5,7 +5,7 @@ import 'animate.css'
|
|||
|
||||
import { currBackground } from '@/hooks/useBackgroundPicture'
|
||||
|
||||
import KUNGalgameTopBar from '@/components/TopBar/KUNGalgameTopBar.vue'
|
||||
import KUNGalgameTopBar from '@/components/top-bar/KUNGalgameTopBar.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -29,12 +29,12 @@ u {
|
|||
|
||||
:root {
|
||||
/* textarea - css vars */
|
||||
--w-e-textarea-bg-color: var(--kungalgame-white);
|
||||
--w-e-textarea-bg-color: var(--kungalgame-white-9);
|
||||
--w-e-textarea-color: var(--kungalgame-font-color-3);
|
||||
--w-e-textarea-border-color: var(--kungalgame-blue-1);
|
||||
--w-e-textarea-slight-border-color: var(--kungalgame-blue-4);
|
||||
--w-e-textarea-slight-color: var(--kungalgame-font-color-0);
|
||||
--w-e-textarea-slight-bg-color: var(--kungalgame-white);
|
||||
--w-e-textarea-slight-bg-color: var(--kungalgame-white-9);
|
||||
--w-e-textarea-selected-border-color: var(--kungalgame-blue-1);
|
||||
/* 选中的元素,如选中了分割线 */
|
||||
--w-e-textarea-handler-bg-color: var(--kungalgame-blue-4);
|
||||
|
@ -42,9 +42,9 @@ u {
|
|||
|
||||
/* toolbar - css vars */
|
||||
--w-e-toolbar-color: var(--kungalgame-font-color-1);
|
||||
--w-e-toolbar-bg-color: var(--kungalgame-white);
|
||||
--w-e-toolbar-bg-color: var(--kungalgame-trans-blue-0);
|
||||
--w-e-toolbar-active-color: var(--kungalgame-font-color-3);
|
||||
--w-e-toolbar-active-bg-color: var(--kungalgame-white);
|
||||
--w-e-toolbar-active-bg-color: var(--kungalgame-trans-blue-1);
|
||||
--w-e-toolbar-disabled-color: var(--kungalgame-red-4);
|
||||
--w-e-toolbar-border-color: var(--kungalgame-blue-4);
|
||||
|
||||
|
|
|
@ -1,80 +1,22 @@
|
|||
<script setup lang="ts">
|
||||
import { onBeforeMount, ref } from 'vue'
|
||||
import WangEditor from '@/components/WangEditor.vue'
|
||||
import WangEditor from '@/components/wang-editor/WangEditor.vue'
|
||||
import Tags from './components/Tags.vue'
|
||||
import Footer from './components/Footer.vue'
|
||||
import KUNGalgameFooter from '@/components/KUNGalgameFooter.vue'
|
||||
|
||||
// 导入编辑帖子的 store
|
||||
import { useKUNGalgameEditStore } from '@/store/modules/edit'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
// 导入防抖函数
|
||||
import { debounce } from '@/utils/debounce'
|
||||
|
||||
const topicData = storeToRefs(useKUNGalgameEditStore())
|
||||
|
||||
// 话题标题的文字
|
||||
const topicTitle = ref('')
|
||||
// 标题的最大长度
|
||||
const maxInputLength = 40
|
||||
|
||||
onBeforeMount(() => {
|
||||
if (topicData.isSave.value) {
|
||||
topicTitle.value = topicData.title.value
|
||||
}
|
||||
})
|
||||
|
||||
// 处理用户输入
|
||||
const handelInput = () => {
|
||||
// 标题不能超过 40 字
|
||||
if (topicTitle.value.length > maxInputLength) {
|
||||
topicTitle.value = topicTitle.value.slice(0, maxInputLength)
|
||||
}
|
||||
|
||||
// 用户输入了纯空格
|
||||
if (topicTitle.value.trim() === '') {
|
||||
return
|
||||
}
|
||||
|
||||
// 创建一个防抖处理函数
|
||||
const debouncedInput = debounce(() => {
|
||||
// 过滤 xss
|
||||
topicData.title.value = topicTitle.value
|
||||
}, 300)
|
||||
|
||||
// 调用防抖处理函数,会在延迟时间内只执行一次更新操作
|
||||
debouncedInput()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="root">
|
||||
<!-- 内容区容器 -->
|
||||
<div class="container">
|
||||
<!-- 内容区容器 -->
|
||||
<div class="content">
|
||||
<!-- 内容区的头部 -->
|
||||
<div class="header">
|
||||
<!-- 话题的标题 -->
|
||||
<div class="title">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="请输入话题的标题(40字以内)"
|
||||
v-model="topicTitle"
|
||||
@input="handelInput"
|
||||
:maxlength="maxInputLength"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 编辑器 -->
|
||||
<WangEditor
|
||||
class="editor"
|
||||
:height="400"
|
||||
:isShowToolbar="true"
|
||||
:isShowAdvance="true"
|
||||
:isShowTitle="true"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 内容区的底部 -->
|
||||
<div class="content-footer">
|
||||
|
@ -92,10 +34,6 @@ const handelInput = () => {
|
|||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.root {
|
||||
height: 100vh;
|
||||
min-height: 1200px;
|
||||
|
@ -117,39 +55,6 @@ const handelInput = () => {
|
|||
padding: 10px;
|
||||
}
|
||||
|
||||
/* 容器的顶部 */
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 话题的发布标题 */
|
||||
.title {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 话题标题的输入框 */
|
||||
.title input {
|
||||
color: var(--kungalgame-font-color-2);
|
||||
/* 距离外轮廓的距离 */
|
||||
padding: 7px;
|
||||
/* 内边距盒子 */
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
/* 标题输入字体大小 */
|
||||
font-size: 40px;
|
||||
border: 1px solid var(--kungalgame-blue-4);
|
||||
background-color: var(--kungalgame-white);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* 标题输入框 focus 之后的样式 */
|
||||
.title input:focus {
|
||||
box-shadow: 0px 0px 5px var(--kungalgame-blue-4);
|
||||
}
|
||||
|
||||
.content-footer {
|
||||
/* 距离内容区的距离 */
|
||||
margin-top: 17px;
|
||||
|
|
|
@ -9,7 +9,7 @@ import 'animate.css'
|
|||
import { defineAsyncComponent } from 'vue'
|
||||
|
||||
// 导入编辑器
|
||||
import WangEditor from '@/components/WangEditor.vue'
|
||||
import WangEditor from '@/components/wang-editor/WangEditor.vue'
|
||||
|
||||
// 异步导入话题标签
|
||||
const Tags = defineAsyncComponent(
|
||||
|
|
Loading…
Reference in a new issue