为什么 vue v-model 不适用于数组道具?
Why is vue v-model not working for an array prop?
我有一个自定义组件,它接受 modelValue
属性并发出 update:modelValue
事件。在父组件中我传递了一个数组:
TestComponent.vue
<template>
<div>
<button @click="updateIt">Test</button>
</div>
</template>
<script>
export default {
props: {
modelValue: Array
},
emits: ["update:modelValue"],
setup(props, {emit}){
return {
updateIt(){
emit("update:modelValue", [4,5,6])
}
}
}
}
</script>
App.vue
<template>
<div>
<test-component v-model="myArr"/>
<ul>
<li v-for="i in myArr" v-text="i"></li>
</ul>
</div>
</template>
<script>
import TestComponent from "./TestComponent.vue";
export default {
components: {
TestComponent
},
setup(props, {emit}){
const myArr = reactive([1,2,3]);
return {
myArr
}
}
}
</script>
当我按下按钮时列表不会更新,为什么?
在内部,v-model
指令更改为 update:modelValue
事件的处理函数,看起来像这样:
$event => ((exp => $event)
其中 exp 是指令中的表达式
这基本上意味着,当发出 update:modelValue
事件时,您发出的值将直接分配给 myArr
变量,有效地替换整个 reactive
变量而不触发反应链,因为它不会通过代理发生。
如果 myArr
是一个 ref([])
vue 检测到它并且处理函数看起来像这样:
$event => (exp ? (exp).value = $event : null)
其中 exp 是指令中的表达式
这意味着值通过 ref 代理分配,触发反应链。
但是没有检查传递的表达式是否为数组的内部逻辑,如果是,则执行一些 splice push 魔法来保留原始变量,你必须自己做。
可能的解决方案:
1) 使用对象键:
<test-component v-model="myArr.data"/>
...
const myArr = reactive({
data: [1,2,3]
});
2) 使用参考:
<test-component v-model="myArr"/>
...
const myArr = ref([1,2,3]);
3) 使用自定义处理函数:
<test-component :modelValue="myArr" @update:modelValue="onChange"/>
...
const myArr = reactive([1,2,3]);
function onChange(newval){
myArr.splice(0, myArr.length, ...newval);
}
我有一个自定义组件,它接受 modelValue
属性并发出 update:modelValue
事件。在父组件中我传递了一个数组:
TestComponent.vue
<template>
<div>
<button @click="updateIt">Test</button>
</div>
</template>
<script>
export default {
props: {
modelValue: Array
},
emits: ["update:modelValue"],
setup(props, {emit}){
return {
updateIt(){
emit("update:modelValue", [4,5,6])
}
}
}
}
</script>
App.vue
<template>
<div>
<test-component v-model="myArr"/>
<ul>
<li v-for="i in myArr" v-text="i"></li>
</ul>
</div>
</template>
<script>
import TestComponent from "./TestComponent.vue";
export default {
components: {
TestComponent
},
setup(props, {emit}){
const myArr = reactive([1,2,3]);
return {
myArr
}
}
}
</script>
当我按下按钮时列表不会更新,为什么?
在内部,v-model
指令更改为 update:modelValue
事件的处理函数,看起来像这样:
$event => ((exp => $event)
其中 exp 是指令中的表达式
这基本上意味着,当发出 update:modelValue
事件时,您发出的值将直接分配给 myArr
变量,有效地替换整个 reactive
变量而不触发反应链,因为它不会通过代理发生。
如果 myArr
是一个 ref([])
vue 检测到它并且处理函数看起来像这样:
$event => (exp ? (exp).value = $event : null)
其中 exp 是指令中的表达式
这意味着值通过 ref 代理分配,触发反应链。
但是没有检查传递的表达式是否为数组的内部逻辑,如果是,则执行一些 splice push 魔法来保留原始变量,你必须自己做。
可能的解决方案:
1) 使用对象键:
<test-component v-model="myArr.data"/>
...
const myArr = reactive({
data: [1,2,3]
});
2) 使用参考:
<test-component v-model="myArr"/>
...
const myArr = ref([1,2,3]);
3) 使用自定义处理函数:
<test-component :modelValue="myArr" @update:modelValue="onChange"/>
...
const myArr = reactive([1,2,3]);
function onChange(newval){
myArr.splice(0, myArr.length, ...newval);
}