Jadual Kandungan
Prinsip pengikatan dua hala data Vue
Proses pelaksanaan
Paparkan Pemerhati
Melaksanakan Pemerhati
Implement Compile
添加解析事件
完整版 myVue
Rumah hujung hadapan web View.js Apakah prinsip pengikatan dua hala dalam vuejs

Apakah prinsip pengikatan dua hala dalam vuejs

Sep 28, 2021 pm 02:06 PM
vuejs Pengikatan dua hala

Prinsip pengikatan dua hala dalam vuejs: menggunakan mod rampasan data dan penerbitan-langganan, rampasan penetap dan getter setiap harta melalui "Object.defineProperty()", menerbitkan mesej kepada pelanggan apabila data berubah , mencetuskan Panggilan balik pendengaran yang sepadan digunakan untuk mengemas kini paparan.

Apakah prinsip pengikatan dua hala dalam vuejs

Persekitaran pengendalian tutorial ini: sistem Windows 7, vue versi 2.9.6, komputer DELL G3.

Prinsip pengikatan dua hala data Vue

Kegunaan utama Vue untuk melaksanakan pengikatan data dua hala ialah: mod rampasan data dan terbitkan-langgan, menggunakan kaedah Object.defineProperty() untuk merampas data , dan kemudian memberitahu keluaran Pemerhati (objek tema) memberitahu semua pemerhati Selepas pemerhati menerima pemberitahuan, ia akan mengemas kini paparan.

https://jsrun.net/RMIKp/embedded/all/light

Rangka kerja MVVM terutamanya merangkumi dua aspek, perubahan data mengemas kini paparan dan perubahan paparan mengemas kini data.

Lihat perubahan data kemas kini Jika ia adalah teg seperti input, anda boleh menggunakan acara oninput..

Perubahan data mengemas kini paparan Anda boleh menggunakan kaedah set Object.definProperty() untuk mengesan perubahan data Apabila Perubahan data mencetuskan fungsi ini dan mengemas kini paparan.

Proses pelaksanaan

Kami tahu cara melaksanakan pengikatan dua hala Pertama, kami perlu merampas dan memantau data, jadi kami perlu menyediakan fungsi Pemerhati untuk memantau perubahan dalam semua sifat. .

Jika atribut berubah, anda perlu memberitahu pemerhati pelanggan untuk melihat sama ada data perlu dikemas kini Jika terdapat berbilang pelanggan, anda memerlukan Dep untuk mengumpulkan pelanggan ini, dan kemudian antara pemerhati pendengar dan pengurusan bersatu pemerhati.

Penghurai arahan, menyusun, juga diperlukan untuk mengimbas dan menghuraikan nod dan atribut yang perlu dipantau.

Jadi, prosesnya lebih kurang seperti ini:

  • Laksanakan Pemerhati pendengar untuk merampas dan memantau semua sifat, dan memaklumkan pelanggan jika terdapat perubahan.

  • Laksanakan Pemerhati pelanggan Apabila menerima pemberitahuan perubahan harta benda, laksanakan fungsi yang sepadan, kemudian kemas kini paparan dan gunakan Dep untuk mengumpul Pemerhati ini.

  • Melaksanakan Parser Compile, yang digunakan untuk mengimbas dan menghuraikan arahan berkaitan nod dan memulakan pelanggan yang sepadan mengikut templat permulaan.

Apakah prinsip pengikatan dua hala dalam vuejs

Paparkan Pemerhati

Pemerhati ialah pendengar data Kaedah teras ialah menggunakan Object.defineProperty() untuk menambah setter dan secara rekursif kaedah getter kepada sifat untuk pemantauan.

var library = {
  book1: {
    name: "",
  },
  book2: "",
};
observe(library);
library.book1.name = "vue权威指南"; // 属性name已经被监听了,现在值为:“vue权威指南”
library.book2 = "没有此书籍"; // 属性book2已经被监听了,现在值为:“没有此书籍”

// 为数据添加检测
function defineReactive(data, key, val) {
  observe(val); // 递归遍历所有子属性
  let dep = new Dep(); // 新建一个dep
  Object.defineProperty(data, key, {
    enumerable: true,
    configurable: true,
    get: function() {
      if (Dep.target) {
        // 判断是否需要添加订阅者,仅第一次需要添加,之后就不用了,详细看Watcher函数
        dep.addSub(Dep.target); // 添加一个订阅者
      }
      return val;
    },
    set: function(newVal) {
      if (val == newVal) return; // 如果值未发生改变就return
      val = newVal;
      console.log(
        "属性" + key + "已经被监听了,现在值为:“" + newVal.toString() + "”"
      );
      dep.notify(); // 如果数据发生变化,就通知所有的订阅者。
    },
  });
}

