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

Vue 2.5.17中使用v-html渲染@click事件失效问题求助

Hey Kevin, let's figure out why your Edit link's click event isn't working, and fix it properly for Vue 2.5.17!

The core issue here is that v-html renders raw HTML, not Vue template code. When you use @click="${this.toggleModalEdit}" in your formatter, Vue doesn't parse that @click directive—it just inserts it as plain text into the DOM. So the click event never gets bound to your parent component's method.

Here are two solid solutions, with the first being the most Vue-idiomatic approach:


Scoped slots let the parent component control how individual table cells are rendered, which keeps your event bindings working because they're part of the parent's Vue template (not raw HTML).

Step 1: Update the Child Component (component.vue)

Modify the <td> to use a scoped slot instead of v-html. This passes the row/cell data up to the parent so you can customize the content:

<tbody class="bg-white divide-y divide-gray-200">
  <tr v-for="(row, rowIndex) in data" :key="rowIndex">
    <td 
      v-for="(col, colIndex) in column" 
      :key="col.dataField"
      :class="col.classes ? col.classes(row[col.dataField], row, rowIndex, colIndex) : ''"
      class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"
    >
      <!-- Scoped slot: pass row/cell data to parent -->
      <slot 
        :name="col.dataField" 
        :row="row" 
        :cell="row[col.dataField]" 
        :rowIndex="rowIndex" 
        :colIndex="colIndex"
      >
        <!-- Fallback content if parent doesn't provide a slot -->
        {{ col.formatter ? col.formatter(row[col.dataField], row) : row[col.dataField] }}
      </slot>
    </td>
  </tr>
</tbody>

Step 2: Update the Parent Component (parent.vue)

Use <template> with slot and slot-scope to define custom content for your Color and Actions columns. Now your @click will work normally because it's part of the parent's template:

<table-component 
  :data="category" 
  :column="column" 
  class="bg-red-200 py-4 mt-8"
>
  <!-- Custom Category Color column -->
  <template slot="color" slot-scope="{ cell, row }">
    <div style="background-color: {{ cell }};" class="rounded-full h-8 w-8 flex items-center justify-center mr-2"></div>
    <div class="font-bold text-gray-500">{{ cell }}</div>
  </template>

  <!-- Custom Actions column with working click event -->
  <template slot="actions" slot-scope="{ row }">
    <a href="#" @click.prevent="toggleModalEdit" class="text-indigo-600 hover:text-indigo-900">Edit</a>
  </template>
</table-component>

Step 3: Simplify the column Computed Property

You no longer need the formatter functions since the slots handle rendering:

column() {
  return [
    {
      dataField: 'name',
      text: 'Name',
    },
    {
      dataField: 'color',
      text: 'Category Color',
      classes: (cell, row, rowIndex, colIndex) => 'flex',
    },
    {
      dataField: 'actions',
      text: 'Actions',
    },
  ]
}

The @click.prevent stops the default link behavior (page jump) while triggering your toggleModalEdit method.


Solution 2: Event Delegation (Quick Fix)

If you don't want to refactor with slots, you can use event delegation on the table body to catch clicks on the Edit link.

Step 1: Update the Child Component

Add a click handler to the <tbody> and emit an event to the parent when an Edit link is clicked:

<tbody class="bg-white divide-y divide-gray-200" @click="handleRowClick">
  <!-- Keep your existing tr/td code here -->
</tbody>

<script>
export default {
  props: { data: Array, column: Array },
  methods: {
    handleRowClick(event) {
      const link = event.target.closest('a');
      if (link?.textContent.trim() === 'Edit') {
        event.preventDefault();
        // Emit event to parent
        this.$emit('toggle-modal-edit');
      }
    }
  }
}
</script>

Step 2: Update the Parent Component

Listen for the emitted event and bind it to your method:

<table-component 
  :data="category" 
  :column="column" 
  class="bg-red-200 py-4 mt-8"
  @toggle-modal-edit="toggleModalEdit"
/>

Step 3: Fix the Formatter

Remove the invalid @click from the Actions formatter:

formatter: (cell, row) => `
  <a href="#" class="text-indigo-600 hover:text-indigo-900">Edit</a>
`

Why Your Original Code Failed

When you use v-html, Vue inserts the string as raw DOM content—it doesn't compile any Vue directives like @click inside it. The @click="${this.toggleModalEdit}" just becomes a plain HTML attribute with the string representation of your method (not an actual function call). Even if you used onclick, it would try to call a global toggleModalEdit function, which doesn't exist (your method is tied to the parent component's instance).

Stick with Solution 1 for long-term maintainability—it's the standard way to handle customizable components in Vue!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 05:58:20