国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

用ES6的class模仿Vue寫一個雙向綁定

waltr / 545人閱讀

摘要:原文地址的博客點擊在線嘗試一下最終效果如下構造器構造一個對象,包含基本的,,初始化編譯器用于解析綁定到輸入框和下拉框的和元素的點擊事件。

原文地址:Bougie的博客

點擊在線嘗試一下

最終效果如下:

構造器(constructor)

構造一個TinyVue對象,包含基本的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和元素的點擊事件@click。
先創建一個函數用來載入事件:

// 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}))
})
載入點擊事件

點擊事件對應的是methods中的事件

this._initEvents("*", "@click", (i, key) => {
    i.addEventListener("click", () => this.$methods[key].bind(this.$data)())
})
視圖更新器(updater)

同理先創建公共函數來處理不同元素中的視圖,包括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

這里實現方法有點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])
        })
    }
})
監聽器(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()
                }
            }
        })
    })
}
使用



您輸入的是:{{text1}}+{{text2}}+{{text3}}

您選擇了:{{select}}

TinyVue全部代碼
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}))
        })
    }
}

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94440.html

相關文章

  • vue for contacts項目總結

    摘要:用來主要前臺的請求,并處理返回相關的數據,做后臺服務。總結做完這個項目,其中的過程還是挺艱辛的,畢竟都是邊學邊做,不過最后能完成還是挺開心的,終于有了一個從到的項目過程。雖然只是一個小小的練手項目,不過對于目前的我,感覺還是不錯的。 showImg(https://oc1gyfe6q.qnssl.com/17-3-30/43434844-file_1490879850754_14751...

    tulayang 評論0 收藏0
  • vue for contacts項目總結

    摘要:用來主要前臺的請求,并處理返回相關的數據,做后臺服務。總結做完這個項目,其中的過程還是挺艱辛的,畢竟都是邊學邊做,不過最后能完成還是挺開心的,終于有了一個從到的項目過程。雖然只是一個小小的練手項目,不過對于目前的我,感覺還是不錯的。 showImg(https://oc1gyfe6q.qnssl.com/17-3-30/43434844-file_1490879850754_14751...

    ralap 評論0 收藏0
  • vue for contacts項目總結

    摘要:用來主要前臺的請求,并處理返回相關的數據,做后臺服務。總結做完這個項目,其中的過程還是挺艱辛的,畢竟都是邊學邊做,不過最后能完成還是挺開心的,終于有了一個從到的項目過程。雖然只是一個小小的練手項目,不過對于目前的我,感覺還是不錯的。 showImg(https://oc1gyfe6q.qnssl.com/17-3-30/43434844-file_1490879850754_14751...

    ARGUS 評論0 收藏0
  • 前端面試題總結——VUE(持續更新中)

    摘要:前端面試題總結持續更新中是哪個組件的屬性模塊的組件。都提供合理的鉤子函數,可以讓開發者定制化地去處理需求。 前端面試題總結——VUE(持續更新中) 1.active-class是哪個組件的屬性? vue-router模塊的router-link組件。 2.嵌套路由怎么定義? 在 VueRouter 的參數中使用 children 配置,這樣就可以很好的實現路由嵌套。 //引入兩個組件 ...

    SimonMa 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<