產品要作一個相似豆瓣那樣的發佈功能,須要在文章插入圖片,剛接到這個需求時,一臉懵逼。沒辦法,爲了餬口,在看了一些大佬的文章後,終於實現了。廢話很少說,直接上代碼!javascript
// parent.vue
<template>
<div>
<editor v-model="content" ref="myEditor"></editor>
</div>
</template>
<script>
import editor from "@/components/editor";
export default {
name: "CommentPublish",
components: {
editor
},
data() {
return {
photoPng,
commentBanner,
title: '',
content: '',
fileList: []
}
},
methods: {
// 插入圖片,實際中應該是上傳完圖片而後插入
insertImg() {
const HTML = `<div><img src="yourImage.png"></div>`
this.$refs.myEditor.insert(HTML)
}
}
}
</script>
複製代碼
// child.vue
<template>
<div class="editor-wrap"
v-html="editorHtml"
ref="editor"
contenteditable="true"
@focus="isLocked = true"
@blur="isLocked = false" // IOS下blur不能獲取光標位置,因此捨棄
@click="saveRange"
@input="changeText">
</div>
</template>
<script>
export default {
name: "editor",
props: ['value'],
data() {
return {
editorHtml: this.value,
isLocked: false,
range: ''
}
},
watch: {
'value'(val){
if (!this.isLocked && !this.editorHtml) { // 解決光標錯位的問題
this.editorHtml = val;
}
}
},
methods: {
changeText() {
this.$emit('input', this.$el.innerHTML);
this.saveRange()
},
// 失焦時記錄焦點位置
saveRange() {
const selection = window.getSelection ? window.getSelection() : document.getSelection()
this.range = selection.getRangeAt(0)
},
// 設置焦點位置
setRange() {
const selection = window.getSelection ? window.getSelection() : document.getSelection()
selection.removeAllRanges()
if (this.range) {
selection.addRange(this.range)
} else {
this.$refs.editor.focus()
}
},
insert(html) {
this.setRange()
document.execCommand("insertHTML", false, html);
}
}
</script>
複製代碼