Skip to content

事件处理

VSchema 提供灵活的事件绑定和动作系统,支持 Vue 事件修饰符。

基础用法

使用 events 属性绑定事件:

json
{
  "com": "button",
  "events": {
    "click": { "set": "count", "value": "{{ count + 1 }}" }
  },
  "children": "点击"
}

动作类型

set - 修改状态

json
{
  "events": {
    "click": { "set": "count", "value": "{{ count + 1 }}" }
  }
}

支持嵌套路径:

json
{ "set": "user.profile.name", "value": "新名称" }
{ "set": "items[0].checked", "value": true }

call - 调用方法

json
{
  "methods": {
    "handleSubmit": [
      { "set": "loading", "value": true },
      { "fetch": "/api/submit", "body": "{{ form }}" },
      { "set": "loading", "value": false }
    ]
  },
  "events": {
    "click": { "call": "handleSubmit" }
  }
}

带参数调用:

json
{ "call": "updateItem", "args": ["{{ item.id }}", "{{ newValue }}"] }

emit - 触发事件

向父组件触发事件:

json
{
  "events": {
    "click": { "emit": "select", "payload": "{{ item }}" }
  }
}

fetch - API 调用

json
{
  "events": {
    "click": {
      "fetch": "/api/users/{{ userId }}",
      "method": "GET",
      "then": { "set": "user", "value": "{{ $response }}" },
      "catch": { "set": "error", "value": "{{ $error.message }}" }
    }
  }
}

完整配置:

json
{
  "fetch": "/api/data",
  "method": "POST",
  "headers": {
    "Content-Type": "application/json"
  },
  "body": {
    "name": "{{ form.name }}",
    "email": "{{ form.email }}"
  },
  "then": { "set": "result", "value": "{{ $response }}" },
  "catch": { "set": "error", "value": "{{ $error.message }}" },
  "finally": { "set": "loading", "value": false }
}

copy - 复制到剪贴板

json
{
  "events": {
    "click": {
      "copy": "{{ shareUrl }}",
      "then": { "set": "copied", "value": true },
      "catch": { "set": "error", "value": "复制失败" }
    }
  }
}

if - 条件执行

json
{
  "events": {
    "click": {
      "if": "count > 10",
      "then": { "set": "message", "value": "大于10" },
      "else": { "set": "message", "value": "小于等于10" }
    }
  }
}

script - 自定义脚本

json
{
  "events": {
    "click": {
      "script": "await $methods.login(state.form.username, state.form.password);"
    }
  }
}

可用变量:state, computed, $event, $response, $error, $methods

ws - WebSocket

json
{
  "events": {
    "click": {
      "ws": "wss://example.com/socket",
      "op": "connect",
      "id": "main",
      "onMessage": { "set": "lastMessage", "value": "{{ $response }}" }
    }
  }
}

详细用法请参考 WebSocket 指南

多个动作

使用数组执行多个动作:

json
{
  "events": {
    "click": [
      { "set": "loading", "value": true },
      { "fetch": "/api/data", "then": { "set": "data", "value": "{{ $response }}" } },
      { "set": "loading", "value": false }
    ]
  }
}

事件修饰符

支持 Vue 事件修饰符语法:

基础修饰符

json
{
  "events": {
    "click.prevent": { "call": "handleClick" },
    "click.stop": { "call": "handleClick" },
    "click.prevent.stop": { "call": "handleClick" },
    "submit.prevent": { "call": "handleSubmit" }
  }
}
修饰符说明
.prevent阻止默认行为
.stop阻止事件冒泡
.capture使用捕获模式
.self只在元素自身触发
.once只触发一次
.passive被动监听

按键修饰符

json
{
  "events": {
    "keyup.enter": { "call": "submit" },
    "keyup.esc": { "call": "cancel" },
    "keydown.ctrl.s": { "call": "save" },
    "keydown.alt.enter": { "call": "newLine" }
  }
}
修饰符说明
.enterEnter 键
.tabTab 键
.escEscape 键
.space空格键
.up上箭头
.down下箭头
.left左箭头
.right右箭头
.ctrlCtrl 键
.altAlt 键
.shiftShift 键
.metaMeta 键 (Mac: Command, Windows: Win)

组合修饰符

json
{
  "events": {
    "keydown.ctrl.shift.s": { "call": "saveAs" },
    "click.ctrl": { "call": "multiSelect" }
  }
}

访问事件对象

使用 $event 访问原生事件对象:

json
{
  "events": {
    "input": { "set": "value", "value": "{{ $event.target.value }}" },
    "click": { "set": "position", "value": "{{ { x: $event.clientX, y: $event.clientY } }}" }
  }
}

实际示例

表单提交

json
{
  "com": "form",
  "events": {
    "submit.prevent": [
      { "set": "loading", "value": true },
      {
        "fetch": "/api/login",
        "method": "POST",
        "body": "{{ form }}",
        "then": [
          { "set": "user", "value": "{{ $response.user }}" },
          { "emit": "login-success" }
        ],
        "catch": { "set": "error", "value": "{{ $error.message }}" },
        "finally": { "set": "loading", "value": false }
      }
    ]
  }
}

防抖搜索

json
{
  "data": { "searchText": "", "timer": null },
  "methods": {
    "debouncedSearch": {
      "script": "clearTimeout(state.timer); state.timer = setTimeout(() => { /* 搜索逻辑 */ }, 300);"
    }
  },
  "com": "input",
  "model": "searchText",
  "events": {
    "input": { "call": "debouncedSearch" }
  }
}

确认删除

json
{
  "events": {
    "click": {
      "if": "confirm('确定要删除吗?')",
      "then": {
        "fetch": "/api/items/{{ item.id }}",
        "method": "DELETE",
        "then": { "set": "items", "value": "{{ items.filter(i => i.id !== item.id) }}" }
      }
    }
  }
}

Released under the MIT License.