vue 的 v-model 雙向綁定 簡單實(shí)現(xiàn)

html代碼:

<!DOCTYPE html>

<html lang="en">

<head>

? ? <meta charset="UTF-8">

? ? <meta http-equiv="X-UA-Compatible" content="IE=edge">

? ? <meta name="viewport" content="width=device-width, initial-scale=1.0">

? ? <title>Document</title>

</head>

<body>

? ? <div id="app">

? ? ? ? {{ clickHere }}

? ? ? ? <h1>{{ str }}</h1>

? ? ? ? <h2 @click="func1">{{ clickHere }}</h2>

? ? ? ? <input v-model="str" type="text">

? ? </div>

? ? <script src="../js/myVue.js"></script>

? ? <script>

? ? ? ? let myVue = new Vue({

? ? ? ? ? ? el: "#app",

? ? ? ? ? ? data: {

? ? ? ? ? ? ? ? str: "你好234",

? ? ? ? ? ? ? ? clickHere: "點(diǎn)擊這里",

? ? ? ? ? ? },

? ? ? ? ? ? methods: {

? ? ? ? ? ? ? ? func1(e) {

? ? ? ? ? ? ? ? ? ? this.clickHere = "點(diǎn)擊這里aaa"

? ? ? ? ? ? ? ? ? ? console.log(this.clickHere);

? ? ? ? ? ? ? ? ? ? console.log(this);

? ? ? ? ? ? ? ? ? ? console.log(e);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? })

? ? </script>

</body>

</html>

--------------------------------------------------------

js代碼:?

class Vue {

? ? constructor(options) {

? ? ? ? this.options = options;

? ? ? ? this.$el = document.querySelector(options.el);

? ? ? ? this.$data = options.data;

? ? ? ? this.$methods = options.methods;

? ? ? ? this.$watchEvent = {};

? ? ? ? this.proxyData();

? ? ? ? this.compile(this.$el);

? ? }

? ? proxyData() {

? ? ? ? let that = this;

? ? ? ? for (let key in that.$data) {

? ? ? ? ? ? // 劫持 Vue(this) 的屬性

? ? ? ? ? ? Object.defineProperty(

? ? ? ? ? ? ? ? that,

? ? ? ? ? ? ? ? key,

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? get: function () {

? ? ? ? ? ? ? ? ? ? ? ? console.log("獲取 data." + key + "的值: ", that.$data[key])

? ? ? ? ? ? ? ? ? ? ? ? return that.$data[key];

? ? ? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? ? ? set: function (val) {

? ? ? ? ? ? ? ? ? ? ? ? that.$data[key] = val;

? ? ? ? ? ? ? ? ? ? ? ? if (that.$watchEvent[key]) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? that.$watchEvent[key].forEach((item, index) => {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? item.update()

? ? ? ? ? ? ? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? )

? ? ? ? }

? ? }

? ? compile(node) {

? ? ? ? let that = this;

? ? ? ? node.childNodes.forEach((item, index) => {

? ? ? ? ? ? // nodeType == 1 => ?node 節(jié)點(diǎn), 帶標(biāo)簽

? ? ? ? ? ? if (item.nodeType == 1) {

? ? ? ? ? ? ? ? // 遞歸節(jié)點(diǎn)-----------------------------------------------------------

? ? ? ? ? ? ? ? if (item.childNodes.length > 0) {

? ? ? ? ? ? ? ? ? ? // 數(shù)據(jù)綁定

? ? ? ? ? ? ? ? ? ? this.compile(item);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? // @click 方法綁定-----------------------------------------------------------

? ? ? ? ? ? ? ? if (item.hasAttribute("@click")) {

? ? ? ? ? ? ? ? ? ? // 獲取方法名

? ? ? ? ? ? ? ? ? ? let funName = item.getAttribute("@click").trim();

? ? ? ? ? ? ? ? ? ? item.addEventListener('click', function (event) {

? ? ? ? ? ? ? ? ? ? ? ? // 執(zhí)行該方法名對(duì)應(yīng)的方法 .call() 改變this指向?yàn)閂ue 對(duì)象

? ? ? ? ? ? ? ? ? ? ? ? that.$methods[funName].call(that, event);

? ? ? ? ? ? ? ? ? ? ? ? console.log("compile : ", that);

? ? ? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? // v-model 綁定-----------------------------------------------------------

? ? ? ? ? ? ? ? if (item.hasAttribute("v-model")) {

? ? ? ? ? ? ? ? ? ? // 獲取方法名

? ? ? ? ? ? ? ? ? ? let funName = item.getAttribute("v-model").trim();

? ? ? ? ? ? ? ? ? ? // 將數(shù)據(jù)綁定到視圖

? ? ? ? ? ? ? ? ? ? item.value = that[funName];

? ? ? ? ? ? ? ? ? ? item.addEventListener('input', function (event) {

? ? ? ? ? ? ? ? ? ? ? ? // 監(jiān)聽視圖數(shù)據(jù)綁定到 model

? ? ? ? ? ? ? ? ? ? ? ? that[funName] = item.value;

? ? ? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? //-----------------------------------------------------------

? ? ? ? ? ? }

? ? ? ? ? ? // nodeType == 3 ?=> 文本節(jié)點(diǎn) 不包含標(biāo)簽

? ? ? ? ? ? if (item.nodeType == 3) {

? ? ? ? ? ? ? ? let reg = /\{\{(.*?)\}\}/g;

? ? ? ? ? ? ? ? let text = item.textContent;

? ? ? ? ? ? ? ? item.textContent = text.replace(reg, function (match, vmKey) {

? ? ? ? ? ? ? ? ? ? /*

? ? ? ? ? ? ? ? ? ? ? ? function 參數(shù) : ?第一個(gè)是 匹配的全部字符

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 第二個(gè)是 第一個(gè)元組

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 第三個(gè)是 第二個(gè)元組

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ...

? ? ? ? ? ? ? ? ? ? */

? ? ? ? ? ? ? ? ? ? vmKey = vmKey.trim();

? ? ? ? ? ? ? ? ? ? if (that[vmKey]) {

? ? ? ? ? ? ? ? ? ? ? ? console.log(that[vmKey]);

? ? ? ? ? ? ? ? ? ? ? ? let watcher = new Watch(that, vmKey, item, "textContent")

? ? ? ? ? ? ? ? ? ? ? ? if (that.$watchEvent[vmKey]) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? that.$watchEvent[vmKey].push(watcher)

? ? ? ? ? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? ? ? ? ? that.$watchEvent[vmKey] = [];

? ? ? ? ? ? ? ? ? ? ? ? ? ? that.$watchEvent[vmKey].push(watcher)

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? return that.$data[vmKey];

? ? ? ? ? ? ? ? })

? ? ? ? ? ? }

? ? ? ? });

? ? }

}

// 用來動(dòng)態(tài)更新視圖

class Watch {

? ? constructor(vm, key, node, attr) {

? ? ? ? this.vm = vm;

? ? ? ? this.key = key;

? ? ? ? this.node = node;

? ? ? ? this.attr = attr;

? ? }

? ? update() {

? ? ? ? this.node[this.attr] = this.vm[this.key];

? ? }

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容