一個很典型的添加新聞功能,肯定離不了網頁編輯器,然後有很多種選擇,百度了大概說是quill和vue的兼容性比較好,網上也有很多在用,就跟風選擇了!
這是最終效果
實現的過程肯定是有些曲折的,所以給各位指條康莊大道
直接上全部代碼:
<template>
<div id="app">
<div class="container">
<el-form label="添加新聞" :model="form" prop="form" class="demo-form-inline" :inline="true" :rules="rules" ref="form">
<el-form-item prop="title" label="標題"label-width="60px">
<el-input style="width: 600px;" v-model="form.title" autocomplete="off" placeholder="請輸入新聞標題"></el-input>
</el-form-item><br>
<el-form-item prop="source" label="來源" label-width="60px">
<el-input style="width:600px;" v-model="form.source" autocomplete="off" placeholder="請輸入來源和作者等相關信息"></el-input>
</el-form-item><br>
<el-form-item prop="newtype" label="類型"label-width="60px">
<el-select v-model="form.newtype" placeholder="請選擇">
<el-option
v-for="item in options"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
</el-form-item>
<el-form-item prop="showinindex" label="是否首頁展示"label-width="140px">
<el-radio-group v-model="form.showinindex">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
</el-form-item><br>
<el-form-item prop="img" label="封面"label-width="60px">
<el-upload
class="avatar-uploader"
action="onon"
:show-file-list="false"
:before-upload="beforeAvatarUpload">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item><br>
<el-form-item prop="summary" label="概要"label-width="60px">
<el-input style="width: 600px;" type="textarea"
:rows="3"
placeholder="請輸入內容" maxlength="90"
show-word-limit v-model="form.summary" autocomplete="off"></el-input>
</el-form-item><br>
<el-form-item prop="content" label="內容"label-width="60px">
<el-card style="height: 410px;">
<quill-editor v-model="form.content" ref="myQuillEditor" style="height: 300px;" :options="editorOption">
<!-- 自定義toolar -->
<div id="toolbar" slot="toolbar">
<!-- Add a bold button -->
<button class="ql-bold" title="加粗">Bold</button>
<button class="ql-italic" title="斜體">Italic</button>
<button class="ql-underline" title="下劃線">underline</button>
<button class="ql-strike" title="刪除線">strike</button>
<button class="ql-blockquote" title="引用"></button>
<button class="ql-code-block" title="代碼"></button>
<button class="ql-header" value="1" title="標題1"></button>
<button class="ql-header" value="2" title="標題2"></button>
<!--Add list -->
<button class="ql-list" value="ordered" title="有序列表"></button>
<button class="ql-list" value="bullet" title="無序列表"></button>
<!-- Add font size dropdown -->
<select class="ql-header" title="段落格式">
<option selected>段落</option>
<option value="1">標題1</option>
<option value="2">標題2</option>
<option value="3">標題3</option>
<option value="4">標題4</option>
<option value="5">標題5</option>
<option value="6">標題6</option>
</select>
<select class="ql-size" title="字體大小">
<option value="12px">12px</option>
<option value="14px">14px</option>
<option value="16px" selected>16px</option>
<option value="18px">18px</option>
<option value="20px">20px</option>
</select>
<select class="ql-font" title="字體">
<option value="SimSun">宋體</option>
<option value="SimHei">黑體</option>
<option value="Microsoft-YaHei">微軟雅黑</option>
<option value="KaiTi">楷體</option>
<option value="FangSong">仿宋</option>
<option value="Arial">Arial</option>
</select>
<!-- Add subscript and superscript buttons -->
<select class="ql-color" value="color" title="字體顏色"></select>
<select class="ql-background" value="background" title="背景顏色"></select>
<select class="ql-align" value="align" title="對齊"></select>
<button class="ql-image" title="圖片"></button>
<button class="ql-clean" title="還原"></button>
<!-- You can also add your own -->
<input class="open-file" type="file" name="file" id="file"
accept="image/png, image/gif, image/jpeg, image/bmp, image/x-icon"
style="display: none;" @change="imgChange($event)" multiple="false"
/>
</div>
</quill-editor>
</el-card>
</el-form-item>
</el-form>
<div style="text-align:center;" >
<el-button @click="cancel('form')">取 消</el-button>
<el-button type="primary" @click="submit('form')">提 交</el-button>
</div>
</div>
</div>
</template>
<script>
import {
Quill,
quillEditor
} from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import qs from "qs";
//引入font.css
import './font.css'
// 自定義字體大小
let Size = Quill.import('attributors/style/size')
Size.whitelist = ['10px', '12px', '14px', '16px', '18px', '20px']
Quill.register(Size, true)
// 自定義字體類型
var fonts = ['SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong', 'Arial', 'Times-New-Roman', 'sans-serif',
'宋體', '黑體'
]
var Font = Quill.import('formats/font')
Font.whitelist = fonts
Quill.register(Font, true)
export default {
name: 'FuncFormsEdit',
components: {
quillEditor,
},
data() {
return {
imageUrl: '',
options: [],
rules: {
title: [
{
required: true,
message: "請輸入標題名稱",
trigger: "blur"
}
],
/*newtype:[{
required: true,
message: "請選擇類型",
trigger: "blur"
}],*/
summary:[
{
required: true,
message: "請輸入概要",
trigger: "blur"
}
]
},
form:{
title: "",
source:"",
newtype:"",
content:"",
summary:"",
showinindex:0,
img:''
},
content: null,
editorOption: {
placeholder: "請輸入",
theme: "snow", // or 'bubble'
modules: {
toolbar: {
container: '#toolbar',
handlers: {
'image': function (value) {
let that = this;
if (value) {
that.container.querySelector('.open-file').click();
} else {
this.quill.format('image', false);
}
}
},
}
}
}
}
},
created(){
this.axios
.post("./ttp/server/app/getNewsTypeList")
.then(res => {
this.options = res.data.data;
});
},
methods: {
beforeAvatarUpload(file) {
const isJPG = file.type === 'image/jpeg';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error('只能上傳圖片文件');
}
if (!isLt2M) {
this.$message.error('圖片大小不能超過 2MB!');
}
var data=new FormData;
data.append("file",file);
let that =this;
that.axios.post("./ttp/server/app/upload",data)
.then(function(res){
// 如果上傳成功
if (res.data.status) {
let imgName = res.data.data.name;
setTimeout(function() {
that.imageUrl = require('D:/upload/img/' + imgName);
that.form.img = imgName;
},2000);
} else {
// 提示信息,需引入Message
this.$alter('圖片引入失敗');
}
})
},
imgChange(e){
var fileInput=e.target;
if(fileInput.files.length==0){
return
}
//this.editor.focus();
if(fileInput.files[0].size>1024*1024*100){
this.$alert('圖片不能大於600KB', '圖片尺寸過大', {
confirmButtonText: '確定',
type: 'warning',
})
}
var data=new FormData;
data.append("file",fileInput.files[0]);
let that =this;
that.axios.post("./ttp/server/app/upload",data)
.then(function(res){
// 如果上傳成功
if (res.data.status) {
let imgName = res.data.data;
setTimeout(function(){
let lujing = require('D:/upload/img/'+imgName);
// 獲取富文本組件實例
let quill = that.$refs.myQuillEditor.quill;
// 獲取光標所在位置
let length = quill.getSelection().index;
quill.insertEmbed(length, 'image', lujing); // 調整光標到最後
quill.setSelection(length + 1);
},2000);
} else {
// 提示信息,需引入Message
this.$alter('圖片插入失敗');
}
})
},
cancel(formName) {
this.$parent.$parent.newsAddVisible = false;
this.$refs[formName].resetFields();
this.$parent.$parent.silent();
},
submit(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
this.axios.post('./ttp/server/app/addNews', qs.stringify(this.form)).then(res => {
if (res.data.status) {
this.$notify.success({
title: "成功",
message: res.data.message
});
this.cancel('form');
}else {
this.$notify.error({
title: "錯誤",
message: res.data.message
});
}
})
.catch(function(err) {
console.log(err);
});
}
});
},
}
}
</script>
<style scoped>
.container{
height: 100%;
margin: 0 auto;
padding: 20px;
background-color: #f9fafc;
}
.ivu-upload {
display: none;
}
.avatar-uploader {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader:hover {
border-color: #409EFF;
}
.el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
參考別人的例子,很容易就把基本的編輯功能都實現,主要曲折點就是圖片上傳功能,具體請參考我寫的: