封装-富文本组件

This commit is contained in:
祝梦园 2024-02-23 15:41:41 +08:00
parent 28b1686a00
commit 0da7dc9f91
2 changed files with 166 additions and 126 deletions

View File

@ -0,0 +1,138 @@
<template>
<div>
<div id="contentEditor"></div>
</div>
</template>
<script>
import Vue from "vue";
import apiConfig from "@/config/api.config";
export default {
name: "contentEditor",
data() {
return {
contentEditor: null,
}
},
props: {
initValue: {
type: String,
required: true
}
},
methods: {
_initEditor(data) {
//
let _ts = this;
let toolbar = [
'emoji',
'headings',
'bold',
'italic',
'strike',
'link',
'|',
'list',
'ordered-list',
'check',
'outdent',
'indent',
'|',
'quote',
'line',
'code',
'inline-code',
'insert-before',
'insert-after',
'|',
// 'upload',
// 'record',
'table',
'|',
'undo',
'redo',
'|',
'edit-mode',
{
name: 'more',
toolbar: [
'fullscreen',
'both',
'preview',
'info'
],
}]
return new Vue.Vditor(data.id, {
toolbar,
mode: 'sv',
tab: '\t',
cdn: apiConfig.VDITOR,
cache: {
enable: this.$route.params.article_id ? false : true,
id: this.$route.params.article_id ? this.$route.params.article_id : '',
},
after() {
_ts.contentEditor.setValue(data.value ? data.value : '');
},
typewriterMode: true,
hint: {
emoji: Vue.emoji
},
preview: {
markdown: {
toc: true,
},
math: {
inlineDigit: true
},
delay: 500,
mode: data.mode,
/*url: `${process.env.Server}/api/console/markdown`,*/
parse: (element) => {
if (element.style.display === 'none') {
return false
}
// LazyLoadImage();
// Vue.Vditor.highlightRender({style: 'github'}, element, this.contentEditor);
},
theme: {
cdn: apiConfig.VDITOR_CSS
}
},
height: data.height,
counter: 102400,
resize: {
enable: data.resize,
},
lang: this.$store.state.locale,
// placeholder: data.placeholder,
})
},
editValue() {
console.log('我被执行了')
let data = this.contentEditor.getValue();
this.$emit('editValue', data)
},
editHtml() {
let data = this.contentEditor.getHTML();
this.$emit('editHtml', data)
}
},
mounted() {
this.contentEditor = this._initEditor({
id: 'contentEditor',
mode: 'both',
height: 480,
placeholder: '', //this.$t('inputContent', this.$store.state.locale)
resize: false,
value: this.initValue
});
}
}
</script>
<style scoped>
</style>

View File

