我遇到了一些奇怪的行为,无法缠住我的头。
我有一个简单的单选按钮组件,用作实际单选按钮的“包装”。
在此组件上,我拥有inheritAttrs: false
并在元素本身上使用v-bind="$attrs"
,因此可以使用v模型和值等。
但是,选择单选按钮时,会抛出错误,即prop值无效(因为它是一个事件而不是字符串),而且有趣的是,我注意到在初始渲染时Vue Devtools中prop的值为空白。 >
我只是想让这些单选按钮使用选定的单选按钮的字符串值更新location
的父级数据对象值。
我无法弄清楚我到底要去哪里。任何帮助表示赞赏。
问题的示例项目: https://codesandbox.io/embed/m40y6y10mx
FormMain.vue
<template>
<div>
<p>Location: {{ location }}</p>
<form-radio
id="location-chicago"
v-model="location"
value="Chicago"
name="location"
label="Chicago"
@change="changed"
/>
<form-radio
id="location-london"
v-model="location"
value="London"
name="location"
label="London"
@change="changed"
/>
</div>
</template>
<script>
import FormRadio from "./FormRadio.vue";
export default {
name: "FormMain",
components: {
FormRadio
},
data() {
return {
location: ""
};
},
methods: {
changed(e) {
console.log("Change handler says...");
console.log(e);
}
}
};
</script>
FormRadio.vue
<template>
<div>
<label :for="id">
{{ label }}
<input
:id="id"
type="radio"
:value="value"
v-on="listeners"
v-bind="$attrs"
>
</label>
</div>
</template>
<script>
export default {
name: "FormRadio",
inheritAttrs: false,
props: {
id: {
type: String,
required: true
},
label: {
type: String,
required: true
},
value: {
type: String,
required: true
}
},
computed: {
listeners() {
return {
...this.$listeners,
change: event => {
console.log("Change event says...");
console.log(event.target.value);
this.$emit("change", event.target.value);
}
};
}
}
};
</script>
答案 0 :(得分:1)
我从子组件调用中完全删除了v模型(这是有冲突的);
<form-radio
id="location-chicago"
value="Chicago"
name="location"
label="Chicago"
@change="changed"
/>
<form-radio
id="location-london"
value="London"
name="location"
label="London"
@change="changed"
/>
然后我更新了更改的方法,以包括设置位置变量
methods: {
changed(e) {
console.log("Change handler says...");
console.log(e);
this.location = e;
}
}
已更新:链接到已更新的CodeSandbox
答案 1 :(得分:1)
修改
找到了this整洁的文章,描述了组件的model
属性。基本上,它允许您自定义v-model
的工作方式。使用此,FormMain.vue
无需更改。只需从FormRadio
中删除值属性,然后使用您自己的定义添加模型属性
查看更新后的codepen:
FormRadio脚本
<script>
export default {
name: "FormRadio",
inheritAttrs: false,
props: {
id: {
type: String,
required: true
},
label: {
type: String,
required: true
}
},
// customize the event/prop pair accepted by v-model
model: {
prop: "radioModel",
event: "radio-select"
},
computed: {
listeners() {
return {
...this.$listeners,
change: event => {
console.log("Change event says...");
console.log(event.target.value);
// emit the custom event to update the v-model value
this.$emit("radio-select", event.target.value);
// the change event that the parent was listening for
this.$emit("change", event.target.value);
}
};
}
}
};
</script>
编辑前:
如果存在value
,Vue似乎会忽略v-model
绑定属性。我通过为radio-value
之类的值使用自定义属性来解决此问题。
FormMain.vue
<form-radio
id="location-chicago"
v-model="location"
radio-value="Chicago"
name="location"
label="Chicago"
@change="changed"
/>
<form-radio
id="location-london"
v-model="location"
radio-value="London"
name="location"
label="London"
@change="changed"
/>
input
事件处理程序将更新v模型。
FormRadio.vue
<template>
<div>
<label :for="(id) ? `field-${id}` : false">
{{ label }}
<input
:id="`field-${id}`"
type="radio"
:value="radioValue"
v-on="listeners"
v-bind="$attrs"
>
</label>
</div>
</template>
<script>
export default {
name: "FormRadio",
inheritAttrs: false,
props: {
id: {
type: String,
required: true
},
label: {
type: String,
required: true
},
radioValue: {
type: String,
required: true
}
},
computed: {
listeners() {
return {
...this.$listeners,
input: event => {
console.log("input event says...");
console.log(event.target.value);
this.$emit("input", event.target.value);
},
change: event => {
console.log("Change event says...");
console.log(event.target.value);
this.$emit("change", event.target.value);
}
};
}
}
};
</script>