[英]@click doesn't work when rendering it using v-html
Actions
列中显示该链接。
vue 版本:^2.5.17
// parent.vue
computed: {
column() {
return [
{
dataField: 'name',
text: 'Name',
},
{
dataField: 'color',
text: 'Category Color',
formatter: (cell,row) => {
return `
<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>
`
},
classes: (cell, row, rowIndex, colIndex) => {
return 'flex';
}
},
{
dataField: 'actions',
text: 'Actions',
formatter: (cell,row) => {
return `
<a href="#" @click="${this.toggleModalEdit}" class="text-indigo-600 hover:text-indigo-900">Edit</a>
`
},
},
]
},
}
// parent.vue data(){ return { modalMode: '', isShowModalEdit: false, category: [ { id: 1, name: 'Jasa Pre-Order', color: '#eb4034' }, { id: 2, name: 'Jualan', color: '#fcba03' }, { id: 3, name: 'Jasa Design', color: '#9f34eb' }, ], } }
// component.vue
<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) : '' " v-html=" col.formatter ? col.formatter(row[col.dataField],row) : row[col.dataField] " class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"></td>
<tr>
</tbody>
// component.vue
props: {
data: {
type: Array,
required: true
},
column: {
type: Array,
required: true
},
}
这是来自component.vue的示例代码:
// component.vue <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): '' " v-html=" col.formatter? col.formatter(row[col.dataField],row): row[col.dataField] " class="px-6 py-4 whitespace-nowrap text-sm text-gray-500"></td> <tr> </tbody>
// component.vue props: { data: { type: Array, required: true }, column: { type: Array, required: true }, }
结果是这样的:
但是Actions
列中的链接无法正常工作,我希望单击此链接时将运行 perent 的方法,即toggleModalEdit
。
这就是我检查链接时的样子:
您的问题是, Vue 的模板编译器根本不处理v-html 指令中的 HTML 。
因为编译器不编译这个@click
,@click 不会被解释(而只是在不触发任何操作的情况下呈现)。
为此,您需要遍历所有列并初始化一个新组件,该组件直接在 HTML 中自己处理单元格内部的内容(而不是稍后将呈现的某些字符串)。
我想这已经足够了——如果你仍然需要解释字符串中的内容,你可以使用Vue.compile
来解释内容。 但要小心,因为它不安全,以防其中有一些恶意代码 - 但由于默认情况下该指令根本没有清理,我想这就是 Vue.js 的工作方式。
感谢@SimplyComple0x78的回答,我标记了您的建议:
为此,您需要遍历所有列并初始化一个新组件,该组件直接在 HTML 中自己处理单元格内部的内容(而不是稍后将呈现的某些字符串)。
所以我尝试创建和初始化一个新组件,我称之为element-generator
。 从这里参考。 这是代码:
// element-generator.vue
<script>
export default {
render: function (createElement) {
const generatedChildren = (child) => {
if(!child) return // when child of undefined
if(typeof child === 'string') return child // when children is String
return child.map((e,i,a)=>{
if(typeof child[i] == 'string'){
return child[i]
}else{
return createElement(
child[i].tag,
child[i].attributes,
generatedChildren(child[i].children) // javascript recursive
)
}
})
}
return createElement(
this.formatter.html.tag,
this.formatter.html.attributes,
generatedChildren(this.formatter.html.children)
)
},
props: {
formatter: {
type: Object,
required: true
},
},
}
</script>
而且我不再在component.vue
中使用v-html
,而是在<td>
内部进行检查并调用element-generator
来处理单元格内的内容:
// component.vue
<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"
>
<element-generator v-if="col.formatter" :formatter="col.formatter(row[col.dataField],row)"></element-generator>
<div v-else>{{row[col.dataField]}}</div>
</td>
</tr>
</tbody>
在parent.vue
中,我用 Object 替换了字符串,稍后将传递给element-generator
,它看起来像这样:
// parent.vue
computed: {
column() {
return [
{
dataField: 'name',
text: 'Name',
},
{
dataField: 'color',
text: 'Category Color',
formatter: (cell,row) => {
return {
html: {
tag: 'div',
attributes: {
class: 'flex'
},
children:[
{
tag: 'div',
attributes: {
style: `background-color: ${cell};`,
class: 'rounded-full h-8 w-8 flex items-center justify-center mr-2',
},
},
{
tag: 'div',
attributes: {
class: 'font-bold text-gray-500',
},
children: cell
},
]
}
}
},
},
{
dataField: 'actions',
text: 'Actions',
formatter: (cell,row) => {
return {
html: {
tag: 'a',
attributes: {
class: 'text-indigo-600 hover:text-indigo-900',
on: {
click: this.toggleModalEdit
},
attrs: {
href: "#"
},
},
children: 'Edit'
},
}
},
},
]
},
},
然后当我在浏览器中检查它时,结果是这样的(这与上一个不同):
非常感谢大家。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.