Skip to content

1.0.0 版本升级改动

musicode edited this page Apr 26, 2019 · 22 revisions

大致说下 1.0.0 版本的升级思路

  1. 采用 typescript 重写所有代码
  2. 底层编译重新设计,性能大幅提升
  3. 更加完备的错误提示
  4. 更加稳定的 API
  5. 对外提供以下四种版本,功能从多到少排序:

yox.js:拥有完整功能的源码版本,建议使用此版本进行开发

yox.min.js:拥有完整功能,但不包含错误提示的压缩版本

yox.runtime.js:不包含编译器的压缩版本,文件体积大为减少,且性能更佳,建议使用此版本进行上线

可通过 Yox.compile('你的模板源码', true) 获取编译后的字符串

yox.pure.js:不包含任何 DOM 的压缩版本,是纯数据操作版本

比较简单的

  1. 删除 Yox.is.primitive 方法
  2. Yox.Event 构造函数签名改为 (type, originalEvent)
  3. Yox.string.camelCase 改为 Yox.string.camelize
  4. 删除 Yox.dom.isElementYox.dom.children
  5. Yox.dom.before(parentNode, node, referenceNode) 中的 referenceNode 改成必传
  6. Yox.dom.setProp 改为 Yox.dom.prop
  7. Yox.dom.setAttr 改为 Yox.dom.attr
  8. 表达式模板 语法增强了校验,具体可查看运行时的报错或警告信息

hasSlot 过滤器

hasSlot(name) 过滤器已不建议使用,更新如下:

before

<div>
  {{#if hasSlot('icon')}}
    <slot name="icon" />
  {{else}}
    默认 icon
  {{/if}}
</div>

after

<div>
  <slot name="icon">
    // 默认 icon
  </slot>
</div>

如果没有人能说出非要 hasSlot 不可的理由,正式版会删掉 hasSlot

数据监听

立即执行监听函数,由从前的 sync 改为了 immediate,虽然这个单词不好记,但没办法,它就是更规范一些。

before

{
  watchers: {
    title: {
      sync: true,
      watcher: function () {

      }
    }
  }
}

after

{
  watchers: {
    title: {
      immediate: true,
      watcher: function () {

      }
    }
  }
}

如果你用的是 yox.watch('keypath', function, true),则无需任何改动。

自定义指令

新版重新设计了自定义指令,结构如下:

Yox.directive({
  name: {
    bind: function (node, directive, vnode) {

      // 当指令写在组件上,isComponent 为 true
      // 比如 <Dog o-x="x" />
      if (vnode.isComponent) {
        // node 是一个 Yox 实例
      }
      else {
        // node 是一个 DOM 元素
      }

      // 如果指令需要销毁,比如绑定了事件
      // 你要在 vnode.data[directive.key] 属性上绑定销毁需要用到的数据

      vnode.data[directive.key] = function () {
        // 销毁逻辑
      }

    },
    unbind: function (node, directive, vnode) {
      // 销毁它
      vnode.data[directive.key]()
    }
  }
})

directive 经过精心设计,你大概会用到以下属性

directive.key

在一个元素(或组件)上,指令的唯一性由两部分保证,一个是指令的命名空间,比如是内置的 event 指令还是自定义指令,一个是指令的实际名称,比如 click,当两者相加时,我们可以认为它是唯一的,比如你不会在一个元素上写两个 on-click,这是没有意义的。

  • directive.ns: 命名空间,比如 event
  • directive.name: 指令名称,比如 click
  • directive.key:vnode 级别的 unique key,比如 event.click

directive.value

指令值的字面量,如果是基本类型,框架会自动转型。举例如下:

  • o-x="1": value 为 1
  • o-x="true": value 为 true
  • o-x="'1'": value 为 "1"
  • o-x="name": value 为 "name",但此时你想做的可能是读取 data 中的 name,这要用到下面的 getter

directive.getter

指令的取值函数,如果指令表达式不是字面量,那么框架会把表达式编译成 getter 函数,取值非常简单,执行它即可。

directive.handler

如果指令表达式是调用函数的形式,比如常见的 on-click="submit()",框架会把表达式编译成 handler 函数,你需要做的就是在合适的时机调用它。

Lazy 指令

本质上,lazy 不是指令,而是指令的辅助。

lazy 有两种值,一种是 true,一般用于 model 指令,表示输入框在失焦时触发变化。一种是大于 0 的数字,表示延时多久,这个一般取决于指令的实现方。

Yox.directive({
  name: {
    bind: function (node, directive, vnode) {
      // vnode.lazy 是一个对象,拥有当前节点上的所有 lazy 配置
    }
  }
})

比如,我们可以为每个事件分别设置延时。

<input
  type="text"

  model="value"
  on-click="click()"
  on-mousedown="mousedown()"
  on-mouseup="mouseup()"

  lazy-model="100"
  lazy-click="200"
  lazy-mousedown="300"
  lazy-mouseup

  lazy="999"
/>

input 节点的 lazy 格式如下:

{
  model: 100,
  click: 200,
  mousedown: 300,
  mouseup: true,
  '': 999
}

内置指令怎么使用 lazy 可查看源码,逻辑很简单:event, model

自定义指令怎么使用 lazy?那就看你咯!

Clone this wiki locally