// 监听对象的所有属性
function observe(data) {
  if (!data || typeof data !== "object") {
    return; // 如果不是对象就return
  }
  Object.keys(data).forEach(function(key) {
    defineReactive(data, key, data[key]);
  });
}
// Dep 负责收集订阅者,当属性发生变化时,触发更新函数。
function Dep() {
  this.subs = {};
}
Dep.prototype = {
  addSub: function(sub) {
    this.subs.push(sub);
  },
  notify: function() {
    this.subs.forEach((sub) => sub.update());
  },
};
Salin selepas log masuk

Dalam analisis idea, perlu ada Dep pelanggan mesej pelanggan yang boleh digunakan untuk mengumpul pelanggan dan melaksanakan fungsi kemas kini yang sepadan apabila atribut berubah.

Dari sudut pandangan kod, menambahkan Dep pelanggan pada pengambil adalah untuk mencetuskan Pemerhati apabila ia dimulakan oleh itu, adalah perlu untuk menentukan sama ada pelanggan diperlukan.

Dalam setter, jika ada perubahan data, semua pelanggan akan dimaklumkan, dan kemudian pelanggan akan mengemas kini fungsi yang sepadan.

Pada ketika ini, Pemerhati yang agak lengkap selesai Seterusnya, mula mereka bentuk Pemerhati.

Melaksanakan Pemerhati

Pemerhati pelanggan perlu menambah dirinya semasa pemulaan. subscriber Dep, kami sudah tahu bahawa Observer ialah operasi Watcher yang dilakukan apabila mendapat, jadi kami hanya perlu mencetuskan fungsi get yang sepadan apabila Watcher dimulakan untuk menambah operasi subscriber yang sepadan.

Bagaimana untuk mencetuskan get? Oleh kerana kita telah menetapkan Object.defineProperty(), kita hanya perlu mendapatkan nilai harta yang sepadan untuk mencetuskannya.

Kami hanya perlu menyimpan cache pelanggan pada Dep.target apabila Pemerhati pelanggan dimulakan dan mengalih keluarnya selepas penambahan itu berjaya.

function Watcher(vm, exp, cb) {
  this.cb = cb;
  this.vm = vm;
  this.exp = exp;
  this.value = this.get(); // 将自己添加到订阅器的操作
}

Watcher.prototype = {
  update: function() {
    this.run();
  },
  run: function() {
    var value = this.vm.data[this.exp];
    var oldVal = this.value;
    if (value !== oldVal) {
      this.value = value;
      this.cb.call(this.vm, value, oldVal);
    }
  },
  get: function() {
    Dep.target = this; // 缓存自己,用于判断是否添加watcher。
    var value = this.vm.data[this.exp]; // 强制执行监听器里的get函数
    Dep.target = null; // 释放自己
    return value;
  },
};
Salin selepas log masuk

Setakat ini, reka bentuk Pemerhati yang ringkas telah siap, dan kemudian dengan mengaitkan Pemerhati dan Pemerhati, pengikatan dua hala yang mudah boleh dicapai.

Oleh kerana parser Compile belum direka bentuk lagi, data templat boleh dikodkan dengan keras terlebih dahulu.

Tukar kod ke dalam penulisan pembina ES6 dan cuba pratontonnya.

https://jsrun.net/8SIKp/embedded/all/light

Kod ini tidak melaksanakan pengkompil tetapi terus dalam pembolehubah terikat Kami hanya Tetapkan data (nama) pada nod untuk mengikat, dan kemudian melaksanakan MyVue baharu pada halaman untuk mencapai pengikatan dua hala.

dan buat perubahan selepas dua saat anda dapat melihat bahawa halaman itu juga telah berubah.

// MyVue
proxyKeys(key) {
    var self = this;
    Object.defineProperty(this, key, {
        enumerable: false,
        configurable: true,
        get: function proxyGetter() {
            return self.data[key];
        },
        set: function proxySetter(newVal) {
            self.data[key] = newVal;
        }
    });
}
Salin selepas log masuk

Fungsi kod di atas adalah untuk memproksi kekunci this.data kepada ini, supaya saya boleh menggunakan this.xx dengan mudah untuk mendapatkan this.data.xx.

Implement Compile

