You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mithril.js中vnode绑定点击事件及传递给匿名函数的方法

Mithril.js: Binding Vnodes to Click Events & Passing Vnodes in Webpack Projects

Let's break down your questions clearly, with practical fixes for your code example:

1. How to bind a vnode to a click event in Mithril.js?

In Mithril, DOM event handlers receive the browser event object as their first argument by default—not the Mithril vnode. To access the vnode in your click handler, you have two simple, reliable approaches:

  • Leverage closure scope:
    Since the view function gets the vnode as a parameter, you can directly reference it inside your click handler without passing it explicitly:

    var Button = {
      view: function(vnode) {
        return m('div', {
          onclick: function() {
            // vnode is accessible here thanks to closure
            console.log("Clicked element's vnode:", vnode);
          }
        }, "Click Me");
      }
    };
    
  • Explicitly pass the vnode via an arrow function:
    If you want to use a separate handler function, wrap the call in an arrow function to pass the vnode through. Just make sure you don't name the arrow function's parameter vnode (that would shadow the outer vnode variable):

    function handleClick(vnode) {
      // Work with the Mithril vnode here
      console.log("Handling click for:", vnode.attrs);
    }
    
    var Button = {
      view: function(vnode) {
        return m('div', {
          onclick: () => handleClick(vnode)
        }, "Click Me");
      }
    };
    

2. Fixing your Webpack project code to pass the vnode correctly

Looking at your original code, there's a common shadowing issue that's preventing you from getting the right vnode:

// Your original code (has a bug)
var Button = { view:function(vnode){ return m('div',{onclick:(vnode)=> setSort(vnode)}) } }
function setSort(vnode){ .... do somthing with vnode .... }

The problem is that the arrow function's parameter is named vnode, which overwrites (shadows) the vnode variable from the view function. Inside that arrow function, vnode is actually the browser click event—not the Mithril vnode you need!

Here's the fixed version:

Option 1: Pass the vnode without shadowing

function setSort(vnode) {
  // Now this vnode is the actual Mithril vnode from the view
  console.log("Using vnode to update state:", vnode.state);
  // Add your sorting logic here
}

var Button = {
  view: function(vnode) {
    // The arrow function doesn't define its own vnode parameter, so it uses the outer one
    return m('div', { onclick: () => setSort(vnode) }, "Sort");
  }
};

Option 2: Access both the event and vnode

If you need the browser event object too, rename the arrow function's parameter to avoid shadowing:

function setSort(event, vnode) {
  console.log("Click event details:", event.target);
  console.log("Mithril vnode data:", vnode.attrs.sortKey);
  // Your sorting logic here
}

var Button = {
  view: function(vnode) {
    return m('div', { onclick: (e) => setSort(e, vnode) }, "Sort");
  }
};

This works exactly the same in Webpack projects—Webpack only bundles your code, so Mithril's core behavior with vnodes and closures stays unchanged.


内容的提问来源于stack exchange,提问作者Tal Yaron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:04:59