Vue .sync 仅适用于 v-model,但会出现突变错误
Posted
技术标签:
【中文标题】Vue .sync 仅适用于 v-model,但会出现突变错误【英文标题】:Vue .sync only works with v-model, but gives mutation error 【发布时间】:2021-04-04 21:01:23 【问题描述】:// 注意:问题是由 VueFormulate 的 FormulaInput(自定义输入)引起的。
检查代码沙箱以获取.sync
的 3 个工作示例
用例
我的应用将多个动态组件注入到视图中,然后将每个组件中的多个输入绑定到父级中的数据。
由于v-model
仅适用于单个值,我发现.sync
(在 Vue 2.3 之后再次添加)是将每个子组件中的多个输入双向绑定到我父级数据的唯一方法。
问题
我遵循了 Vue 文档和许多教程中的确切语法,但是当我在我的子组件中使用 :value="value
时,它会在我的数据中输入 undefined
,并且在控制台中没有错误。
如果我使用v-model
,它会按预期工作,但是每次按下按键都会在控制台中产生no-mutate-props
错误。
预期结果
我希望双向绑定能够正常工作,而不会在控制台中产生任何 no-mutate-props
错误。
我想我需要某种观察者来检查引用我的道具的值,但这似乎有点混乱,我必须为大约 30 个组件实现它......如果我更喜欢更清洁的东西可能。
Code Sandbox Example of issue
在儿童中
// input1
<input
type="text"
:value="value" <----- this will work if I make it a v-model, but produces mutation error in console
@input="$emit('update:value', value)"
/>
// input2
<input
type="text"
:value2="value2" <----- again, will work with v-model only
@input="$emit('update:value2', value2)"
/>
props:
value:
type: String
,
value2:
type: String
在父母中
<component
:is="step.component"
:value.sync="step.value"
:value2.sync="step.value2"
:value3.sync="step.value3"
/>
【问题讨论】:
【参考方案1】:value
不起作用的原因仅仅是因为您发出了相同的未更改的value
,它被传递下来。没有v-model
,value
不会发生任何变化,因此没有新的东西可以重新发射。
将该输入更改为:
<input
:value="value"
@input="$emit('update:value', $event.target.value)"
type="text"
step="1"
placeholder="Child Input1 (value)"
/>
这样,当输入事件发生时,您会从输入框中发出一个新值。
【讨论】:
【参考方案2】:为了完整起见,我想在 Dan 的回答中添加一个通用替代方案:允许将 v-model
与任何无法直接变异的内容一起使用的 Vue 模式:computed getter + setter。
概念证明:
Vue.component('child',
template: `
<input v-model="local" type="text" />
`,
props: ['value'],
computed:
local:
get()
return this.value;
,
set(value)
this.$emit('update:value', value);
)
new Vue(
el: '#app',
data: () => (
foo:
bar: 'baz'
)
)
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<div id="app">
<div>
<child :value.sync="foo.bar" />
</div>
<pre v-html="foo" />
</div>
我特意使用了一个嵌套属性,它通常不是反应式的。
虽然在这个特定示例中使用它实际上只是有点冗长(因此它可能不如 Dan 提出的语法有用)它在与 Vuex 状态属性一起使用时会派上用场(在 getter 中获取存储值并提交setter 中的突变 - 特别是因为您可以将本地计算命名为与 state 属性相同)。
值得注意的是,它不需要额外的侦听器(性能提升可以忽略不计)(例如:@input
、@change
、@keydown
等... - 为了完整起见,在生产代码中您可能想要添加粘贴事件侦听器,可能还有其他边缘情况 - 自动完成!? - 虽然大多数情况都被 @input
覆盖)。
正如您所料,每当v-model
属性的值发生变化时,setter 中的代码就会运行一次。简而言之,这是一个适当的双向绑定。
【讨论】:
以上是关于Vue .sync 仅适用于 v-model,但会出现突变错误的主要内容,如果未能解决你的问题,请参考以下文章