摘要:原文地址的博客點(diǎn)擊在線嘗試一下最終效果如下構(gòu)造器構(gòu)造一個(gè)對(duì)象,包含基本的,,初始化編譯器用于解析綁定到輸入框和下拉框的和元素的點(diǎn)擊事件。
原文地址:Bougie的博客
點(diǎn)擊在線嘗試一下
最終效果如下:
構(gòu)造一個(gè)TinyVue對(duì)象,包含基本的el,data,methods
class TinyVue{ constructor({el, data, methods}){ this.$data = data this.$el = document.querySelector(el) this.$methods = methods // 初始化 this._compile() this._updater() this._watcher() } }編譯器(compile)
用于解析綁定到輸入框和下拉框的v-model和元素的點(diǎn)擊事件@click。
先創(chuàng)建一個(gè)函數(shù)用來(lái)載入事件:
// el為元素tagName,attr為元素屬性(v-model,@click) _initEvents(el, attr, callBack) { this.$el.querySelectorAll(el).forEach(i => { if(i.hasAttribute(attr)) { let key = i.getAttribute(attr) callBack(i, key) } }) }載入輸入框事件
this._initEvents("input, textarea", "v-model", (i, key) => { i.addEventListener("input", () => { Object.assign(this.$data, {[key]: i.value}) }) })載入選擇框事件
this._initEvents("select", "v-model", (i, key) => { i.addEventListener("change", () => Object.assign(this.$data, {[key]: i.options[i.options.selectedIndex].value})) })載入點(diǎn)擊事件
點(diǎn)擊事件對(duì)應(yīng)的是methods中的事件
this._initEvents("*", "@click", (i, key) => { i.addEventListener("click", () => this.$methods[key].bind(this.$data)()) })視圖更新器(updater)
同理先創(chuàng)建公共函數(shù)來(lái)處理不同元素中的視圖,包括input、textarea的value,select的選擇值,div的innerHTML
_initView(el, attr, callBack) { this.$el.querySelectorAll(el, attr, callBack).forEach(i => { if(i.hasAttribute(attr)) { let key = i.getAttribute(attr), data = this.$data[key] callBack(i, key, data) } }) }更新輸入框視圖
this._initView("input, textarea", "v-model", (i, key, data) => { i.value = data })更新選擇框視圖
this._initView("select", "v-model", (i, key, data) => { i.querySelectorAll("option").forEach(v => { if(v.value == data) v.setAttribute("selected", true) else v.removeAttribute("selected") }) })更新innerHTML
這里實(shí)現(xiàn)方法有點(diǎn)low,僅想到正則替換{{text}}
let regExpInner = /{{ *([w_-]+) *}}/g this.$el.querySelectorAll("*").forEach(i => { let replaceList = i.innerHTML.match(regExpInner) || (i.hasAttribute("vueID") && i.getAttribute("vueID").match(regExpInner)) if(replaceList) { if(!i.hasAttribute("vueID")) { i.setAttribute("vueID", i.innerHTML) } i.innerHTML = i.getAttribute("vueID") replaceList.forEach(v => { let key = v.slice(2, v.length - 2) i.innerHTML = i.innerHTML.replace(v, this.$data[key]) }) } })監(jiān)聽(tīng)器(watcher)
數(shù)據(jù)變化之后更新視圖
_watcher(data = this.$data) { let that = this Object.keys(data).forEach(i => { let value = data[i] Object.defineProperty(data, i, { enumerable: true, configurable: true, get: function () { return value; }, set: function (newVal) { if (value !== newVal) { value = newVal; that._updater() } } }) }) }使用
TinyVue全部代碼
您輸入的是:{{text1}}+{{text2}}+{{text3}}
您選擇了:{{select}}
class TinyVue{ constructor({el, data, methods}){ this.$data = data this.$el = document.querySelector(el) this.$methods = methods this._compile() this._updater() this._watcher() } _watcher(data = this.$data) { let that = this Object.keys(data).forEach(i => { let value = data[i] Object.defineProperty(data, i, { enumerable: true, configurable: true, get: function () { return value; }, set: function (newVal) { if (value !== newVal) { value = newVal; that._updater() } } }) }) } _initEvents(el, attr, callBack) { this.$el.querySelectorAll(el).forEach(i => { if(i.hasAttribute(attr)) { let key = i.getAttribute(attr) callBack(i, key) } }) } _initView(el, attr, callBack) { this.$el.querySelectorAll(el, attr, callBack).forEach(i => { if(i.hasAttribute(attr)) { let key = i.getAttribute(attr), data = this.$data[key] callBack(i, key, data) } }) } _updater() { this._initView("input, textarea", "v-model", (i, key, data) => { i.value = data }) this._initView("select", "v-model", (i, key, data) => { i.querySelectorAll("option").forEach(v => { if(v.value == data) v.setAttribute("selected", true) else v.removeAttribute("selected") }) }) let regExpInner = /{{ *([w_-]+) *}}/g this.$el.querySelectorAll("*").forEach(i => { let replaceList = i.innerHTML.match(regExpInner) || (i.hasAttribute("vueID") && i.getAttribute("vueID").match(regExpInner)) if(replaceList) { if(!i.hasAttribute("vueID")) { i.setAttribute("vueID", i.innerHTML) } i.innerHTML = i.getAttribute("vueID") replaceList.forEach(v => { let key = v.slice(2, v.length - 2) i.innerHTML = i.innerHTML.replace(v, this.$data[key]) }) } }) } _compile() { this._initEvents("*", "@click", (i, key) => { i.addEventListener("click", () => this.$methods[key].bind(this.$data)()) }) this._initEvents("input, textarea", "v-model", (i, key) => { i.addEventListener("input", () => { Object.assign(this.$data, {[key]: i.value}) }) }) this._initEvents("select", "v-model", (i, key) => { i.addEventListener("change", () => Object.assign(this.$data, {[key]: i.options[i.options.selectedIndex].value})) }) } }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/94440.html
摘要:用來(lái)主要前臺(tái)的請(qǐng)求,并處理返回相關(guān)的數(shù)據(jù),做后臺(tái)服務(wù)??偨Y(jié)做完這個(gè)項(xiàng)目,其中的過(guò)程還是挺艱辛的,畢竟都是邊學(xué)邊做,不過(guò)最后能完成還是挺開(kāi)心的,終于有了一個(gè)從到的項(xiàng)目過(guò)程。雖然只是一個(gè)小小的練手項(xiàng)目,不過(guò)對(duì)于目前的我,感覺(jué)還是不錯(cuò)的。 showImg(https://oc1gyfe6q.qnssl.com/17-3-30/43434844-file_1490879850754_14751...
摘要:用來(lái)主要前臺(tái)的請(qǐng)求,并處理返回相關(guān)的數(shù)據(jù),做后臺(tái)服務(wù)??偨Y(jié)做完這個(gè)項(xiàng)目,其中的過(guò)程還是挺艱辛的,畢竟都是邊學(xué)邊做,不過(guò)最后能完成還是挺開(kāi)心的,終于有了一個(gè)從到的項(xiàng)目過(guò)程。雖然只是一個(gè)小小的練手項(xiàng)目,不過(guò)對(duì)于目前的我,感覺(jué)還是不錯(cuò)的。 showImg(https://oc1gyfe6q.qnssl.com/17-3-30/43434844-file_1490879850754_14751...
摘要:用來(lái)主要前臺(tái)的請(qǐng)求,并處理返回相關(guān)的數(shù)據(jù),做后臺(tái)服務(wù)??偨Y(jié)做完這個(gè)項(xiàng)目,其中的過(guò)程還是挺艱辛的,畢竟都是邊學(xué)邊做,不過(guò)最后能完成還是挺開(kāi)心的,終于有了一個(gè)從到的項(xiàng)目過(guò)程。雖然只是一個(gè)小小的練手項(xiàng)目,不過(guò)對(duì)于目前的我,感覺(jué)還是不錯(cuò)的。 showImg(https://oc1gyfe6q.qnssl.com/17-3-30/43434844-file_1490879850754_14751...
摘要:前端面試題總結(jié)持續(xù)更新中是哪個(gè)組件的屬性模塊的組件。都提供合理的鉤子函數(shù),可以讓開(kāi)發(fā)者定制化地去處理需求。 前端面試題總結(jié)——VUE(持續(xù)更新中) 1.active-class是哪個(gè)組件的屬性? vue-router模塊的router-link組件。 2.嵌套路由怎么定義? 在 VueRouter 的參數(shù)中使用 children 配置,這樣就可以很好的實(shí)現(xiàn)路由嵌套。 //引入兩個(gè)組件 ...
閱讀 1731·2021-11-22 15:33
閱讀 2108·2021-10-08 10:04
閱讀 3559·2021-08-27 13:12
閱讀 3429·2019-08-30 13:06
閱讀 1479·2019-08-29 16:43
閱讀 1402·2019-08-29 16:40
閱讀 797·2019-08-29 16:15
閱讀 2756·2019-08-29 14:13