美文网首页
Commit 6 - 12:初步实现each

Commit 6 - 12:初步实现each

作者: 丨ouo丨 | 来源:发表于2018-12-21 16:01 被阅读21次

    Commit 6: refactor

    • 主要改动:重构
    • 备注:逻辑的改动并不大,主要是结构上面重构了一下

    Commit 7: augmentArray seems to work

    • 主要改动:开始添加sd-each

    Commit 8: WIP

    • 主要改动:持续重构

    Commit 9: refactor

    • 主要改动:添加了全局apiVue.extend

    • 以下是目前的代码结构

      Commit9-结构.png

    Commit 10: kinda working now.

    • 主要改动:监听array变化

    • 代码实现:

      • src/directives.js,each部分

        each: {
            update: function (collection) {
                watchArray(collection, this.mutate.bind(this))
            },
            mutate: function (mutation) {
                console.log(mutation)
                console.log(this)
            }
        }
        
      • src/watchArray.js

        var proto = Array.prototype,
            slice = proto.slice,
            mutatorMethods = [
                'pop',
                'push',
                'reverse',
                'shift',
                'unshift',
                'splice',
                'sort'
            ]
        
        module.exports = function (arr, callback) {
        
            mutatorMethods.forEach(function (method) {
                arr[method] = function () {
                    // 调用原生同名方法
                    proto[method].apply(this, arguments)
                    // 回调
                    callback({
                        event: method,
                        args: slice.call(arguments),
                        array: arr
                    })
                }
            })
        
        }
        

    Commit 11: sd-each-* works

    • 主要改动:实现了部分sd-each的逻辑
    • 备注:运行了一下,buildItem函数会报错,但是在下一个提交已经修复了。

    Commit 12: big refactor.. again

    • 主要改动:一次比较大的重构,初步实现sd-each列表(可以生成li了)

    • 流程图(dev.html的运行过程)

      Commit12.png

      在绑定完指令后,对变量进行赋值时,会调用指令中的update方法(绑定指令详见commit2)。因此,通过阅读each指令的代码,就可以知道列表的实现原理。

      each: {
          // 在第一次绑定完后调用
          bind: function () {
              this.el['sd-block'] = true
              this.prefixRE = new RegExp('^' + this.arg + '.')
              var ctn = this.container = this.el.parentNode
              this.marker = document.createComment('sd-each-' + this.arg + '-marker')
              ctn.insertBefore(this.marker, this.el)
              ctn.removeChild(this.el)
              this.childSeeds = []
          },
          // set的时候调用
          update: function (collection) {
              if (this.childSeeds.length) {
                  this.childSeeds.forEach(function (child) {
                      child.destroy()
                  })
                  this.childSeeds = []
              }
              // 见commit10
              watchArray(collection, this.mutate.bind(this))
              var self = this
              // 循环生成子实例
              collection.forEach(function (item, i) {
                  self.childSeeds.push(self.buildItem(item, i, collection))
              })
          },
          // 
          mutate: function (mutation) {
              console.log(mutation)
          },
          // 生成子实例
          buildItem: function (data, index, collection) {
              var Seed = require('./seed'),
                  // 克隆一个节点node
                  node = this.el.cloneNode(true),
                  ctrl = node.getAttribute(config.prefix + '-controller'),
                  Ctrl = ctrl ? controllers[ctrl] : Seed
              if (ctrl) node.removeAttribute(config.prefix + '-controller')
              // 以node、data生成子实例
              var spore = new Ctrl(node, data, {
                      eachPrefixRE: this.prefixRE,
                      parentScope: this.seed.scope
                  })
              // 在页面中插入node
              this.container.insertBefore(node, this.marker)
              collection[index] = spore.scope
              return spore
          }
      }
      
    • 总结

      1. 处理节点时采用递归的方式
      2. sd-each时,会给列表中的每个元素生成一个子实例

    相关文章

      网友评论

          本文标题:Commit 6 - 12:初步实现each

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