Vue v-for:使用事件处理程序 (@change) 从数组动态填充 HTML 到组件模板
Vue v-for: Dynamicly fill HTML with event handler (@change) from an array into a component template
这是我当前的设置:
HTML
<question
v-for="question in questions"
v-bind:id="question.id"
v-bind:title="question.title"
v-bind:statement="question.statement"
v-bind:interaction="question.interaction"
@onchange-vg="onChangeVg"/>
</question>
<question>
的定义
var questionComponent = Vue.component('question', {
props: ['id', 'title', 'statement', 'interaction', 'currentQuestion'],
template: `
<div :id="'question-' + id">
<div class="flex my-3">
<div class="py-0"><span>{{ id }}</span></div>
<div>
<p>{{ title }}</p>
<div :class="{'hidden':(id !== this.$parent.currentQuestion), 'block':(id === this.$parent.currentQuestion)}">
<p>{{ statement }}</p>
<span v-html="interaction"></span>
</div>
</div>
</div>
</div>
`
});
Vue
var app = new Vue({
el: '#app',
data() {
return {
vg: null,
currentQuestion: 1,
questions: [
{
id: 1,
title: 'Question 1',
statement: 'Details for question 1',
interaction: `
<select ref="vb-art" @change="$emit('onchange-vg')">
<option disabled value="" selected>Make a choice</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
</select>
`
},
{
title: 'Question 2',
statement: 'Details for question 2',
interaction: `
<select ref="vb-art" @change="$emit('onchange-vg')">
<option disabled value="" selected>Make a choice</option>
<option value="black">Black</option>
<option value="white">White</option>
</select>
`
},
],
}
},
methods: {
onChangeVerguetungsart() {
console.log("Value: " + event.target.value);
currentQuestion++;
},
},
});
一切都很好。我的问题是,<select ref="vb-art" @change="$emit('onchange-vg')">
中的事件处理程序 @change 没有触发。
当我用 interaction
中的整个 <select ref="vb-art" @change="$emit('onchange-vg')">...</select>
代码替换 <span v-html="interaction"></span>
时,一切正常。
互动可能因问题而异。它可以是一个 、一个或只是一个简单的 link。这就是为什么我尝试将代码放入数组而不是组件定义的原因。
我该如何解决这个问题,以便 <span v-html="interaction"></span>
接受来自数组值传递的代码片段的事件处理程序?
你应该避免 v-html
。 v-html 只是简单地绑定 HTML,而不是 Vue 指令。
对于你的情况 v-html 是没有必要的。从交互中创建选项数组 属性 并通过 vue 模板生成标记。
interaction: [
{value: 'red', label: 'Red'},
{value: 'blue', label: 'Blue'}
]
在你的组件中
<select ref="vb-art" @change="$emit('onchange-vg')">
<option disabled value="" selected>Make a choice</option>
<option v-for="{value, label} in interaction" :key="value" :value="value">{{ label }}</option>
</select>
更新:
如果您有动态内容,那么插槽就是您的朋友。 (参考文档
https://vuejs.org/v2/guide/components-slots.html 更多示例)
你的组件:
<div>
<p>{{ title }}</p>
<div>
<p>{{ statement }}</p>
<slot />
</div>
</div>
和用法
<question
v-for="question in questions"
v-bind:id="question.id"
v-bind:title="question.title"
v-bind:statement="question.statement"
v-bind:interaction="question.interaction"
>
<select ref="vb-art" @change="onChangeVg">
<option disabled value="" selected>Make a choice</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
</select>
</question>
好处是,您不需要发射任何东西。
顺便说一句,使用 this.$parent 也不是个好主意。您的组件与父组件耦合。请改用道具。
这是我当前的设置:
HTML
<question
v-for="question in questions"
v-bind:id="question.id"
v-bind:title="question.title"
v-bind:statement="question.statement"
v-bind:interaction="question.interaction"
@onchange-vg="onChangeVg"/>
</question>
<question>
var questionComponent = Vue.component('question', {
props: ['id', 'title', 'statement', 'interaction', 'currentQuestion'],
template: `
<div :id="'question-' + id">
<div class="flex my-3">
<div class="py-0"><span>{{ id }}</span></div>
<div>
<p>{{ title }}</p>
<div :class="{'hidden':(id !== this.$parent.currentQuestion), 'block':(id === this.$parent.currentQuestion)}">
<p>{{ statement }}</p>
<span v-html="interaction"></span>
</div>
</div>
</div>
</div>
`
});
Vue
var app = new Vue({
el: '#app',
data() {
return {
vg: null,
currentQuestion: 1,
questions: [
{
id: 1,
title: 'Question 1',
statement: 'Details for question 1',
interaction: `
<select ref="vb-art" @change="$emit('onchange-vg')">
<option disabled value="" selected>Make a choice</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
</select>
`
},
{
title: 'Question 2',
statement: 'Details for question 2',
interaction: `
<select ref="vb-art" @change="$emit('onchange-vg')">
<option disabled value="" selected>Make a choice</option>
<option value="black">Black</option>
<option value="white">White</option>
</select>
`
},
],
}
},
methods: {
onChangeVerguetungsart() {
console.log("Value: " + event.target.value);
currentQuestion++;
},
},
});
一切都很好。我的问题是,<select ref="vb-art" @change="$emit('onchange-vg')">
中的事件处理程序 @change 没有触发。
当我用 interaction
中的整个 <select ref="vb-art" @change="$emit('onchange-vg')">...</select>
代码替换 <span v-html="interaction"></span>
时,一切正常。
互动可能因问题而异。它可以是一个 、一个或只是一个简单的 link。这就是为什么我尝试将代码放入数组而不是组件定义的原因。
我该如何解决这个问题,以便 <span v-html="interaction"></span>
接受来自数组值传递的代码片段的事件处理程序?
你应该避免 v-html
。 v-html 只是简单地绑定 HTML,而不是 Vue 指令。
对于你的情况 v-html 是没有必要的。从交互中创建选项数组 属性 并通过 vue 模板生成标记。
interaction: [
{value: 'red', label: 'Red'},
{value: 'blue', label: 'Blue'}
]
在你的组件中
<select ref="vb-art" @change="$emit('onchange-vg')">
<option disabled value="" selected>Make a choice</option>
<option v-for="{value, label} in interaction" :key="value" :value="value">{{ label }}</option>
</select>
更新: 如果您有动态内容,那么插槽就是您的朋友。 (参考文档 https://vuejs.org/v2/guide/components-slots.html 更多示例)
你的组件:
<div>
<p>{{ title }}</p>
<div>
<p>{{ statement }}</p>
<slot />
</div>
</div>
和用法
<question
v-for="question in questions"
v-bind:id="question.id"
v-bind:title="question.title"
v-bind:statement="question.statement"
v-bind:interaction="question.interaction"
>
<select ref="vb-art" @change="onChangeVg">
<option disabled value="" selected>Make a choice</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
</select>
</question>
好处是,您不需要发射任何东西。
顺便说一句,使用 this.$parent 也不是个好主意。您的组件与父组件耦合。请改用道具。