Walaupun pengikatan data dua hala dilaksanakan di atas, keseluruhan proses tidak menghuraikan stor bahagian DOM, tetapi menggantikannya dengan tetap, jadi seterusnya kita perlu melaksanakan parser untuk melakukannya kerja penghuraian dan pengikatan data.

Langkah pelaksanaan penyusunan penghurai:

  • Menghuraikan arahan templat, menggantikan data templat dan mulakan paparan.

  • 将模板指定对应的节点绑定对应的更新函数,初始化相应的订阅器。

为了解析模板,首先需要解析 DOM 数据,然后对含有 DOM 元素上的对应指令进行处理,因此整个 DOM 操作较为频繁,可以新建一个 fragment 片段,将需要的解析的 DOM 存入 fragment 片段中在进行处理。

function nodeToFragment(el) {
  var fragment = document.createDocumentFragment();
  var child = el.firstChild;
  while (child) {
    // 将Dom元素移入fragment中
    fragment.appendChild(child);
    child = el.firstChild;
  }
  return fragment;
}
Salin selepas log masuk

接下来需要遍历各个节点,对含有相关指令和模板语法的节点进行特殊处理,先进行最简单模板语法处理,使用正则解析“{{变量}}”这种形式的语法。

function compileElement (el) {
    var childNodes = el.childNodes;
    var self = this;
    [].slice.call(childNodes).forEach(function(node) {
        var reg = /\{\{(.*)\}\}/; // 匹配{{xx}}
        var text = node.textContent;
        if (self.isTextNode(node) && reg.test(text)) {  // 判断是否是符合这种形式{{}}的指令
            self.compileText(node, reg.exec(text)[1]);
        }
        if (node.childNodes && node.childNodes.length) {
            self.compileElement(node);  // 继续递归遍历子节点
        }
    });
},
function compileText (node, exp) {
    var self = this;
    var initText = this.vm[exp];
    updateText(node, initText);  // 将初始化的数据初始化到视图中
    new Watcher(this.vm, exp, function (value) {  // 生成订阅器并绑定更新函数
        self.updateText(node, value);
    });
},
function updateText (node, value) {
    node.textContent = typeof value == 'undefined' ? '' : value;
}
Salin selepas log masuk

获取到最外层的节点后,调用 compileElement 函数,对所有的子节点进行判断,如果节点是文本节点切匹配{{}}这种形式的指令,则进行编译处理,初始化对应的参数。

然后需要对当前参数生成一个对应的更新函数订阅器,在数据发生变化时更新对应的 DOM。

这样就完成了解析、初始化、编译三个过程了。

接下来改造一个 myVue 就可以使用模板变量进行双向数据绑定了。

https://jsrun.net/K4IKp/embedded/all/light

添加解析事件

添加完 compile 之后,一个数据双向绑定就基本完成了,接下来就是在 Compile 中添加更多指令的解析编译,比如 v-model、v-on、v-bind 等。

添加一个 v-model 和 v-on 解析:

function compile(node) {
  var nodeAttrs = node.attributes;
  var self = this;
  Array.prototype.forEach.call(nodeAttrs, function(attr) {
    var attrName = attr.name;
    if (isDirective(attrName)) {
      var exp = attr.value;
      var dir = attrName.substring(2);
      if (isEventDirective(dir)) {
        // 事件指令
        self.compileEvent(node, self.vm, exp, dir);
      } else {
        // v-model 指令
        self.compileModel(node, self.vm, exp, dir);
      }
      node.removeAttribute(attrName); // 解析完毕,移除属性
    }
  });
}
// v-指令解析
function isDirective(attr) {
  return attr.indexOf("v-") == 0;
}
// on: 指令解析
function isEventDirective(dir) {
  return dir.indexOf("on:") === 0;
}
Salin selepas log masuk

上面的 compile 函数是用于遍历当前 dom 的所有节点属性,然后判断属性是否是指令属性,如果是在做对应的处理(事件就去监听事件、数据就去监听数据..)

完整版 myVue

在 MyVue 中添加 mounted 方法,在所有操作都做完时执行。

class MyVue {
  constructor(options) {
    var self = this;
    this.data = options.data;
    this.methods = options.methods;
    Object.keys(this.data).forEach(function(key) {
      self.proxyKeys(key);
    });
    observe(this.data);
    new Compile(options.el, this);
    options.mounted.call(this); // 所有事情处理好后执行mounted函数
  }
  proxyKeys(key) {
    // 将this.data属性代理到this上
    var self = this;
    Object.defineProperty(this, key, {
      enumerable: false,
      configurable: true,
      get: function getter() {
        return self.data[key];
      },
      set: function setter(newVal) {
        self.data[key] = newVal;
      },
    });
  }
}
Salin selepas log masuk

