js 动态改变Input/Textarea值,vue双向绑定数据没有改变
给 input、textarea 组件设置快捷录入操作
- vue 自带的修饰键+keydown 事件
- js 原生事件委托 onkeydown 事件
一、vue 自带的修饰键+keydown 事件
<input @keydown.ctrl.81="setValue">
这个实现非常方便简单,但是每个 input、textarea 都得去绑定,非常的麻烦
二、js 原生事件委托 onkeydown 事件
<template>
<div id="app">
<div class="oper-c">
<br /><br />
<input type="text" v-model="inputStr" />
<br /><br />
<textarea v-model="textareaStr" />
</div>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
inputStr: "input str",
textareaStr: "textarea str",
};
},
destroyed() {
window.removeEventListener('resize', this.resizeWin)
},
mounted() {
const operInput = document.querySelector(".oper-c input");
const operTextarea = document.querySelector(".oper-c textarea");
operInput.onkeydown = (e) => {
if (e.altKey) {
if (e.keyCode === 81) {
// e.target.value = "快捷键插入";
this.insertAtCaret(e.target, "快捷键插入")
e.target.dispatchEvent(new Event("input"));
}
}
};
operInput.onselect = (e) => {
this.setCaret(e)
};
operTextarea.onkeydown = (e) => {
if (e.altKey) {
if (e.keyCode === 81) {
// e.target.value = "快捷键插入";
this.insertAtCaret(e.target, "快捷键插入")
e.target.dispatchEvent(new Event("input"));
}
}
};
operTextarea.onselect = (e) => {
this.setCaret(e)
};
},
methods: {
setCaret(obj) {
if (obj.createTextRange) {
obj.caretPos = document.selection.createRange().duplicate();
}
},
insertAtCaret(obj, value) {
if (document.all) {
if (obj.createTextRange && obj.caretPos) {
var caretPos = obj.caretPos;
caretPos.text =
caretPos.text.charAt(caretPos.text.length - 1) == " "
? value + " "
: value;
} else {
obj.value = value;
}
} else {
if (obj.setSelectionRange) {
var rangeStart = obj.selectionStart;
var rangeEnd = obj.selectionEnd;
var tempStr1 = obj.value.substring(0, rangeStart);
var tempStr2 = obj.value.substring(rangeEnd);
obj.value = tempStr1 + value + tempStr2;
} else {
alert(
"This version of Mozilla based browser does not support setSelectionRange"
);
}
}
}
},
watch: {
inputStr: {
handler(val) {
console.log("input值变化:", val);
},
},
textareaStr: {
handler(val) {
console.log("textarea值变化:", val);
},
},
},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
text-align: center;
}
</style>
是不是通过事件委托方法,比每个组件都去绑修饰符要简单、快捷很多。
注意:这里运用原生 js 插入 input 、textarea 值,并不会改变 vue 双向绑定数据,这里主动通知浏览器进行事件分发,让Vue监听到
e.target.dispatchEvent(new Event(“input”));
为什么会出现这种情况?
Vue只监听浏览器原生事件,而jQuery改变输入框的值属于jQuery定义的事件,这个Vue是无法监听到的。
还有这里是能用原生 js 实现,没有考滤多个 Input 、textarea 的情况, 可以通过 document.querySelectorAll 来处理
当然用 jquery 的方法也会更加方便,只是这个包有点大,具体可以根据自身项目选择最优方式
$(".oper-c").on("keydown", 'input, textarea', function(){});
$(".oper-c").on("select", 'input, textarea', function(){});