'admin-22.04.28:wangeditor替换成v5,适配深色模式'

This commit is contained in:
lyt 2022-04-28 19:39:44 +08:00
parent 35fdb164e9
commit 9991d931a2
7 changed files with 1334 additions and 406 deletions

View File

@ -17,6 +17,7 @@
- 🎯 优化 登录页添加 `NextLoading.start()` 方法,防止第一次进入界面时出现短暂空白 - 🎯 优化 登录页添加 `NextLoading.start()` 方法,防止第一次进入界面时出现短暂空白
- 🎯 优化 地址栏有参数退出登录,再次登录不跳之前界面问题 `src/layout/navBars/breadcrumb/user.vue` - 🎯 优化 地址栏有参数退出登录,再次登录不跳之前界面问题 `src/layout/navBars/breadcrumb/user.vue`
- 🎯 优化 `SvgIcon` 组件,防止 `开启 Tagsview 图标` 时,`tagsView 右键菜单关闭` 报错问题 - 🎯 优化 `SvgIcon` 组件,防止 `开启 Tagsview 图标` 时,`tagsView 右键菜单关闭` 报错问题
- 🎯 优化 [wangEditor](https://www.wangeditor.com/) 更新到 v5[vue3 版本线上示例中 wangeditor 富文本编辑器 demo 实例,无法换行#I5565B](https://gitee.com/lyt-top/vue-next-admin/issues/I5565B),感谢@[jenchih](https://gitee.com/jenchih)
- 🎉 新增 [vuex](https://vuex.vuejs.org/) 替换成 [pinia](https://pinia.vuejs.org/getting-started.html) - 🎉 新增 [vuex](https://vuex.vuejs.org/) 替换成 [pinia](https://pinia.vuejs.org/getting-started.html)
- 🎉 新增 tagsView 支持自定义 tagsView 名称(文章详情时有用),前往体验:[路由参数/普通路由](https://lyt-top.gitee.io/vue-next-admin-preview/#/params/common) - 🎉 新增 tagsView 支持自定义 tagsView 名称(文章详情时有用),前往体验:[路由参数/普通路由](https://lyt-top.gitee.io/vue-next-admin-preview/#/params/common)
- 🐞 修复 适配 `"element-plus": "^2.1.9"` 版本 - 🐞 修复 适配 `"element-plus": "^2.1.9"` 版本

1514
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,8 @@
}, },
"dependencies": { "dependencies": {
"@element-plus/icons-vue": "^1.1.4", "@element-plus/icons-vue": "^1.1.4",
"axios": "^0.27.1", "@wangeditor/editor": "^5.0.1",
"axios": "^0.27.2",
"countup.js": "^2.1.0", "countup.js": "^2.1.0",
"cropperjs": "^1.5.12", "cropperjs": "^1.5.12",
"echarts": "^5.3.2", "echarts": "^5.3.2",
@ -31,11 +32,10 @@
"vue-clipboard3": "^2.0.0", "vue-clipboard3": "^2.0.0",
"vue-grid-layout": "^3.0.0-beta1", "vue-grid-layout": "^3.0.0-beta1",
"vue-i18n": "^9.1.9", "vue-i18n": "^9.1.9",
"vue-router": "^4.0.14", "vue-router": "^4.0.14"
"wangeditor": "^4.7.15"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^17.0.27", "@types/node": "^17.0.29",
"@types/nprogress": "^0.2.0", "@types/nprogress": "^0.2.0",
"@types/sortablejs": "^1.10.7", "@types/sortablejs": "^1.10.7",
"@typescript-eslint/eslint-plugin": "^5.21.0", "@typescript-eslint/eslint-plugin": "^5.21.0",
@ -49,7 +49,7 @@
"sass": "^1.51.0", "sass": "^1.51.0",
"sass-loader": "^12.6.0", "sass-loader": "^12.6.0",
"typescript": "^4.6.3", "typescript": "^4.6.3",
"vite": "^2.9.5", "vite": "^2.9.6",
"vue-eslint-parser": "^8.3.0" "vue-eslint-parser": "^8.3.0"
}, },
"browserslist": [ "browserslist": [

View File

@ -1,12 +1,15 @@
<template> <template>
<div class="editor-container"> <div class="editor-container">
<div :id="id"></div> <div id="editor-toolbar"></div>
<div :id="id" :style="{ height }"></div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { toRefs, reactive, onMounted, watch, defineComponent } from 'vue'; import { toRefs, reactive, onMounted, watch, defineComponent } from 'vue';
import wangeditor from 'wangeditor'; import { createEditor, createToolbar, IEditorConfig, IToolbarConfig, IDomEditor } from '@wangeditor/editor';
import '@wangeditor/editor/dist/css/style.css';
import { toolbarKeys } from './toolbar';
// //
interface WangeditorState { interface WangeditorState {
@ -31,33 +34,61 @@ export default defineComponent({
type: String, type: String,
default: () => '请输入内容', default: () => '请输入内容',
}, },
// //
//
// https://v3.cn.vuejs.org/guide/migration/v-model.html#%E8%BF%81%E7%A7%BB%E7%AD%96%E7%95%A5 // https://v3.cn.vuejs.org/guide/migration/v-model.html#%E8%BF%81%E7%A7%BB%E7%AD%96%E7%95%A5
modelValue: String, modelValue: String,
// https://www.wangeditor.com/v5/getting-started.html#mode-%E6%A8%A1%E5%BC%8F
// <default|simple> default
mode: {
type: String,
default: () => 'default',
},
//
height: {
type: String,
default: () => '310px',
},
}, },
setup(props, { emit }) { setup(props, { emit }) {
const state = reactive<WangeditorState>({ const state = reactive<WangeditorState>({
editor: null, editor: null,
}); });
// //
// https://doc.wangeditor.com/ const wangeditorConfig = () => {
const initWangeditor = () => { const editorConfig: Partial<IEditorConfig> = { MENU_CONF: {} };
state.editor = new wangeditor(`#${props.id}`); props.isDisable ? (editorConfig.readOnly = true) : (editorConfig.readOnly = false);
state.editor.config.zIndex = 1; editorConfig.placeholder = props.placeholder;
state.editor.config.placeholder = props.placeholder; editorConfig.onChange = (editor: IDomEditor) => {
state.editor.config.uploadImgShowBase64 = true; // console.log('content', editor.children);
state.editor.config.showLinkImg = false; // console.log('html', editor.getHtml());
onWangeditorChange(); emit('update:modelValue', editor.getHtml());
state.editor.create();
state.editor.txt.html(props.modelValue);
props.isDisable ? state.editor.disable() : state.editor.enable();
};
//
const onWangeditorChange = () => {
state.editor.config.onchange = (html: string) => {
emit('update:modelValue', html);
}; };
(<any>editorConfig).MENU_CONF['uploadImage'] = {
base64LimitSize: 10 * 1024 * 1024,
};
return editorConfig;
};
//
const toolbarConfig = () => {
const toolbarConfig: Partial<IToolbarConfig> = {};
toolbarConfig.toolbarKeys = toolbarKeys;
return toolbarConfig;
};
//
// https://www.wangeditor.com/
const initWangeditor = () => {
state.editor = createEditor({
html: props.modelValue,
selector: `#${props.id}`,
config: wangeditorConfig(),
mode: props.mode,
});
createToolbar({
editor: state.editor,
selector: '#editor-toolbar',
mode: props.mode,
config: toolbarConfig(),
});
}; };
// //
onMounted(() => { onMounted(() => {
@ -68,7 +99,8 @@ export default defineComponent({
watch( watch(
() => props.modelValue, () => props.modelValue,
(value) => { (value) => {
state.editor.txt.html(value); state.editor.clear();
state.editor.dangerouslyInsertHtml(value);
} }
); );
return { return {

View File

@ -0,0 +1,60 @@
/**
*
*/
export const toolbarKeys = [
'headerSelect',
'blockquote',
'|',
'bold',
'underline',
'italic',
{
key: 'group-more-style',
title: '更多',
iconSvg:
'<svg viewBox="0 0 1024 1024"><path d="M204.8 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M505.6 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M806.4 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path></svg>',
menuKeys: ['through', 'code', 'sup', 'sub', 'clearStyle'],
},
'color',
'bgColor',
'|',
'fontSize',
'fontFamily',
'lineHeight',
'|',
'bulletedList',
'numberedList',
'todo',
{
key: 'group-justify',
title: '对齐',
iconSvg:
'<svg viewBox="0 0 1024 1024"><path d="M768 793.6v102.4H51.2v-102.4h716.8z m204.8-230.4v102.4H51.2v-102.4h921.6z m-204.8-230.4v102.4H51.2v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z"></path></svg>',
menuKeys: ['justifyLeft', 'justifyRight', 'justifyCenter', 'justifyJustify'],
},
{
key: 'group-indent',
title: '缩进',
iconSvg:
'<svg viewBox="0 0 1024 1024"><path d="M0 64h1024v128H0z m384 192h640v128H384z m0 192h640v128H384z m0 192h640v128H384zM0 832h1024v128H0z m0-128V320l256 192z"></path></svg>',
menuKeys: ['indent', 'delIndent'],
},
'|',
'emotion',
'insertLink',
{
key: 'group-image',
title: '图片',
iconSvg:
'<svg viewBox="0 0 1024 1024"><path d="M959.877 128l0.123 0.123v767.775l-0.123 0.122H64.102l-0.122-0.122V128.123l0.122-0.123h895.775zM960 64H64C28.795 64 0 92.795 0 128v768c0 35.205 28.795 64 64 64h896c35.205 0 64-28.795 64-64V128c0-35.205-28.795-64-64-64zM832 288.01c0 53.023-42.988 96.01-96.01 96.01s-96.01-42.987-96.01-96.01S682.967 192 735.99 192 832 234.988 832 288.01zM896 832H128V704l224.01-384 256 320h64l224.01-192z"></path></svg>',
menuKeys: ['uploadImage'],
},
'insertTable',
'codeBlock',
'divider',
'|',
'undo',
'redo',
'|',
'fullScreen',
];

View File

@ -1,8 +1,6 @@
<template> <template>
<div class="layout-navbars-close-full" v-if="isTagsViewCurrenFull"> <div class="layout-navbars-close-full" v-if="isTagsViewCurrenFull">
<div class="layout-navbars-close-full-box" :title="$t('message.tagsView.closeFullscreen')" @click="onCloseFullscreen"> <SvgIcon name="ele-Close" :title="$t('message.tagsView.closeFullscreen')" @click="onCloseFullscreen" />
<SvgIcon name="ele-Close" />
</div>
</div> </div>
</template> </template>
@ -34,28 +32,27 @@ export default defineComponent({
z-index: 9999999999; z-index: 9999999999;
right: -30px; right: -30px;
top: -30px; top: -30px;
.layout-navbars-close-full-box { .svg-icon-container {
width: 60px; width: 60px;
height: 60px; height: 60px;
border-radius: 100%; border-radius: 100%;
position: relative;
cursor: pointer; cursor: pointer;
background: rgba(0, 0, 0, 0.1); background: rgba(0, 0, 0, 0.1);
transition: all 0.3s ease; transition: all 0.3s ease;
i { position: relative;
::v-deep(i) {
position: absolute; position: absolute;
left: 11px; left: 10px;
top: 35px; top: 12px;
color: #333333; color: #333333;
transition: all 0.3s ease; transition: all 0.3s ease;
} }
&:hover { }
background: rgba(0, 0, 0, 0.2); &:hover {
transition: all 0.3s ease;
::v-deep(i) {
color: var(--el-color-primary);
transition: all 0.3s ease; transition: all 0.3s ease;
i {
color: var(--el-color-primary);
transition: all 0.3s ease;
}
} }
} }
} }

View File

@ -1,28 +1,36 @@
/* wangeditor富文本编辑器 /* wangeditor富文本编辑器
------------------------------- */ ------------------------------- */
.w-e-toolbar { .editor-container {
border: 1px solid #ebeef5 !important; z-index: 9999;
border-bottom: 1px solid #ebeef5 !important; .w-e-toolbar {
border-top-left-radius: 3px; border: 1px solid var(--el-border-color-light, #ebeef5) !important;
border-top-right-radius: 3px; border-bottom: 1px solid var(--el-border-color-light, #ebeef5) !important;
z-index: 2 !important; border-top-left-radius: 3px;
} border-top-right-radius: 3px;
.w-e-text-container { z-index: 2 !important;
border: 1px solid #ebeef5 !important; }
border-top: none !important; .w-e-text-container {
border-bottom-left-radius: 3px; border: 1px solid var(--el-border-color-light, #ebeef5) !important;
border-bottom-right-radius: 3px; border-top: none !important;
z-index: 1 !important; border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
z-index: 1 !important;
}
} }
/* web端自定义截屏 [data-theme='dark'] {
------------------------------- */ // textarea - css vars
#screenShotContainer { --w-e-textarea-bg-color: var(--el-color-white) !important;
z-index: 9998 !important; --w-e-textarea-color: var(--el-text-color-primary) !important;
}
#toolPanel { // toolbar - css vars
height: 42px !important; --w-e-toolbar-color: var(--el-text-color-primary) !important;
} --w-e-toolbar-bg-color: var(--el-color-white) !important;
#optionPanel { --w-e-toolbar-active-color: var(--el-text-color-primary) !important;
height: 37px !important; --w-e-toolbar-active-bg-color: var(--next-color-menu-hover) !important;
--w-e-toolbar-border-color: var(--el-border-color-light, #ebeef5) !important;
// modal - css vars
--w-e-modal-button-bg-color: var(--el-color-primary) !important;
--w-e-modal-button-border-color: var(--el-color-primary) !important;
} }