然后就可以测试使用了。

https://jsrun.net/Y4IKp/embedded/all/light

总结一下流程,回头在哪看一遍这个图,是不是清楚很多了。

Apakah prinsip pengikatan dua hala dalam vuejs

可以查看的代码地址:Vue2.x 的双向绑定原理及实现

相关推荐:《vue.js教程

Atas ialah kandungan terperinci Apakah prinsip pengikatan dua hala dalam vuejs. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Beberapa petua untuk membangunkan aplikasi Android menggunakan bahasa Vue.js dan Kotlin Beberapa petua untuk membangunkan aplikasi Android menggunakan bahasa Vue.js dan Kotlin Jul 31, 2023 pm 02:17 PM

Beberapa petua untuk membangunkan aplikasi Android menggunakan bahasa Vue.js dan Kotlin Dengan populariti aplikasi mudah alih dan pertumbuhan berterusan keperluan pengguna, pembangunan aplikasi Android telah menarik lebih banyak perhatian daripada pembangun. Apabila membangunkan apl Android, memilih tindanan teknologi yang betul adalah penting. Dalam beberapa tahun kebelakangan ini, bahasa Vue.js dan Kotlin secara beransur-ansur menjadi pilihan popular untuk pembangunan aplikasi Android. Artikel ini akan memperkenalkan beberapa teknik untuk membangunkan aplikasi Android menggunakan bahasa Vue.js dan Kotlin serta memberikan contoh kod yang sepadan. 1. Sediakan persekitaran pembangunan pada permulaan

Beberapa petua untuk membangunkan aplikasi visualisasi data menggunakan Vue.js dan Python Beberapa petua untuk membangunkan aplikasi visualisasi data menggunakan Vue.js dan Python Jul 31, 2023 pm 07:53 PM

Beberapa petua untuk membangunkan aplikasi visualisasi data menggunakan Vue.js dan Python Pengenalan: Dengan kemunculan era data besar, visualisasi data telah menjadi penyelesaian penting. Dalam pembangunan aplikasi visualisasi data, gabungan Vue.js dan Python boleh memberikan fleksibiliti dan fungsi yang berkuasa. Artikel ini akan berkongsi beberapa petua untuk membangunkan aplikasi visualisasi data menggunakan Vue.js dan Python, dan melampirkan contoh kod yang sepadan. 1. Pengenalan kepada Vue.js Vue.js ialah JavaScript yang ringan

Penyepaduan bahasa Vue.js dan Lua, amalan terbaik dan perkongsian pengalaman dalam membina enjin bahagian hadapan untuk pembangunan permainan Penyepaduan bahasa Vue.js dan Lua, amalan terbaik dan perkongsian pengalaman dalam membina enjin bahagian hadapan untuk pembangunan permainan Aug 01, 2023 pm 08:14 PM

Penyepaduan bahasa Vue.js dan Lua, amalan terbaik dan perkongsian pengalaman untuk membina enjin bahagian hadapan untuk pembangunan permainan Pengenalan: Dengan pembangunan berterusan pembangunan permainan, pilihan enjin bahagian hadapan permainan telah menjadi keputusan penting. Antara pilihan ini, rangka kerja Vue.js dan bahasa Lua telah menjadi tumpuan ramai pembangun. Sebagai rangka kerja hadapan yang popular, Vue.js mempunyai ekosistem yang kaya dan kaedah pembangunan yang mudah, manakala bahasa Lua digunakan secara meluas dalam pembangunan permainan kerana prestasinya yang ringan dan cekap. Artikel ini akan meneroka bagaimana untuk

Mengintegrasikan Vue.js dengan Objektif-C, petua dan nasihat untuk membangunkan apl Mac yang boleh dipercayai Mengintegrasikan Vue.js dengan Objektif-C, petua dan nasihat untuk membangunkan apl Mac yang boleh dipercayai Jul 30, 2023 pm 03:01 PM

Penyepaduan bahasa Vue.js dan Objektif-C, petua dan cadangan untuk membangunkan aplikasi Mac yang boleh dipercayai Dalam beberapa tahun kebelakangan ini, dengan populariti Vue.js dalam pembangunan bahagian hadapan dan kestabilan Objective-C dalam pembangunan aplikasi Mac, pembangun Mula. cuba menggabungkan kedua-duanya untuk membangunkan aplikasi Mac yang lebih dipercayai dan cekap. Artikel ini akan memperkenalkan beberapa petua dan cadangan untuk membantu pembangun menyepadukan Vue.js dan Objective-C dengan betul serta membangunkan aplikasi Mac berkualiti tinggi. satu

