基于vue实现的小程序管理后台图文编辑器

vue

附加说明:

1)基于element-ui的button和upload组件

2)支持文字和图片混合编辑

实现思路:

  页面中主要的组件:多行文本编辑框(高度随文本变化)、图片上传

       功能点梳理:

              新增段落,在文末或者任一段落上可点击添加段落按钮,点击后在文末或段落后新增一个段落;

              新增的段落可选择是文本还是图片,选择文本则将该新增段落变为多行文本编辑框,选择图片则触发选择本地文件进行上传,上传完后替换原新增段落;

              任一段落可进行上下移动、删除、在其下增加新增端口的操作;

              完成编辑,点击完成编辑按钮,用户可指定后续操作,一般是将编辑的内容保存到后端。

代码如下:

<template>

<div class="editor-viewer">

<div class="content-viewer">

<div class="content-list">

<div v-for="(content, index) in contentList" class="editor-item"

:key="index" :tabindex="index" @mouseover="handleMouseIn(index, content)"

@mouseout="handleMouseOut(index, content)">

<div class="textarea" contenteditable="true" v-if="content.type === \'text\'" >

{{content.value}}

</div>

<!-- <textarea v-if="content.type === \'text\'" v-model="content.value"></textarea> -->

<img v-if="content.type === \'image\'" :src="content.value">

<div class="add-module" v-if="content.type === \'empty\'">

<el-button @click="change2Text(index)">A</el-button>

<el-upload :data="{index: index}"

class="el-button"

action="https://jsonplaceholder.typicode.com/posts/"

:show-file-list="false"

:on-success="handleUploadSuccess"

:before-upload="beforeImageUpload" titlr="只能上传jpg/png文件,且不超过2M">

<i class="el-icon-picture" ></i>

</el-upload>

<el-button @click="delOne(index)" icon="el-icon-delete"></el-button>

</div>

<div class="editor-item-ops" v-if="content.type !== \'empty\' " v-show="content.visible">

<el-button icon="el-icon-plus" circle @click="beginAdd(index)"></el-button>

<el-button icon="el-icon-arrow-down" v-if="contentList.length > 1 && index !== contentList.length - 1"

circle @click="moveDown(index)"></el-button>

<el-button icon="el-icon-arrow-up" circle v-if="contentList.length > 1 && index !== 0"

@click="moveUp(index)"></el-button>

<el-button icon="el-icon-delete" circle @click="delOne(index, true)"></el-button>

</div>

</div>

</div>

</div>

<div class="editor-btn-viewer">

<el-button class="editor-btn" icon="el-icon-circle-check-outline"

@click="finishEdit"> 完成编辑</el-button>

<el-button class="editor-btn" icon="el-icon-circle-plus-outline" @click="addAtLast"> 添加模块</el-button>

</div>

</div>

</template>

<script>

import {Upload} from \'element-ui\'

export default {

data () {

return {

contentList: []

}

},

props: [\'contents\'],

components: {

ElUpload: Upload

},

methods: {

spliceContent (start, count, added) {

if (typeof added !== \'undefined\') {

return this.contentList.splice(start, count, added)

} else {

return this.contentList.splice(start, count)

}

},

addAtLast () {

this.contentList.push({type: \'empty\', value: \'\', visible: false})

},

beginAdd (index) {

this.spliceContent(index+1, 0, {type: \'empty\', value: \'\', visible: false})

},

moveDown (index) {

let cur = this.spliceContent(index, 1)

this.spliceContent(index + 1, 0, cur[0])

},

moveUp (index) {

let cur = this.spliceContent(index, 1)

this.spliceContent(index - 1, 0, cur[0])

},

delOne (index, delImage = false) {

this.spliceContent(index, 1)

if (delImage) {

// todo: 需要删除内容服务器上的图片文件

}

},

change2Text (index) {

this.spliceContent(index, 1, {type: \'text\', value: \'\', visible: false})

},

change2Image (index) {

this.spliceContent(index, 1, {type: \'image\', value: \'\', visible: false})

},

handleUploadSuccess(res, file) {

// res 需要返回附加data:index

let imageUrl = URL.createObjectURL(file.raw);

this.spliceContent(res.index, 1, {type: \'image\', value: imageUrl, visible: false})

},

beforeImageUpload(file) {

const isJPG = file.type === \'image/jpeg\';

const isLt2M = file.size / 1024 / 1024 < 2;

console.info(file)

if (!isJPG) {

this.$message.error(\'上传头像图片只能是 JPG 格式!\');

}

if (!isLt2M) {

this.$message.error(\'上传头像图片大小不能超过 2MB!\');

}

return isJPG && isLt2M;

},

handleMouseIn (index) {

let item = this.contentList[index];

item.visible = true;

this.spliceContent(index, 1, item);

},

handleMouseOut (index) {

let item = this.contentList[index];

item.visible = false;

this.spliceContent(index, 1, item);

},

finishEdit () {

}

},

mounted () {

this.contentList = this.contents.map(el => {

el.visible = false;

return el;

});

}

}

</script>

<style scoped>

.editor-viewer {

width: 600px;

height: 600px;

border: 1px solid #ddd;

position: relative;

}

.content-viewer {

width: 100%;

height: 552px;

overflow-y: scroll;

overflow-x: hidden;

}

.editor-btn-viewer {

width: 100%;

position: absolute;

bottom: 0;

left: 0;

}

.el-button {

background-color: #eee;

}

.editor-btn{

width: 50%;

padding: 15px;

outline: none;

border: 1px solid #ddd;

border-radius: 0;

margin: 0;

font-size: 16px;

}

.el-button:hover {

color: #409eff;

border-color: #c6e2ff;

background-color: #ecf5ff;

}

.content-list {

padding: 5px;

}

.editor-item +.editor-item{

margin-top: 5px;

}

.editor-item {

position: relative;

}

div.editor-item:hover{

box-shadow: 0 0 10px #ccc;

}

.editor-item>.textarea,

.editor-item>img{

width: 100%;

height: auto;

border: 1px solid #ccc;

min-height: 200px;

text-align: left;

}

.editor-item>img{

width: 571px;

}

.editor-item>textarea{

resize: none;

}

.editor-item-ops {

height: 50px;

position: absolute;

right: 6px;

bottom: 0;

z-index:100;

}

.editor-item-ops > .editor-btn {

background-color: #666;

}

.add-module {

border: 1px dashed #ccc;

min-height: 100px;

width: 100%;

line-height: 100px;

}

</style>

以上是 基于vue实现的小程序管理后台图文编辑器 的全部内容, 来源链接: utcz.com/z/379556.html

回到顶部