首页 > 解决方案 > Vue 将插槽数据存储在父组件中

问题描述

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

索引.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 文件中。

标签: javascriptvue.jsvuejs2

解决方案


正如@User 28 所提到的,您可以利用槽和作用域槽来使其与任意数量的字段一起使用,如下所示:

<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以获取工作示例。


推荐阅读