@ -19,7 +19,9 @@
</el-form-item> </el-form-item>
<br> <br>
<el-form-item label="作品集介绍"> <el-form-item label="作品集介绍">
<div id="contentEditor"></div> <content-editor @editValue="editValue" :initValue="portfolio.portfolioDescription||''"
v-if="isLoading" @editHtml="editHtml"
ref="contentEditor"></content-editor>
</el-form-item> </el-form-item>
<el-form-item class="text-right"> <el-form-item class="text-right">
<el-button :loading="loading" @click="deletePortfolio" v-if="isEdit">删除</el-button> <el-button :loading="loading" @click="deletePortfolio" v-if="isEdit">删除</el-button>
@ -89,9 +91,8 @@
</template> </template>
<script> <script>
import Vue from 'vue';
import {mapState} from 'vuex'; import {mapState} from 'vuex';
import apiConfig from '~/config/api.config'; import ContentEditor from "@/components/ContentEditor.vue";
export default { export default {
name: "PortfolioPost", name: "PortfolioPost",
@ -107,7 +108,9 @@ export default {
.catch(err => error({statusCode: 404})) .catch(err => error({statusCode: 404}))
]) ])
}, },
components: {
ContentEditor
},
computed: { computed: {
...mapState({ ...mapState({
portfolioDetail: state => state.portfolio.detail.data, portfolioDetail: state => state.portfolio.detail.data,
@ -134,19 +137,10 @@ export default {
}, },
data() { data() {
return { return {
contentEditor: null,
portfolio: { portfolio: {
idPortfolio: 0, idPortfolio: 0,
portfolioDescription: '' portfolioDescription: ''
}, },
// rules: {
// portfolioTitle: [
// {required: true, message: '', trigger: 'blur'}
// ],
// portfolioDescription: [
// {required: true, message: '', trigger: 'blur'}
// ]
// },
loading: false, loading: false,
tokenURL: { tokenURL: {
URL: '', URL: '',
@ -158,104 +152,23 @@ export default {
isEdit: false, isEdit: false,
autoCrop: true, autoCrop: true,
notificationFlag: true, notificationFlag: true,
contentHtml: {} contentValue: {
portfolioDescription: '',
portfolioDescriptionHtml: ''
},
isLoading: false
} }
}, },
methods: { methods: {
editValue(data) {
this.contentValue.portfolioDescription = data
},
editHtml(data) {
this.contentValue.portfolioDescriptionHtml = data
},
realTime(data) { realTime(data) {
this.cropImg = data; this.cropImg = data;
}, },
_initEditor(data) {
//
let _ts = this;
let toolbar = [
'emoji',
'headings',
'bold',
'italic',
'strike',
'link',
'|',
'list',
'ordered-list',
'check',
'outdent',
'indent',
'|',
'quote',
'line',
'code',
'inline-code',
'insert-before',
'insert-after',
'|',
// 'upload',
// 'record',
'table',
'|',
'undo',
'redo',
'|',
'edit-mode',
{
name: 'more',
toolbar: [
'fullscreen',
'both',
'preview',
'info'
],
}]
return new Vue.Vditor(data.id, {
toolbar,
mode: 'sv',
tab: '\t',
cdn: apiConfig.VDITOR,
cache: {
enable: this.$route.params.article_id ? false : true,
id: this.$route.params.article_id ? this.$route.params.article_id : '',
},
after() {
_ts.contentEditor.setValue(data.value ? data.value : '');
},
input: (val) => {
this.portfolio.portfolioDescription = val
},
typewriterMode: true,
hint: {
emoji: Vue.emoji
},
preview: {
markdown: {
toc: true,
},
math: {
inlineDigit: true
},
delay: 500,
mode: data.mode,
/*url: `${process.env.Server}/api/console/markdown`,*/
parse: (element) => {
if (element.style.display === 'none') {
return false
}
// LazyLoadImage();
// Vue.Vditor.highlightRender({style: 'github'}, element, this.contentEditor);
},
theme: {
cdn: apiConfig.VDITOR_CSS
}
},
height: data.height,
counter: 102400,
resize: {
enable: data.resize,
},
lang: this.$store.state.locale,
// placeholder: data.placeholder,
})
},
handleAvatarSuccess(res) { handleAvatarSuccess(res) {
let _ts = this; let _ts = this;
if (res && res.data && res.data.url) { if (res && res.data && res.data.url) {
@ -294,18 +207,13 @@ export default {
handleSubmitData() { handleSubmitData() {
let _ts = this; let _ts = this;
_ts.$set(_ts, 'loading', true); _ts.$set(_ts, 'loading', true);
let portfolioDescription = _ts.contentEditor.getValue();
let portfolioDescriptionHtml = _ts.contentEditor.getHTML();
let data = _ts.portfolio;
data.portfolioDescription = portfolioDescription;
data.portfolioDescriptionHtml = portfolioDescriptionHtml;
data.headImgType = 0
// if (_ts.isEdit) {
// _ts.$refs.contentEditor.editValue();
// } else { _ts.$refs.contentEditor.editHtml();
// data.headImgUrl = _ts.headImgUrl let data = _ts.portfolio;
// } data.portfolioDescription = _ts.contentValue.portfolioDescription;
data.portfolioDescriptionHtml = _ts.contentValue.portfolioDescriptionHtml;
data.headImgType = 0
if ((data.portfolioDescription || undefined) == undefined || (data.portfolioDescriptionHtml || undefined) == undefined) { if ((data.portfolioDescription || undefined) == undefined || (data.portfolioDescriptionHtml || undefined) == undefined) {
this.$message.error('请输入必填信息'); this.$message.error('请输入必填信息');
return false return false
@ -337,6 +245,7 @@ export default {
}, },
async updatePortfolio() { async updatePortfolio() {
console.log('我怎么一直在执行')
let _ts = this let _ts = this
let data = this.handleSubmitData() let data = this.handleSubmitData()
let id = _ts.idPortfolio; let id = _ts.idPortfolio;
@ -431,6 +340,7 @@ export default {
_ts.$store.commit("setActiveMenu", "portfolio-post"); _ts.$store.commit("setActiveMenu", "portfolio-post");
this.$axios.$get('/api/upload/simple/token').then(function (res) { this.$axios.$get('/api/upload/simple/token').then(function (res) {
if (res) { if (res) {
_ts.$store.commit('setUploadHeaders', res.uploadToken); _ts.$store.commit('setUploadHeaders', res.uploadToken);
_ts.$set(_ts, 'tokenURL', { _ts.$set(_ts, 'tokenURL', {
token: res.uploadToken || '', token: res.uploadToken || '',
@ -454,15 +364,7 @@ export default {
} else { } else {
this.isEdit = false this.isEdit = false
} }
this.isLoading = true
this.contentEditor = this._initEditor({
id: 'contentEditor',
mode: 'both',
height: 480,
placeholder: '', //this.$t('inputContent', this.$store.state.locale)
resize: false,
value: this.portfolio.portfolioDescription
});
} }
} }
</script> </script>