<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>模拟VUE双向绑定实现</title>
<style>
#app {
background: #eee;
}
</style>
</head>
<body>
<div id="app"></div>
<script>
var app = document.getElementById("app");
var isEnd = true;
function bindDom() {
var input1 = document.getElementById("input1");
input1.addEventListener("compositionstart", function () {
console.log("开始输入中文");
isEnd = false;
});
input1.addEventListener("compositionend", function () {
isEnd = true;
console.log("结束输入中文");
});
input1.addEventListener("input", function (e) {
setTimeout(function () {
console.log("触发input");
if(isEnd){
inputChange(e.target);
}
}, 0)
});
}
function inputChange(dm) {
console.log(dm)
var pos = dm.selectionEnd;
vm.data.inputValue = dm.value;
console.log(pos);
var input1 = document.getElementById("input1");
input1.focus();
input1.setSelectionRange(pos, pos);
}
var tpl = '<input id="input1" type="text" value="{{inputValue}}"><div>{{inputValue}}</div>';
function Vue() {
this.data = {
inputValue: 0
};
}
var vm = new Vue();
Object.keys(vm.data).forEach(function (key) {
vm.data['_' + key] = vm.data[key];
Object.defineProperty(vm.data, key, {
get: function() {
console.log("读取", this['_' + key]);
return this['_' + key];
},
set: function(value) {
console.log("设置", value);
this['_' + key] = value;
app.innerHTML = Template(tpl, vm.data);
bindDom();
}
});
});
var Template = function (tpl, data) {
var pattern = /\{\{([^\}\}]+)?\}\}/g;
var body = "return '";
body += tpl.replace(pattern, function (m, g) {
return "' + this." + g.trim() + " + '";
});
body += "';";
return new Function(body.replace(/[\t\n\r]/g, '')).apply(data);
};
app.innerHTML = Template(tpl, vm.data);
bindDom();
</script>
</body>
</html>