Selaa lähdekoodia

添加富文本

lincl 4 vuotta sitten
vanhempi
commit
ba16a9272c

+ 2 - 1
package.json

@ -14,7 +14,8 @@
    "element-ui": "^2.15.1",
    "js-cookie": "^2.2.1",
    "vue": "^2.5.11",
    "vue-i18n": "^8.23.0"
    "vue-i18n": "^8.23.0",
    "vue-quill-editor": "^3.0.6"
  },
  "browserslist": [
    "> 1%",

+ 57 - 0
src/components/Form/editOptions.js

@ -0,0 +1,57 @@
const editorOption = {
    theme: 'snow',
    boundary: document.body,
    modules: {
        toolbar: [
            ['bold', 'italic', 'underline', 'strike'],
            ['blockquote', 'code-block'],
            [{
                'header': 1
            }, {
                'header': 2
            }],
            [{
                'list': 'ordered'
            }, {
                'list': 'bullet'
            }],
            [{
                'script': 'sub'
            }, {
                'script': 'super'
            }],
            [{
                'indent': '-1'
            }, {
                'indent': '+1'
            }],
            [{
                'direction': 'rtl'
            }],
            [{
                'size': ['small', false, 'large', 'huge']
            }],
            [{
                'header': [1, 2, 3, 4, 5, 6, false]
            }],
            [{
                'color': []
            }, {
                'background': []
            }],
            [{
                'font': []
            }],
            [{
                'align': []
            }],
            ['clean'],
            ['link', 'image', 'video']
        ]
    },
    placeholder: 'Insert text here ...',
    readOnly: false,
}
export default editorOption

+ 1 - 1
src/components/Form/example/configs.js

@ -70,7 +70,7 @@ var config = {
            children: [{
                label: "姓名2",
                id: "name2",
                type: 'text',
                type: 'richtext',
            }],
        },
        // {

+ 4 - 1
src/components/Form/example/index.vue

@ -1,6 +1,6 @@
<template>
	<div class="plr50 pt30">
		<Form ref="form" :configs='config'>
		<Form @input="change" ref="form" :configs='config'>
			<!-- <div slot="name" slot-scope="scope">gfdgfg</div> -->
			<div slot="footer" class="">
				<el-button >取消</el-button>
@ -46,6 +46,9 @@ export default {
		}, 1000)
	},
	methods: {
		change(form){
			console.log('form', form)
		},
		submit(){
			this.$refs.form.submit().then((valid)=>{
				console.log(valid)

+ 161 - 93
src/components/Form/form.vue

@ -1,98 +1,116 @@
<template>
	<div>
		<el-row v-for="(v, i) in rows" :gutter="40" :key="i">
			<el-col :span="(item.span||1)/columnNum * 24" v-for="(item, k) in v" :key="k">
				<el-form-item  :label="item.label" :prop="item.id">
					<slot v-if="$scopedSlots[item.id]" :name="item.id" :config="item" />
					<template v-else>
						<el-input v-bind="item" v-if="item.type=='text'||item.type=='number'||item.type=='digit'" v-model="form[item.id]" :placeholder="item.placeholder" clearable/>
						<el-input
							v-bind="item"
							v-if="item.type=='textarea'"
							v-model="form[item.id]">
						</el-input>
						<el-date-picker
							:key="i"
							v-else-if="item.type=='daterange'||item.type=='monthrange'"
							v-model="form[item.id]"
							:start-placeholder="item.label+ '起'"
							:end-placeholder="item.label+ '至'"
							align="right"
							unlink-panels
							:value-format="item.format||(item.type=='monthrange'? 'yyyy-MM' : 'yyyy-MM-dd' )"
							range-separator="至"
							:picker-options="item.pickerOptions || pickerOptions"
							v-bind="item"
							>
						</el-date-picker>
						<el-date-picker
							v-bind="item"
							clearable
							:key="i"
							v-else-if="item.type=='date'||item.type=='year'||item.type=='month'||item.type=='week'||item.type=='dates'"
							v-model="form[item.id]"
							:value-format="item.format||(item.type=='year'? 'yyyy' : item.type=='month'? 'yyyy-MM' : 'yyyy-MM-dd' )"
							>
						</el-date-picker>
						<!-- <el-date-picker
							clearable
							v-else-if="type=='datetime'"
							:key="i"
							v-model="form[item.id]"
							type="datetime"
							:placeholder="item.placeholder">
						</el-date-picker> -->
						<el-select 
							v-else-if="item.type=='select'"
							:key="i"
							v-model="form[item.id]"
							clearable 
							v-bind="item"
							@change="onSelChange($event, item)"
							>
							<el-option
								v-for="opt in item.optionList"
								:key="opt.value"
								:label="opt.label"
								:value="opt.value">
							</el-option>
						</el-select>
						<Upload
							:configs="item"
							v-else-if="item.type=='photo'"
							v-model="form[item.id]">
						</Upload>
						<template v-else-if="item.type=='radio'">
							<el-radio 
								v-for="opt in item.optionList" 
								:key="opt.value" 
								v-model="form[item.id]" 
								:label="opt.value">{{opt.label}}</el-radio>
						</template>
						<template v-else-if="item.type=='checkbox'">
							<el-checkbox-group 
								@change="onCheckboxChange($event, item)"
		<el-row :gutter="40">
			<template v-for="(item, k) in fields">
				<el-col v-if="!item.isHide" :span="(item.span||1)/columnNum * 24" :key="k">
					<el-form-item  :label="item.label" :prop="item.id">
						<slot v-if="$scopedSlots[item.id]" :name="item.id" :config="item" />
						<template v-else>
							<el-input v-bind="item" v-if="item.type=='text'||item.type=='number'||item.type=='digit'" v-model="form[item.id]" :placeholder="item.placeholder" clearable/>
							<el-input
								v-bind="item"
								v-if="item.type=='textarea'"
								v-model="form[item.id]">
							</el-input>
							<el-date-picker
								v-else-if="item.type=='daterange'||item.type=='monthrange'"
								v-model="form[item.id]"
								:start-placeholder="item.label+ '起'"
								:end-placeholder="item.label+ '至'"
								align="right"
								unlink-panels
								:value-format="item.format||(item.type=='monthrange'? 'yyyy-MM' : 'yyyy-MM-dd' )"
								range-separator="至"
								:picker-options="item.pickerOptions || pickerOptions"
								v-bind="item"
								>
							</el-date-picker>
							<el-date-picker
								v-bind="item"
								clearable
								v-else-if="item.type=='date'||item.type=='year'||item.type=='month'||item.type=='week'||item.type=='dates'"
								v-model="form[item.id]"
								:value-format="item.format||(item.type=='year'? 'yyyy' : item.type=='month'? 'yyyy-MM' : 'yyyy-MM-dd' )"
								>
							</el-date-picker>
							<!-- <el-date-picker
								clearable
								v-else-if="type=='datetime'"
								v-model="form[item.id]"
								type="datetime"
								:placeholder="item.placeholder">
							</el-date-picker> -->
							<el-select 
								v-else-if="item.type=='select'"
								v-model="form[item.id]"
								clearable 
								v-bind="item"
								@change="onSelChange($event, item)"
								v-on="item.evts"
								>
								<el-option
									v-for="opt in item.optionList"
									:key="opt.value"
									:label="opt.label"
									:value="opt.value">
								</el-option>
							</el-select>
							<Upload
								:configs="item"
								v-else-if="item.type=='photo'"
								v-model="form[item.id]">
								 <el-checkbox 
							</Upload>
							<template v-else-if="item.type=='radio'">
								<el-radio 
									v-for="opt in item.optionList" 
									:key="opt.value" 
									:label="opt.value">
									{{opt.label}}
								</el-checkbox>
							</el-checkbox-group>
									v-model="form[item.id]" 
									:label="opt.value">{{opt.label}}</el-radio>
							</template>
							<template v-else-if="item.type=='checkbox'">
								<el-checkbox-group 
									@change="onCheckboxChange($event, item)"
									v-model="form[item.id]">
									<el-checkbox 
										v-for="opt in item.optionList" 
										:key="opt.value" 
										:label="opt.value">
										{{opt.label}}
									</el-checkbox>
								</el-checkbox-group>
							</template>
							<el-input-number v-else-if="item.type=='inputNumber'" v-model="form[item.id]" :controls-position="item.controlsPosition||''" :placeholder="item.placeholder" :min="item.min||''" :max="item.max"></el-input-number>
							<template v-else-if="item.type=='richtext'">
								<quill-editor 
									ref="formQuillTextEditor"
									v-model="form[item.id]" 
									@blur="onEditorBlur($event, item)"
									@focus="onEditorFocus($event, item)"
									:options="resetEditorOption(item.editorOption)" 
									@ready="onEditorReady($event, item)"  
									@change="onEditorChange($event, item)">
								</quill-editor>
								<el-upload style="display:none"  :action="UploadUrl" :show-file-list="false" :before-upload='newEditorbeforeupload'  :on-success='newEditorSuccess'
									ref="uniqueId" id="uniqueId">
								</el-upload >
							</template>
						</template>
						<el-input-number v-else-if="item.type=='inputNumber'" v-model="form[item.id]" :controls-position="item.controlsPosition||''" :placeholder="item.placeholder" :min="item.min||''" :max="item.max"></el-input-number>
					</template>
				</el-form-item>
			</el-col>
					</el-form-item>
				</el-col>
			</template>
		</el-row>
	</div>
</template>
<script>
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import {quillEditor} from 'vue-quill-editor'
import Upload from './Upload'
import {pickerOptions} from '../js/common'
import Tools from '../../utils/tool'
import defaultEditorOption from './editOptions'
export default {
	props: {
		fields: {},
@ -100,7 +118,8 @@ export default {
		form: {},
	},
	components:{
		Upload
		Upload,
		quillEditor
	},
	computed:{
		
@ -109,23 +128,14 @@ export default {
		return {
			rows: "",
			pickerOptions,
			uploadLoading: false,
			UploadUrl: Tools.upload_stream_url
		}
	},
	created(){
		var rows = [], count = 0, temp = []
		this.fields.forEach((v, i) => {
			count += (v.span || 1)
			if(count > this.columnNum){
				rows.push(temp)
				temp = [v]
				count = v.span
			} else {
				temp.push(v)
			}
			this.loadDict(v)
		});
		rows.push(temp)
		this.rows = rows
	},
	mounted() {
		
@ -161,6 +171,61 @@ export default {
				item.onChange(exist)
			}
		},
		//富文本编辑  新增 start
		resetEditorOption(editorOption){
			if(editorOption){
				return editorOption
			}
			return defaultEditorOption
		},
		onEditorBlur(editor) {
          	this.$emit('onEditorBlur', {editor, item})
		},
		onEditorFocus(editor) {
			this.$emit('onEditorFocus', {editor, item})
		},
		onEditorReady(editor) {
            this.$emit('onEditorReady', {editor, item})
		},
		onEditorChange({editor, html, text}, item) {
			this.$emit('onEditorChange', {editor, html, text, item})
        },
        newEditorbeforeupload(file){                       
            var $uptypes = ["image/jpg", "image/png",'image/jpeg'];
            const isJPG = $uptypes.indexOf(file.type) > -1;
            const isLt3M = file.size / 1024 / 1024 < 3;
            this.uploadLoading = this.$loading({
                background: 'rgba(0, 0, 0, 0.2)',
                text: '上传中'
            })
            if (!isJPG) {
                this.uploadLoading.close()
                this.$message.error("上传头像图片只能是 JPG/PNG 格式!");
            }
            if (!isLt3M) {
                this.uploadLoading.close()
                this.$message.error("上传头像图片大小不能超过 3MB!");
            }
            return isJPG && isLt3M;  
                                                              
        },
        newEditorSuccess(res, file, fileList){
			var vm = this
            if(res.status==200){ 
                var image = Tools.formatImgUrl(res.obj.fullUri),
                    addImgRange = this.$refs.formQuillTextEditor.quill.getSelection()
                var length = addImgRange.index,quill = vm.$refs.formQuillTextEditor.quill
                    quill.insertEmbed(addImgRange != null?length:0, 'image',image)
                    quill.setSelection(length + 1);
            }else{ 
                vm.$message.error("图片上传失败!"); 
            }
            if (this.uploadLoading) {
                this.uploadLoading.close()
            }
		},
		//富文本编辑  新增  end
	}
}
</script>
@ -172,6 +237,9 @@ export default {
		/deep/ .el-form-item__content{
			text-align: left;
		}
		/deep/ .ql-editor{
			min-height: 150px;
		}
	}
}
</style>

+ 6 - 1
src/components/TablePage/index.vue

@ -75,7 +75,7 @@
							v-if="item.isHide!==true" 
							:key="i" 
							:prop="item.id" 
							v-bind="item"
							v-bind="resetBind(item) "
							:label="item.label" 
							:width="item.width||''" 
							:align="item.align || 'left'" 
@ -236,6 +236,11 @@ export default {
					v.optionList = options
				}
			})
		},
		resetBind(item){
			var tmp = _.assign({}, item)
			delete tmp['type']
			return tmp
		}
	}
}