Vue хранить данные слота в родительском компоненте - PullRequest
2 голосов
/ 22 января 2020

Я создаю компонент, который принимает несколько полей ввода, используя слот, когда пользователь отправляет форму внутри родительского компонента, я хочу вывести значения всех входных данных.

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>

Как вы видите, я ссылаюсь на "form.email" внутри индекса. html, который должен заполнять ввод данными в компоненте FilterForm, однако это выдает эту ошибку

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

Что имеет смысл, поскольку данные формы не доступно в файле index. html.

Как использовать эту систему, чтобы данные формы сохранялись в компоненте FilterForm, но я могу добавить любое количество входов формы в индекс. html файл.

Ответы [ 2 ]

0 голосов
/ 22 января 2020

Как уже упоминалось @User 28, вы можете воспользоваться слотами и 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 реквизит некоторых уникальных идентификаторов для полей, которые вас интересуют.
  • Когда отправлена ​​форма внутри 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 для рабочего примера.

0 голосов
/ 22 января 2020

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>

Пример

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...