jsデータ双方向バインドの実現
3005 ワード
前の記事「js実装データ一方向バインド」に続き、前の記事では原生jsでデータの一方向バインドが実現された.この記事では、jsでデータの双方向バインドを実現する方法について説明します.バインド方式はvueの
ラベルの作成
変数nameをv-modelプロパティでバインドする入力ボックスを作成します.ここではvueバインドの形式を模倣しているだけで、コードにはvue依存は導入されていません.完全に原生jsによって実現される.
ワンウェイバインド
ここで私たちはまた一方向バインドを実現しました.データの双方向バインドを実現するには簡単です.render関数を少し修正するだけです.
双方向バインド
変更されたrender関数は、v-modelプロパティを持つinputラベルをフィルタリング、遍歴して取得し、データをビューにバインドし、ビューの変更によってデータの更新がトリガーされ、データの双方向バインドが実現されます.複雑に見えるバインドメカニズムは、私たちがよく知っているjsのいくつかの基礎的な操作によって実現されています.
完全なコード
v-model
命令を模倣する.ラベルの作成
:{{name}}
変数nameをv-modelプロパティでバインドする入力ボックスを作成します.ここではvueバインドの形式を模倣しているだけで、コードにはvue依存は導入されていません.完全に原生jsによって実現される.
ワンウェイバインド
let el = document.getElementById('app');
let template = el.innerHTML;
let _data = {
name: '_BuzzLy'
};
let data = new Proxy(_data, {
set(obj, name, value) {
obj[name] = value;
render();
}
});
render();
function render() {
el.innerHTML = template.replace(/\{\{\w+\}\}/g, str => {
str = str.substring(2, str.length - 2);
return _data[str];
});
}
ここで私たちはまた一方向バインドを実現しました.データの双方向バインドを実現するには簡単です.render関数を少し修正するだけです.
双方向バインド
function render() {
el.innerHTML = template.replace(/\{\{\w+\}\}/g, str => {
str = str.substring(2, str.length - 2);
return _data[str];
});
// input
Array.from(el.getElementsByTagName('input'))
// v-model
.filter(ele => ele.getAttribute('v-model'))
// input
.forEach(input => {
// v-model key, key value input
// =>
let name = input.getAttribute('v-model');
input.value = _data[name];
// input
input.oninput = function () {
// input , data
// =>
data[name] = this.value;
};
});
}
変更されたrender関数は、v-modelプロパティを持つinputラベルをフィルタリング、遍歴して取得し、データをビューにバインドし、ビューの変更によってデータの更新がトリガーされ、データの双方向バインドが実現されます.複雑に見えるバインドメカニズムは、私たちがよく知っているjsのいくつかの基礎的な操作によって実現されています.
完全なコード
<div id="div1">
<input type="text" v-model="name"/>
<br/> :{{name}}
</div>
<script>
let el = document.getElementById('div1');
let template = el.innerHTML;
let _data = {
name: '_BuzzLy'
};
let data = new Proxy(_data, {
set(obj, name, value) {
obj[name] = value;
render();
}
});
render();
function render() {
el.innerHTML = template.replace(/\{\{\w+\}\}/g, str => {
str = str.substring(2, str.length - 2);
return _data[str];
});
Array.from(el.getElementsByTagName('input'))
.filter(ele => ele.getAttribute('v-model'))
.forEach(input => {
let name = input.getAttribute('v-model');
input.value = _data[name];
input.oninput = function () {
data[name] = this.value;
};
});
}
</script>
</code></pre>
</article>
</div>
</div>