【问题标题】:v-model and scoped slots not working?v-model 和作用域插槽不起作用?
【发布时间】:2018-03-27 11:53:13
【问题描述】:

我有一个组件:

<slot name="test" :name="name">
    <input type="text" v-model="name">
</slot>

输入绑定到数据中的名称。

当我在父级中使用插槽时:

<div slot="test" slot-scope="props">
    <input type="text" v-model="props.name">
</div>

孩子的数据不会更新。它没有关联 - 为什么?

【问题讨论】:

  • 当您在子项中编辑时,它不会反映在父项中,或者当您在父项中编辑时,它不会反映在子项中?
  • 在父级中编辑时,不会影响子级。

标签: vue.js vuejs2


【解决方案1】:

您看到的实际上是父级的默认&lt;input&gt;。所以你明白我的意思,在两者中添加一些文本,比如:

<slot name="test" :name="name">
    Default: <input type="text" v-model="name">
</slot>
<div slot="test" slot-scope="props">
    Actual: <input type="text" v-model="props.name">
</div>

您会看到出现的是default

现在,发生这种情况是因为,它似乎像一个错误,当插槽道具与父级的名称相同时,插槽不起作用。

解决方法:重命名 slot 属性。

在下面的示例中,我将其从 name 重命名为 namex。请注意,默认中的 v-model 保持不变 name 因为模板中的任何内容都引用 that 模板的道具(换句话说,插槽道具,例如namex,将永远不可用在父默认槽中)。

<slot name="test" :namex="name">
    Default: <input type="text" v-model="name">
</slot>
<div slot="test" slot-scope="props">
    Actual: <input type="text" v-model="props.namex">
</div>

【讨论】:

  • 恐怕这行不通。即使有解决方法,模型也不会绑定到子组件。
  • 你看到Actual: 文本被渲染了吗?
  • 您不应该修改传递给插槽的道具,而应该将回调作为 slotProp 传递,这将修改作为插槽道具传递的数据,stackoverflow.com/a/61993508/8320709
【解决方案2】:

要在作用域槽中使用v-modelv-model 的值必须更深一层:

Vue.component('render-props', {
  data: () => ({message: 'hello', obj: {msg: 'obj_msg'}}),
  template: `<div>
    <slot name="a" :message="message">
      default: {{message}}
      <input v-model="message"/>
    </slot>
    <slot name="b" :obj="obj">
      default: {{obj.msg}}
      <input v-model="obj.msg"/>
    </slot>
  </div>`
});
new Vue({
  el: "#root",
  template: `<div>
    <render-props>
      <template v-slot:a="props">
        actual: {{props.message}}
        <input v-model="props.message"/>
      </template>
      <template v-slot:b="props">
        actual: {{props.obj.msg}}
        <input v-model="props.obj.msg"/>
      </template>
    </render-props>
    <cus_2 />
  </div>`
});

【讨论】:

  • 这里不是这样。
【解决方案3】:

你不应该修改你传递给插槽的数据,漂亮 很像道具。你应该通过一个方法来改变你 价值。你总是可以传递一个对象并修改一个属性(比如 prop) 但也不推荐

-来自https://github.com/vuejs/vue/issues/9726

所以我想像

<template>
   <slot v-bind:value="value"></slot>
</template>
<script>
export default {
  name: 'FooBar',
  data() {
    value: '',
  },
  methods: {
    updateValue(e) {
      this.value = e.target.value;
    }
  },
};
</script>

那么当使用组件&lt;FooBar&gt;而不是使用v-model时,你可以使用传递的作用域插槽props、方法(updateValue)和将要更新的实际props,value

<FooBar v-slot="slotProps">
  <input type="text" :value="slotProps.value" @input="slotProps.updateValue" />
</Foobar>

【讨论】:

    猜你喜欢
    • 2019-08-08
    • 1970-01-01
    • 2019-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    • 1970-01-01
    相关资源
    最近更新 更多