事件仅作为内联 JS 语句触发

Event only firing as inline JS statement

我在 SSR 模式下的 Nuxtjs 应用程序中有以下代码。

<Component
      :is="author.linkUrl ? 'a' : 'div'"
      v-bind="!author.linkUrl && { href: author.linkUrl, target: '_blank' }"
      @click="author.linkUrl ? handleAnalytics() : null"
    >

点击事件如果是 a 标签,只有写成 handleAnalytics() 才会触发,但 handleAnalytics 将不起作用。

不要误会我的意思,代码可以正常工作,但我不明白为什么。

使用经典事件绑定 (@click="handleAnalytics),Vue 会自动为您绑定它,因为它认为这是一个函数。

但是当提供三元条件时,它不会自动绑定,而是包装到匿名函数中。所以你必须用括号调用它,否则你只是 returning 函数而不执行它。

为了更清楚,可以这样写:@click="() => author.linkUrl ? handleAnalytics() : null"


注意:当有动态标签组件时,我建议改用render函数。

这是一种高级技术,但这样你就不会将东西绑定到不需要它的元素(没有那种破解 return null).

示例:

export default {
  props: {
    author: { type: Object, required: true },
  },
  render (h: CreateElement) {
    const renderLink = () => {
      return h('a', {
        attrs: {
          href: author.linkUrl,
          target: '_blank',
        },
        on: {
          click: this.handleAnalytics 
        },
      )
    }

    const renderDiv = () => {
      return h('div')
    }
    
    return this.author.linkUrl ? renderLink() : renderDiv()
  }
}

文档:Vue2, Vue3

在 javascript 中,函数是对对象的引用。就像在任何其他语言中一样,您需要将此引用存储在内存中。

这里有几个例子可以帮助您理解为什么它不起作用:

function handleAnalytics() { return 'bar' };

const resultFromFunction = handleAnalytics();
const referenceFn = handleAnalytics;

resultFromFunction 将具有 bar 作为其值,而 referenceFn 将具有对函数 handleAnalytics 的引用,允许您执行以下操作:

if (someCondition) {
  referenceFn();
}

一个更实际的例子:

function callEuropeanUnionServers() { ... }
function callAmericanServers() { ... }

// Where would the user like for his data to be stored
const callAPI = user.preferesDataIn === 'europe' 
  ? callEuropeanUnionServers
  : callEuropeanUnionServers;

// do some logic
// ...

// In this state you won't care which servers the data is stored.
// You will only care that you need to make a request to store the user data.
callAPI();

在您的示例中,您正在做的是:

@click="author.linkUrl ? handleAnalytics() : null"

伪代码中发生的事情是:

  1. 检查作者有linkUrl
  2. 如果是,则先 EXECUTE handleAnalytics 然后将结果传递给处理程序 @click
  3. 如果没有,只需传递 null

为什么在使用 handleAnalytics 而不是 handleAnalytics() 时有效?

  1. 检查作者有linkUrl
  2. 如果是,则将 REFERENCE handleAnalytics 传递给处理程序 @click
  3. 如果没有,只需传递 null

总结

当使用 handleAnalytics 时,您正在传递对 @click 的引用。使用 handleAnalytics() 时,您将从 handleAnalytics 返回的结果传递给 @click 处理程序。