Электронно Vue Screenshot Функция | Электрон + Vue Достичь Div Editable Contabletable Вставить Smiley на основе
Чтобы не использовать vue для ручной сборки электронных приложений. электрон-вью использует все преимуществаvue-cli
в качестве инструмента для строительных лесов, а также наличиеvue-loader
изwebpack
,electron-packager
илиelectron-builder
, а также некоторые из наиболее часто используемых плагинов, такие какvue-router
,vuex
и т.п.
Имитация редактора чата WeChat для вставки смайликов
Как реализовать клиент WeChat для вставки смайликов в курсор редактора? Обычно есть две идеи реализации:
-
общий метод (реализация ввода/текстовой области)
Реализовано через входную или текстуру, вставьте [Smiley], (: 12 тегов Emoji в текстовом поле, а также анализируют теги при отображении
Как на рисунке: эффект может быть достигнут следующим кодом
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
<div class="col col-sm-12">
<button class="btn btn-success" data-emoj="[笑脸]">[笑脸]</button>
<button class="btn btn-success" data-emoj="[奋斗]">[奋斗]</button>
<button class="btn btn-success" data-emoj="[:17]">[:17]</button>
</div>
<div class="col col-sm-12">
<textarea class="form-control" id="content" rows="10"></textarea>
</div>
</div>
</div>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script>
(function ($) {
$.fn.extend({
insertEmojAtCaret: function (myValue) {
var $t = $(this)[0];
if (document.selection) {
this.focus();
sel = document.selection.createRange();
sel.text = myValue;
this.focus();
} else if ($t.selectionStart || $t.selectionStart == '0') {
var startPos = $t.selectionStart;
var endPos = $t.selectionEnd;
var scrollTop = $t.scrollTop;
$t.value = $t.value.substring(0, startPos) + myValue + $t.value.substring(endPos, $t.value.length);
this.focus();
$t.selectionStart = startPos + myValue.length;
$t.selectionEnd = startPos + myValue.length;
$t.scrollTop = scrollTop;
} else {
this.value += myValue;
this.focus();
}
}
});
})(jQuery);
$("button").on("click", function() {
$("#content").insertEmojAtCaret($(this).attr("data-emoj"));
});
</script>
</body>
</html>
Но описанный выше метод - это не то, что я хочу, чтобы вставить эффект изображения смайлика в поле редактирования.
-
редактируемые атрибуты div (настраивать
contenteditable="true"
выполнить)
Используйте div для имитации настроекcontenteditable="true"
Реализуйте влияние богатого текстового редактора. Этот метод может вставить смазочные изображения в редактируемой области. Поскольку DIV не может быть связан с V-образностью в Vue, она должна быть транспонирована.
Как показано выше: установив divcontenteditable="true"Для достижения функции про-тест прошел.
Реализовать идеи
Создайте новый редактируемый компонент chatInput.vue, который прослушивает изменения данных и возвращается к родительскому компоненту.
<template>
...
<chatInput ref="chatInput" v-model="editorText" />
</template>
...
export default {
data () {
return {
editorText: '',
...
}
},
...
}
2. Значение editorText, переданное в v-model, получается и отслеживается на предмет изменений в реквизите дочернего компонента.Официальное описание Vue:
v-модель в компоненте по умолчанию будет использовать свойство с именем value и событие с именем input , а значение v-model будет передано в свойство в дочернем компоненте.
Talent.v UE JS.org/V2/expensive/co…
export default {
props: {
value: { type: String, default: '' }
},
data () {
return {
editorText: this.value,
...
}
},
watch: {
value() {
...
}
},
}
3. Отслеживая полученное значение prop и присваивая значение параметру v-html в подкомпоненте, реализуется двусторонняя привязка.
В vue компонент div[contenteditable=true] используется в качестве поля ввода текста. После не ручного ввода значений, например, нажатия на выражение, курсор будет потерян. Следующий код можно использовать для позиционирования курсор до конца
function setLastAtCaret(obj) {
console.log(obj)
console.log(window.getSelection)
console.log(document.selection)
if (window.getSelection) { //ie11 10 9 ff safari
obj.focus(); //解决ff不获取焦点无法定位问题
var range = window.getSelection(); //创建range
range.selectAllChildren(obj); //range 选择obj下所有子内容
range.collapseToEnd(); //光标移至最后
} else if (document.selection) { //ie10 9 8 7 6 5
var range = document.selection.createRange(); //创建选择对象
//var range = document.body.createTextRange();
range.moveToElementText(obj); //range定位到obj
range.collapse(false); //光标移至最后
range.select();
}
}
Но этот метод каждый раз, когда он позиционируется в конец ввода, не идеален~~
В этом случае благодаря этому совместному использованию прекрасно решается эффект вставки смайликов в курсор редактируемого поля div в vue.
/**
* 光标处插入内容
* @param html 需要插入的内容
*/
insertHtmlAtCaret(html) {
let sel, range;
if(!this.$refs.editor.childNodes.length) {
this.$refs.editor.focus()
}
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
let el = document.createElement("div");
el.appendChild(html)
var frag = document.createDocumentFragment(), node, lastNode;
while ((node = el.firstChild)) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if (document.selection && document.selection.type != "Control") {
// IE < 9
document.selection.createRange().pasteHTML(html);
}
this.handleInput()
}
Компонент chatInput.vue
Ниже приведена реализация возможности редактирования в vue+electron.contenteditable="true"
Вставить полный код выражения в месте курсора
<!-- vue实现contenteditable功能 -->
<template>
<div
ref="editor"
class="editor"
contenteditable="true"
v-html="editorText"
@input="handleInput"
@focus="handleFocus"
@blur="handleBlur">
</div>
</template>
<script>
export default {
props: {
value: { type: String, default: '' }
},
data () {
return {
editorText: this.value,
isChange: true,
}
},
watch: {
value() {
if(this.isChange) {
this.editorText = this.value
}
}
},
methods: {
handleInput() {
this.$emit('input', this.$el.innerHTML)
},
// 清空编辑器
handleClear() {
this.$refs.editor.innerHTML = ''
this.$refs.editor.focus()
},
// 获取焦点
handleFocus() {
this.isChange = false
this.$emit('focusFn')
},
// 失去焦点
handleBlur() {
this.isChange = true
this.$emit('blurFn')
},
/**
* 光标处插入内容
* @param html 需要插入的内容
*/
insertHtmlAtCaret(html) {
let sel, range;
if(!this.$refs.editor.childNodes.length) {
this.$refs.editor.focus()
}
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
let el = document.createElement("div");
el.appendChild(html)
var frag = document.createDocumentFragment(), node, lastNode;
while ((node = el.firstChild)) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if (document.selection && document.selection.type != "Control") {
// IE < 9
document.selection.createRange().pasteHTML(html);
}
this.handleInput()
}
}
}
</script>
<style>
</style>
div в vuecontenteditable = 'true'
Также поддерживает событие вставки
Изображения чата можно отправлять, вставляя скриншоты в редактируемые поля.
// 可编辑div contenteditable中粘贴发送图片
handlePastImage {
let that = this
this.$refs.editor.addEventListener('paste', function(e) {
let cbd = e.clipboardData
let ua = window.navigator.userAgent
if(!(e.clipboardData && e.clipboardData.items)) return
if(cbd.items && cbd.items.length === 2 && cbd.items[0].kind === "string" && cbd.items[1].kind === "file" &&
cbd.types && cbd.types.length === 2 && cbd.types[0] === "text/plain" && cbd.types[1] === "Files" &&
ua.match(/Macintosh/i) && Number(ua.match(/Chrome\/(\d{2})/i)[1]) < 49){
return;
}
for(var i = 0; i < cbd.items.length; i++){
var item = cbd.items[i];
console.log(item);
console.log(item.kind);
if(item.kind == "file"){
var blob = item.getAsFile();
if(blob.size === 0){
return;
}
// 插入图片记录
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function(){
var _img = this.result;
// ***返回图片给父组件
that.$emit('pasteFn', _img)
}
}
}
})
},
electronic-vue реализует функцию скриншота
1. Вызвать собственный API снимков экрана модуля через поддержку Electron: desktopCapturer
Для этого метода перейдите на официальный сайт api Ниже приводится подробное описание второго метода.
2. Запустите файл .exe через командную строку, чтобы вызвать dll
передано в nodejsexecFile
Метод заключается в выполнении исполняемого файла, исполняемый файл вызывает dll в каталоге того же уровня и вызывает инструмент для создания снимков экрана.
Упакуйте файлы exe и dll вstatic
каталог, выполнить через абсолютный путь. exe и dll можно найти в сети.
screenShot() {
return new Promise((resolve) => {
const { execFile } = require('child_process')
var screenWin = execFile('./static/PrintScr.exe')
screenWin.on('exit', function(code) {
let pngs = require('electron').clipboard.readImage().toPNG()
let imgData = new Buffer.from(pngs, 'base64')
let imgs = 'data:image/png;base64,' + btoa(new Uint8Array(imgData).reduce((data, byte) => data + String.fromCharCode(byte), ''))
resolve(imgs)
})
})
},
Что ж, вышеизложенное основано на electro + vue, чтобы реализовать небольшой обмен записями редактора чата, вставляющего выражения и скриншоты, и мы продолжим делиться некоторыми электронными боевыми проектами в будущем.
Чат таро | реакция + имитация таро Интерфейс приложения чата WeChat | экземпляр чата таро