新聞中心
本喵寫(xiě)了以下三種不同方式的數(shù)據(jù)綁定(只實(shí)現(xiàn)了單向綁定):

創(chuàng)新互聯(lián)建站專注于企業(yè)營(yíng)銷型網(wǎng)站建設(shè)、網(wǎng)站重做改版、武陵源網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5場(chǎng)景定制、商城網(wǎng)站制作、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為武陵源等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。
- 第一種,使用了“臟值”檢測(cè),該方法是 angular 的數(shù)據(jù)綁定原理。
- 第二種,使用了 es5 的 Object.defineProperty(),vue2 的數(shù)據(jù)綁定就是基于該方法。
- 第三種,使用了 es6 的 Proxy ,vue3 的數(shù)據(jù)綁定開(kāi)始全盤(pán)換為這種方式。
廢話不多說(shuō),直接擼起代碼~
01 臟值檢測(cè)
如果綁定的數(shù)據(jù)過(guò)多,臟值檢測(cè)可能會(huì)造成性能問(wèn)題,因?yàn)槊看胃淖冎?,都需要進(jìn)行輪詢改變對(duì)應(yīng)的值。
臟值檢測(cè) 臟值檢測(cè)
- 第一個(gè)綁定數(shù)據(jù):
- 第二個(gè)綁定數(shù)據(jù):
- 第三個(gè)綁定數(shù)據(jù):
- window.onload = function () {
- // 首次加載需要初始化數(shù)據(jù)
- apply()
- bind()
- }
- // data
- let counter = 0
- // methods
- function add() {
- counter++
- }
- function reset() {
- counter = 0
- }
- // bind event
- function bind() {
- let list = document.querySelectorAll("[a-click]")
- list.forEach(item => {
- item.onclick = function () {
- window[item.getAttribute("a-click")]()
- apply()
- }
- })
- }
- // bind data
- function apply() {
- let list = document.querySelectorAll("[a-bind='counter']")
- list.forEach(item => {
- if (item.innerHTML !== counter + '') {
- item.innerHTML = counter
- }
- })
- }
02 Object.defineProperty(ES5)
該方法是目前比較主流的方法,兼容性也不錯(cuò),支持 ie8(注意:下面并沒(méi)實(shí)現(xiàn) vue2 的發(fā)布訂閱者模式,有空再擼一個(gè)出來(lái))。
Object.defineProperty Object.defineProperty(ES5語(yǔ)法)
- 第一個(gè)綁定數(shù)據(jù):
- 第二個(gè)綁定數(shù)據(jù):
- 第三個(gè)綁定數(shù)據(jù):
- window.onload = function () {
- // 首次加載需要初始化數(shù)據(jù)
- apply('counter', obj.counter)
- bind()
- }
- // data
- let obj = {
- _counter: 0
- }
- // counter 只是一個(gè)載體,真正的值存儲(chǔ)在 _counter
- Object.defineProperty(obj, 'counter', {
- get: function () {
- //console.log('get:', counter)
- return this._counter
- },
- set: function (val) {
- this._counter = val
- //console.log('set:', counter)
- apply('counter', this._counter)
- }
- })
- // methods
- function add() {
- obj.counter++
- }
- function reset() {
- obj.counter = 0
- }
- // bind event
- function bind() {
- let list = document.querySelectorAll('[a-click]')
- list.forEach(item => {
- item.onclick = function () {
- window[item.getAttribute('a-click')]()
- }
- })
- }
- // bind data
- function apply(str, val) {
- let list = document.querySelectorAll(`[a-bind=${str}]`)
- list.forEach(item => {
- if (item.innerHTML !== val + '') {
- item.innerHTML = val
- }
- })
- }
03 Proxy(ES6)
相比上面兩種方法,用 es6 Proxy 來(lái)寫(xiě)數(shù)據(jù)綁定,代碼會(huì)直觀很多,而且很易用,不過(guò)遺憾的是 Proxy 兼容性很差,IE 是全面不支持它,而且 babel 沒(méi)法完全將它轉(zhuǎn)為 es5 語(yǔ)法,雖然有 google 大佬寫(xiě)的 Polyfill,但那個(gè)也是有殘缺的(不知道尤大在 vue3 里怎么解決它)。
proxy proxy(ES6語(yǔ)法)
- 第一個(gè)綁定數(shù)據(jù):
- 第二個(gè)綁定數(shù)據(jù):
- 第三個(gè)綁定數(shù)據(jù):
- window.onload = function () {
- // 首次加載需要初始化數(shù)據(jù)
- apply('counter', obj.counter)
- bind()
- }
- // data
- let obj = new Proxy({
- counter: 0
- }, {
- set: function (obj, prop, value) {
- obj[prop] = value
- if (prop == 'counter') {
- apply('counter', value)
- }
- return true
- }
- })
- // methods
- function add() {
- obj.counter++
- }
- function reset() {
- obj.counter = 0
- }
- // bind event
- function bind() {
- let list = document.querySelectorAll('[a-click]')
- list.forEach(item => {
- item.onclick = function () {
- window[item.getAttribute('a-click')]()
- }
- })
- }
- // bind data
- function apply(str, val) {
- let list = document.querySelectorAll(`[a-bind=${str}]`)
- list.forEach(item => {
- if (item.innerHTML !== val + '') {
- item.innerHTML = val
- }
- })
- }
04 總結(jié)
除了上面三種方式外,其實(shí)原本還有一種 Object.observe 方法,該方法是在 es7 的草案中,不過(guò)經(jīng)過(guò)各位大佬的討論,還是廢棄了這種方法,只有 chrome 曾經(jīng)支持過(guò)(沒(méi)錯(cuò),是曾經(jīng),現(xiàn)在不支持了),這里就不鞭尸了(懶)。上面三種方式,無(wú)疑 proxy 是一個(gè)趨勢(shì),vue3 也改用它了,相信未來(lái)幾年,proxy 會(huì)得到各個(gè)技術(shù)人的熱捧。
本文標(biāo)題:前端的三種數(shù)據(jù)綁定技術(shù)
網(wǎng)站網(wǎng)址:http://m.fisionsoft.com.cn/article/djephhh.html


咨詢
建站咨詢
