如何避免Vue2.2动态生成span的onclick方法自动触发
问题触发原因
- 你在模板字符串中直接写了
${this.changeLikeProperty(colName, rowData)},这段代码在拼接字符串的时候就会立即执行对应方法,把方法的返回值(你没有定义返回值的情况下就是undefined)赋值给onclick属性,自然会出现元素刚创建完方法就自动执行的情况。 .prevent是Vue的@click指令专属的事件修饰符,原生HTML的onclick属性不支持这个语法,所以添加后不会生效。
解决方法
方案1:改用Vue原生渲染逻辑生成元素(更推荐,符合Vue开发规范)
不要手动拼接HTML字符串,改用v-if控制或者渲染函数生成元素,直接用Vue的@click绑定事件,不会出现自动执行的问题。
如果是在template模板中直接使用,可以这么写:
<template> <span :class="rowData.isLike ? 'mdi mdi-ok' : 'mdi mdi-outline'" @click="rowData.isLike ? changeFavouriteProperty(colName, rowData) : changeLikeProperty(colName, rowData)" ></span> </template>
如果是在表格自定义渲染等需要用render函数的场景,可以这么修改:
fnLikeIcon(colName, rowData, h) { if (rowData.isLike) { return h('span', { class: 'mdi mdi-ok', on: { // 用箭头函数包裹目标方法,只有点击触发时才会执行内层逻辑 click: () => this.changeFavouriteProperty(colName, rowData) } }) } else { return h('span', { class: 'mdi mdi-outline', on: { click: () => this.changeLikeProperty(colName, rowData) } }) } }
方案2:如果必须使用拼接HTML字符串的方式
需要把函数调用改成字符串形式的匿名函数包裹,同时把需要用到的方法临时挂载到全局window对象,方便原生onclick访问:
created() { // 组件初始化时把方法挂载到window window.changeLikeProperty = this.changeLikeProperty window.changeFavouriteProperty = this.changeFavouriteProperty } fnLikeIcon(colName, rowData) { let currentStatus = ''; // 序列化参数,处理引号转义 const rowStr = JSON.stringify(rowData).replace(/"/g, '"') if (rowData.isLike) { currentStatus = `<span class="mdi mdi-ok" onclick="changeFavouriteProperty('${colName}', ${rowStr})"></span>`; } else { currentStatus = `<span class="mdi mdi-outline" onclick="changeLikeProperty('${colName}', ${rowStr})"></span>`; } return currentStatus; } beforeDestroy() { // 组件销毁时清除全局挂载的方法,避免内存泄漏 delete window.changeLikeProperty delete window.changeFavouriteProperty }
该方案需要额外处理参数序列化和全局方法清理,兼容性和可维护性都不如方案1,非必要场景优先选择方案1。
内容的提问来源于stack exchange,提问作者Jonan87
相关产品推荐
相关产品推荐

