问题描述
【ant design vue】 使用wangeditor 做文章编辑 如何填充内容到编辑器中
问题出现的环境背景及自己尝试过哪些方法
最近才是vue,不是很熟悉,我百度了相关问题都没有一个合适的解决方法,希望大神指教一下。
相关代码
组件
<template>
<div :class="prefixCls">
<div ref="editor" class="editor-wrapper"></div>
</div>
</template>
<script>
import WEditor from 'wangeditor'
export default {
name: 'WangEditor',
props: {
prefixCls: {
type: String,
default: 'ant-editor-wang'
},
// eslint-disable-next-line
value: {
type: String
}
},
data () {
return {
editor: null,
editorContent: null
}
},
watch: {
value (val) {
this.editorContent = val
this.editor.txt.html(val)
}
},
mounted () {
this.initEditor()
},
methods: {
initEditor () {
this.editor = new WEditor(this.$refs.editor)
// this.editor.onchangeTimeout = 200
this.editor.customConfig.onchange = (html) => {
this.editorContent = html
this.$emit('change', this.editorContent)
}
this.editor.create()
}
}
}
</script>
<style lang="less" scoped>
.ant-editor-wang {
.editor-wrapper {
text-align: left;
}
}
</style>
编辑页面调用
<template>
<a-card :bordered="false">
<a-tabs type="card">
<a-tab-pane key="1" tab="基本信息">
<a-form @submit="handleSubmit" :form="form">
<a-row class="form-row" :gutter="16">
<a-col :lg="6" :md="12" :sm="24">
<a-form-item label="书名">
<a-input
allowClear
placeholder="请输入书名"
v-decorator="[
'books.title',
{initialValue: books.title},
{rules: [{ required: true, message: '请输入书名', whitespace: true}]}
]" />
</a-form-item>
</a-col>
<a-col :xl="{span: 7, offset: 1}" :lg="{span: 8}" :md="{span: 12}" :sm="24">
<a-form-item
label="作者">
<a-input
allowClear
placeholder="请输入作者名称"
v-decorator="[
'books.author',
{initialValue: books.author},
{rules: [{ required: true, message: '请输入作者名称', whitespace: true}]}
]" />
</a-form-item>
</a-col>
<a-col :xl="{span: 9, offset: 1}" :lg="{span: 10}" :md="{span: 24}" :sm="24">
<a-form-item
label="类型">
<a-select mode="multiple" allowClear placeholder="请选择类型" v-decorator="[ 'books.class_tree_id',{initialValue: parseInt(books.class_tree_id)}, {rules: [{ required: true, message: '请选择类型' }]} ]">
<a-select-option v-for="i in this.classtree" :key="i.id">{{ i.name }}</a-select-option>
</a-select>
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row" :gutter="16">
<a-col :lg="6" :md="12" :sm="24">
<a-form-item
label="标签">
<a-select allowClear mode="tags" placeholder="按Enter或Tab选中标签" v-decorator="[ 'books.tags', {initialValue: books.tags} ]">
</a-select>
</a-form-item>
</a-col>
<a-col :xl="{span: 7, offset: 1}" :lg="{span: 8}" :md="{span: 12}" :sm="24">
<a-form-item
label="简介">
<a-input
type="textarea"
:rows="3"
placeholder="不填写自动获取第一页前100个字..."
v-decorator="[
'books.desc'
]" />
</a-form-item>
</a-col>
<a-col :xl="{span: 9, offset: 1}" :lg="{span: 10}" :md="{span: 24}" :sm="24">
<a-form-item>
<a-upload
name="file"
list-type="picture-card"
style="height: 102px;width: 102px;"
:show-upload-list="false"
:customRequest="customRequest"
:beforeUpload="beforeUpload"
@change="handleChange"
>
<img v-if="imageUrl" :src="imageUrl" alt="avatar" style="width: 86px;height: 86px;" />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">
上传封面
</div>
</div>
</a-upload>
</a-form-item>
</a-col>
</a-row>
<a-form-item
v-for="(domain, index) in dynamicValidateForm.domains"
:key="index"
:props="'domains.' + index + '.value'"
>
<a-form-item
label="页标题"
>
<a-input
allowClear
style="width: 50%;margin-right: 8px"
v-decorator="[
`chapter.title[${index}]`,
{initialValue: domain.title},
{ rules: [{ required: true, message: '请输入页标题' }] },
]"
placeholder="页标题"
/>
<a-input
:disabled="true"
style="width: 10%;margin-right: 8px;"
v-decorator="[
`chapter.words[${index}]`,
{initialValue: domain.words}
]"
placeholder="字数"
suffix="个"
/>
<a-tooltip placement="top">
<template slot="title">
<span>移除</span>
</template>
<a-icon
v-if="dynamicValidateForm.domains.length > 1"
class="dynamic-delete-button"
type="minus-circle-o"
:disabled="dynamicValidateForm.domains.length === 1"
@click="removeDomain(domain)"
/>
</a-tooltip>
</a-form-item>
<a-form-item
label="页内容"
>
<wangeditor
ref="editor"
@change="changeEditor($event, index)"
v-model="domain.content"
>
</wangeditor>
</a-form-item>
</a-form-item>
<a-form-item>
<a-button type="dashed" style="width: 100%" @click="addDomain">
<a-icon type="plus" /> 添加页
</a-button>
</a-form-item>
<a-form-item>
<a-button type="primary" htmlType="submit" style="margin-right: 8px;">
提交
</a-button>
<a-button @click="handleGo">
返回
</a-button>
</a-form-item>
</a-form>
</a-tab-pane>
<!-- <a-tab-pane key="2" tab="其他信息">
Content of Tab Pane 2
</a-tab-pane> -->
</a-tabs>
</a-card>
</template>
<script>
import Wangeditor from '@/components/Editor/WangEditor'
import { getClassTreeList } from '@/api/classtree'
import { upload, read, update } from '@/api/books'
import { refreshMenus } from '@/utils/util'
export default {
name: 'BooksEdit',
components: {
Wangeditor
},
data () {
return {
id: this.$route.query.id,
form: this.$form.createForm(this),
loading: false,
imageUrl: '',
dynamicValidateForm: {
domains: []
},
classtree: [],
books: {
cover: ''
},
chapter: {
words: []
},
content: [],
words: [],
words_obj: {}
}
},
created () {
// 获取书籍分类列表
this.getTypeList()
// 获取图书信息
this.getBookInfo(this.id)
},
methods: {
// 提交
handleSubmit (e) {
e.preventDefault()
const { form: { validateFields } } = this
validateFields((errors, values) => {
if (!errors) {
values['content'] = this.content
values['books']['cover'] = this.books.cover
update(this.id, values).then((res) => {
this.refresh(res.msg)
refreshMenus()
}).catch(err => this.failed(err))
}
})
},
// 成功
refresh (message) {
this.$notification['success']({
message: message,
duration: 4
})
this.handleGo()
},
// 失败
failed (errors) {
this.$notification['error']({
message: errors.message,
duration: 4
})
},
// 返回上一页
handleGo () {
this.$router.go(-1) // 返回上一层
},
// 重置
handleReset () {
this.form.resetFields()
},
// 点击上传图片
handleChange (info) {
if (info.file.status === 'uploading') {
this.loading = true
return
}
if (info.file.status === 'done') {
this.$message.success(`${info.file.name} 上传成功`)
}
if (info.file.status === 'error') {
this.$message.error(`${info.file.name} 上传失败`)
}
},
// 上传前回调
beforeUpload (file) {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
if (!isJpgOrPng) {
this.$message.error('你只能上传JPG或PNG文件!')
}
const isLt2M = file.size / 1024 / 1024 < 2
if (!isLt2M) {
this.$message.error('图像必须小于2MB!')
}
return isJpgOrPng && isLt2M
},
customRequest (file) { // 上传提交
const formData = new FormData()
formData.append('file', file.file)
formData.append('token', 'token')
this.saveFile(formData)
},
// 回调
saveFile (formData) {
upload(formData).then((res) => {
if (res) {
this.books.cover = res.data
this.imageUrl = process.env.VUE_APP_API_URL + res.data
this.loading = false
}
}).catch((err) => {
this.loading = false
this.$message.error(err)
})
},
// 添加页
addDomain () {
this.dynamicValidateForm.domains.push({
words: '',
title: '',
content: ''
})
},
// 移除页
removeDomain (item) {
const index = this.dynamicValidateForm.domains.indexOf(item)
if (index !== -1) {
this.dynamicValidateForm.domains.splice(index, 1)
this.content.splice(index, 1)
}
},
// 获取分类列表
getTypeList () {
getClassTreeList().then(res => {
this.classtree = res.data
})
},
// 获取图书信息
getBookInfo ($id) {
read($id).then(res => {
this.books = res.data
// 封面
this.imageUrl = process.env.VUE_APP_API_URL + res.data.cover
this.dynamicValidateForm.domains = res.data.chapter_content
})
},
// 正文内容
changeEditor (val, index) {
this.content[index] = val
// 字数
this.chapter.words[index] = this.$refs.editor[index].$refs.editor.innerText.length
// 设置表单字段值
this.$set(this.words_obj, 'chapter.words[' + index + ']', this.chapter.words[index])
const { form: { setFieldsValue } } = this
this.$nextTick(() => {
setFieldsValue(this.words_obj)
})
}
}
}
</script>
<style lang="less" scoped>
.dynamic-delete-button {
cursor: pointer;
position: relative;
top: 4px;
font-size: 24px;
color: #999;
transition: all 0.3s;
}
.dynamic-delete-button:hover {
color: #777;
}
.dynamic-delete-button[disabled] {
cursor: not-allowed;
opacity: 0.5;
}
.ant-upload-text {
margin-top: 8px;
color: #666;
}
</style>