Skip to content

Commit

Permalink
添加富文本编辑功能
Browse files Browse the repository at this point in the history
  • Loading branch information
zhh committed Jun 1, 2018
1 parent a7d2085 commit 02a28d6
Show file tree
Hide file tree
Showing 43 changed files with 1,238 additions and 5 deletions.
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<title>mall-admin-web</title>
</head>
<body>
<script src="./static/tinymce4.7.5/tinymce.min.js"></script>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
Expand Down
116 changes: 116 additions & 0 deletions src/components/Tinymce/components/editorImage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<template>
<div class="upload-container">
<el-button icon='el-icon-upload' size="mini" :style="{background:color,borderColor:color}"
@click=" dialogVisible=true" type="primary">上传图片
</el-button>
<el-dialog append-to-body :visible.sync="dialogVisible">
<el-upload class="editor-slide-upload"
action="http:https://macro-oss.oss-cn-shenzhen.aliyuncs.com"
:data="dataObj"
:multiple="true"
:file-list="fileList"
:show-file-list="true"
list-type="picture-card"
:on-remove="handleRemove"
:on-success="handleSuccess"
:before-upload="beforeUpload">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="handleSubmit">确 定</el-button>
</el-dialog>
</div>
</template>

<script>
import {policy} from '@/api/oss'
export default {
name: 'editorSlideUpload',
props: {
color: {
type: String,
default: '#1890ff'
}
},
data() {
return {
dialogVisible: false,
listObj: {},
fileList: [],
dataObj: {
policy: '',
signature: '',
key: '',
ossaccessKeyId: '',
dir: '',
host: ''
}
}
},
methods: {
checkAllSuccess() {
return Object.keys(this.listObj).every(item => this.listObj[item].hasSuccess)
},
handleSubmit() {
const arr = Object.keys(this.listObj).map(v => this.listObj[v])
if (!this.checkAllSuccess()) {
this.$message('请等待所有图片上传成功 或 出现了网络问题,请刷新页面重新上传!')
return
}
console.log(arr);
this.$emit('successCBK', arr);
this.listObj = {};
this.fileList = [];
this.dialogVisible = false;
},
handleSuccess(response, file) {
const uid = file.uid;
const objKeyArr = Object.keys(this.listObj)
for (let i = 0, len = objKeyArr.length; i < len; i++) {
if (this.listObj[objKeyArr[i]].uid === uid) {
this.listObj[objKeyArr[i]].url = this.dataObj.host + '/' + this.dataObj.dir + '/' + file.name;
this.listObj[objKeyArr[i]].hasSuccess = true;
return
}
}
},
handleRemove(file) {
const uid = file.uid;
const objKeyArr = Object.keys(this.listObj);
for (let i = 0, len = objKeyArr.length; i < len; i++) {
if (this.listObj[objKeyArr[i]].uid === uid) {
delete this.listObj[objKeyArr[i]];
return
}
}
},
beforeUpload(file) {
const _self = this
const fileName = file.uid;
this.listObj[fileName] = {};
return new Promise((resolve, reject) => {
policy().then(response => {
_self.dataObj.policy = response.data.policy;
_self.dataObj.signature = response.data.signature;
_self.dataObj.ossaccessKeyId = response.data.accessKeyId;
_self.dataObj.key = response.data.dir + '/${filename}';
_self.dataObj.dir = response.data.dir;
_self.dataObj.host = response.data.host;
_self.listObj[fileName] = {hasSuccess: false, uid: file.uid, width: this.width, height: this.height};
resolve(true)
}).catch(err => {
console.log(err)
reject(false)
})
})
}
}
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.upload-container .editor-slide-upload{
margin-bottom: 20px;
}
</style>
163 changes: 163 additions & 0 deletions src/components/Tinymce/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<template>
<div class="tinymce-container editor-container">
<textarea class="tinymce-textarea" :id="tinymceId"></textarea>
<div class="editor-custom-btn-container">
<editorImage color="#1890ff" class="editor-upload-btn" @successCBK="imageSuccessCBK"></editorImage>
</div>
</div>
</template>

<script>
import editorImage from './components/editorImage'
import '../../../static/tinymce4.7.5/langs/zh_CN'
const plugins = [
`advlist anchor autolink autosave code codesample colorpicker colorpicker
contextmenu directionality emoticons fullscreen hr image imagetools importcss insertdatetime
legacyoutput link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace
spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount`
];
const toolbar = [
`bold italic underline strikethrough alignleft aligncenter
alignright outdent indent blockquote undo redo removeformat`,
`hr bullist numlist link image charmap preview anchor pagebreak
fullscreen insertdatetime media table forecolor backcolor`
];
export default {
name: 'tinymce',
components: {editorImage},
props: {
id: {
type: String
},
value: {
type: String,
default: ''
},
toolbar: {
type: Array,
required: false,
default() {
return []
}
},
menubar: {
default: 'file edit insert view format table'
},
height: {
type: Number,
required: false,
default: 360
},
width: {
type: Number,
required: false,
default: 720
}
},
data() {
return {
hasChange: false,
hasInit: false,
tinymceId: this.id || 'vue-tinymce-' + +new Date()
}
},
watch: {
value(val) {
if (!this.hasChange && this.hasInit) {
this.$nextTick(() => window.tinymce.get(this.tinymceId).setContent(val))
}
}
},
mounted() {
this.initTinymce()
},
activated() {
this.initTinymce()
},
deactivated() {
this.destroyTinymce()
},
methods: {
initTinymce() {
const _this = this
window.tinymce.init({
selector: `#${this.tinymceId}`,
width: this.width,
height: this.height,
language: 'zh_CN',
body_class: 'panel-body ',
object_resizing: false,
toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,
menubar: false,
plugins: plugins,
end_container_on_empty_block: true,
powerpaste_word_import: 'clean',
code_dialog_height: 450,
code_dialog_width: 1000,
advlist_bullet_styles: 'square',
advlist_number_styles: 'default',
imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'],
default_link_target: '_blank',
link_title: false,
init_instance_callback: editor => {
if (_this.value) {
editor.setContent(_this.value)
}
_this.hasInit = true
editor.on('NodeChange Change KeyUp SetContent', () => {
this.hasChange = true
this.$emit('input', editor.getContent())
})
}
})
},
destroyTinymce() {
if (window.tinymce.get(this.tinymceId)) {
window.tinymce.get(this.tinymceId).destroy()
}
},
setContent(value) {
window.tinymce.get(this.tinymceId).setContent(value)
},
getContent() {
window.tinymce.get(this.tinymceId).getContent()
},
imageSuccessCBK(arr) {
const _this = this
arr.forEach(v => {
window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`)
})
}
},
destroyed() {
this.destroyTinymce()
}
}
</script>

<style scoped>
.tinymce-container {
position: relative;
}
.tinymce-container >>> .mce-fullscreen {
z-index: 10000;
}
.tinymce-textarea {
visibility: hidden;
z-index: -1;
}
.editor-custom-btn-container {
position: absolute;
right: 10px;
top: 2px;
/*z-index: 2005;*/
}
.editor-upload-btn {
display: inline-block;
}
</style>
Loading

0 comments on commit 02a28d6

Please sign in to comment.