美文网首页
Reactivity in the Wild

Reactivity in the Wild

作者: 7dbe8fdb929f | 来源:发表于2020-09-03 11:34 被阅读0次

    If you begin to understand what you are without trying to change it, then what you are undergoes a transformation.
    -- Jiddu Krishnamurti

    In this article, we want to achieve something like Vue, to perform dependency-tracking and change-notification when properties are accessed or modified, by adding getter/setters which are invisible to the user.

    <template>
      <div>Clicked {{count}} times!</div>
      <button type="button" id="counter-button">Click me!</button>
    </template>
    <div id="app"></div>
    
    const data = {
      message: "a",
      count: 0,
    }
    
    function render() {
      const template = document.querySelector("template")
      let content = template.innerHTML
      content = content.replace(/{{(\w+)}}/g, (all, key) => {
        return data[key]
      })
      document.getElementById("app").innerHTML = content
      document.getElementById("counter-button").addEventListener("click", () => {
        data.count++
      })
    }
    

    We will walk through all of properties and convert them to getter/setters using Object.defineProperty, this is an ES5-only and un-shimmable feature.

    function defineReactive(obj, key, val) {
      const property = Object.getOwnPropertyDescriptor(obj, key)
      if (property && property.configurable === false) {
        return
      }
    
      // cater for pre-defined getter/setters
      const getter = property && property.get
      const setter = property && property.set
    
      Object.defineProperty(obj, key, {
        get: function reactiveGetter () {
          const value = getter ? getter.call(obj) : val
          return value
        },
        set: function reactiveSetter (newVal) {
          const value = getter ? getter.call(obj) : val
          if (newVal === value) {
            return
          }
          if (setter) {
            setter.call(obj, newVal)
          } else {
            val = newVal
          }
          // update dom
          render()
        },
      })
    }
    
    Object.keys(data).forEach(key => {
      defineReactive(data, key, data[key])
    })
    
    render()
    

    相关文章

      网友评论

          本文标题:Reactivity in the Wild

          本文链接:https://www.haomeiwen.com/subject/xnynsktx.html