Cara menggunakan Vue untuk melaksanakan kesan gelembung sembang seperti QQ Cara menggunakan Vue untuk melaksanakan kesan gelembung sembang seperti QQ Sep 20, 2023 pm 02:27 PM

Cara menggunakan Vue untuk melaksanakan kesan gelembung sembang seperti QQ Dalam era sosial hari ini, fungsi sembang telah menjadi salah satu fungsi teras aplikasi mudah alih dan aplikasi web. Salah satu elemen yang paling biasa dalam antara muka sembang ialah gelembung sembang, yang boleh membezakan dengan jelas mesej penghantar dan penerima, dengan berkesan meningkatkan kebolehbacaan mesej. Artikel ini akan memperkenalkan cara menggunakan Vue untuk melaksanakan kesan gelembung sembang seperti QQ dan memberikan contoh kod khusus. Pertama, kita perlu mencipta komponen Vue untuk mewakili gelembung sembang. Komponen ini terdiri daripada dua bahagian utama

Cara menggunakan PHP dan Vue.js untuk melaksanakan fungsi penapisan dan pengisihan data pada carta Cara menggunakan PHP dan Vue.js untuk melaksanakan fungsi penapisan dan pengisihan data pada carta Aug 27, 2023 am 11:51 AM

Cara menggunakan PHP dan Vue.js untuk melaksanakan fungsi penapisan dan pengisihan data pada carta Dalam pembangunan web, carta ialah cara yang sangat biasa untuk memaparkan data. Menggunakan PHP dan Vue.js, anda boleh melaksanakan fungsi penapisan dan pengisihan data dengan mudah pada carta, membolehkan pengguna menyesuaikan paparan data pada carta, meningkatkan visualisasi data dan pengalaman pengguna. Pertama, kita perlu menyediakan satu set data untuk carta digunakan. Katakan kita mempunyai jadual data yang mengandungi tiga lajur: nama, umur dan gred Data adalah seperti berikut: Nama, Umur, Gred Zhang San 1890 Li

Bangunkan perangkak web dan alat pengikis data yang cekap menggunakan bahasa Vue.js dan Perl Bangunkan perangkak web dan alat pengikis data yang cekap menggunakan bahasa Vue.js dan Perl Jul 31, 2023 pm 06:43 PM

Gunakan bahasa Vue.js dan Perl untuk membangunkan perangkak web dan alat mengikis data yang cekap Dalam beberapa tahun kebelakangan ini, dengan perkembangan pesat Internet dan kepentingan data yang semakin meningkat, permintaan untuk perangkak web dan alat pengikis data juga telah meningkat. Dalam konteks ini, adalah pilihan yang baik untuk menggabungkan bahasa Vue.js dan Perl untuk membangunkan perangkak web dan alat mengikis data yang cekap. Artikel ini akan memperkenalkan cara membangunkan alat sedemikian menggunakan bahasa Vue.js dan Perl, serta melampirkan contoh kod yang sepadan. 1. Pengenalan kepada bahasa Vue.js dan Perl

Penyepaduan bahasa Vue.js dan Dart, kemahiran praktikal dan pembangunan untuk membina antara muka UI aplikasi mudah alih yang hebat Penyepaduan bahasa Vue.js dan Dart, kemahiran praktikal dan pembangunan untuk membina antara muka UI aplikasi mudah alih yang hebat Aug 02, 2023 pm 03:33 PM

Penyepaduan bahasa Vue.js dan Dart, amalan dan kemahiran pembangunan untuk membina antara muka UI aplikasi mudah alih yang hebat Pengenalan: Dalam pembangunan aplikasi mudah alih, reka bentuk dan pelaksanaan antara muka pengguna (UI) adalah bahagian yang sangat penting. Untuk mencapai antara muka aplikasi mudah alih yang hebat, kami boleh menyepadukan Vue.js dengan bahasa Dart, dan menggunakan ciri pengikatan data dan komponenisasi yang berkuasa Vue.js dan perpustakaan pembangunan aplikasi mudah alih yang kaya bagi bahasa Dart untuk membina aplikasi mudah alih yang Memukau. antara muka UI. Artikel ini akan menunjukkan kepada anda bagaimana untuk

See all articles