Vue将插槽数据存储在父组件中

时间:2020-01-22 08:46:12

标签: javascript vue.js vuejs2

我正在构建一个使用插槽接收多个输入字段的组件,当用户在父组件中提交表单时,我想输出所有输入的值。

index.html

<filter-form>
    <input type="text" name="email" :value="form.email" />
</filter-form>

FilterForm.vue

<template>
  <div>
    <form
      @submit.prevent="onSubmit"
    >
      <slot />
      <div>
        <button>
          Submit
        </button>
      </div>
    </form>
  </div>
</template>

<script>
export default {
  data () {
    return {
      form: {
        email: 'test@email.com'
      }
    }
  }
}
</script>

如您所见,我在index.html中引用了“ form.email”,它应该用FilterForm组件中的数据填充输入,但这会引发此错误

Property or method "form" is not defined on the instance but referenced during render

这很有意义,因为index.html文件中没有表单数据。

如何使用此系统,以便将表单数据保留在FilterForm组件中,但是我可以将任意数量的表单输入添加到index.html文件中。

2 个答案:

答案 0 :(得分:0)

Vue具有一个名为Scoped Slots的功能,可以解决您的问题。

<filter-form>
  <template v-slot='slotProps'>
    <input :value='slotProps.form.email' />
  </template>
</filter-form>

<div>
  <form @submit.prevent=''>
    <slot :form='form'/>
      <div>
        <button>Submit</button>
      </div>
  </form>
</div>

Example

答案 1 :(得分:0)

正如@User 28所提到的,您可以利用slot和scoped-slots使其与任意数量的字段一起使用,如下所示:

<template>
  <div id="app">
    <FormWrapper :names="['name', 'country']" @submit="process($event)">
      <template #default="{ form }">
        <input name="name" type="text" v-model="form.name">
        <input name="country" type="text" v-model="form.country">
      </template>
    </FormWrapper>
  </div>
</template>

<script>
import FormWrapper from "./components/FormWrapper";

export default {
  name: "App",
  components: {
    FormWrapper
  },
  methods: {
    process(values) {
      console.log(values);
    }
  }
};
</script>

在这里,FormWrapper可以嵌套任意输入字段。一些关键点:

  • 您需要为names道具提供您关心的字段的一些唯一ID。
  • 提交FormWrapper内的表单时,将使用作为对象发送的值触发submit事件。
  • 还要注意,我们在form对象中传递槽位数据,并通过v-model将其绑定到输入。

这是FormWrapper组件:

<template>
  <div class="form-wrapper">
    <slot :form="form"></slot>
    <div class="controls">
      <button @click="submit()">Submit</button>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    names: Array
  },

  data() {
    return {
      form: {}
    };
  },

  created() {
    for (const name of this.names) {
      this.$set(this.form, name, "");
    }
  },

  methods: {
    submit() {
      this.$emit("submit", this.form);
    }
  }
};
</script>

您可以查看https://codesandbox.io/s/so-form-wrapper-yxz0i中的示例。