programing

여러 하위 구성 요소에서 데이터 수집 Vue js

prostudy 2022. 4. 15. 22:14
반응형

여러 하위 구성 요소에서 데이터 수집 Vue js

나는 지금 며칠 동안 아이 부품에서 데이터를 어떻게 잡을지 고민하느라 머리가 깨지고 있어.

상황은 이와 같다.

나는 한 부모 구성요소가 있다.Post여기서 사용자는 날짜, 제목, 설명 및 여러 인스턴스를 포함할 수 있는Event구성 요소들 Event구성요소에는 제목, 설명, 참석자와 같은 필드가 있다.

사용자가 여러 개를 추가할 수 있어야 함Event구성 요소: 즉, 여러 구성 요소가 있는 경우Event의 범위 내에서Post구성 요소

그래서 어떻게 구성 요소를 구성하여 여러 가지 구성 요소를 갖추는지 알 수 없다.Event내 안에 있는 물건들Post나중에 API로 보낼 수 있는 구성 요소.

의 구조post내가 필요한 것은:

// Post.vue
{ 
    "date": '',
    "name": '',
    "description": '',
    "events": {
       {
        "title": '',
        "description": '',
        "attendees": ''
       },
       {
        "title": '',
        "description": '',
        "attendees": ''
       }
    }
}

그래서, 나는 그것을 위해 vuex를 어떻게 사용해야 할지 모르겠다.나는 데이터를 전달하기 위해 $emit을 사용해 보았지만, 데이터를 가져올 수 있는 적합한 데이터를 찾을 수 없었다.Post본을 뜨다

어디서 찾아야 하는지 누가 가르쳐 줄래?

편집 #1: 샘플 코드 추가

구성 요소의 코드:

<template>
  <v-form>
    <v-container>
      <v-row>
        <v-col
          cols="12"
          md="4"
        >
          <v-date-picker v-model="post.date" scrollable>
            <v-spacer />
            <v-btn text color="primary" @click="modal = false">
              Cancel
            </v-btn>
            <v-btn text color="primary" @click="$refs.dialog.save(date)">
              OK
            </v-btn>
          </v-date-picker>
        </v-col>

        <v-col
          cols="12"
          md="4"
        >
          <v-text-field
            v-model="post.name"
            label="name"
            required
          />
        </v-col>

        <v-col
          cols="12"
          md="4"
        >
          <v-textarea
            v-model="post.description"
            name="description"
            label="Description"
            dense
            value
            rows="4"
            hint
          />
        </v-col>
      </v-row>
      <v-row>
        <v-btn primary rounded @click="addLine">
          Add Event
        </v-btn>
        <v-expansion-panels accordion>
          <UserEvent
            v-for="(line, index) in lines"
            :key="index"
            @addLine="addLine"
            @removeLine="removeLine(index)"
          />
        </v-expansion-panels>
      </v-row>
    </v-container>
  </v-form>
</template>

<script>
import UserEvent from './partials/event'
export default {
  name: 'Post',
  components: { UserEvent },
  data () {
    return {
      post: [],
      lines: [],
      blockRemoval: true
    }
  },
  watch: {
    lines () {
      this.blockRemoval = this.lines.length <= 1
    }
  },
  mounted () {
  },
  methods: {
    addLine () {
      const checkEmptyLines = this.lines.filter(line => line.number === null)
      if (checkEmptyLines.length >= 1 && this.lines.length > 0) { return }
      this.lines.push({
        title: null,
        description: null,
        attendees: null
      })
    },
    removeLine (lineId) {
      if (!this.blockRemoval) { this.lines.splice(lineId, 1) }
    }
  }
}
</script>

하위 구성 요소 UserEvent

// UserEvent.vue
<template>
  <v-expansion-panel>
    <v-expansion-panel-header>Event details</v-expansion-panel-header>
    <v-expansion-panel-content>
      <v-row>
        <v-col cols="12" md="6">
          <v-text-field
            v-model="event.title"
            label="Title"
            required
          />
        </v-col>

        <v-col
          cols="12"
          md="6"
        >
          <v-text-field
            v-model="event.atttendees"
            label="Atendees"
            required
          />
        </v-col>

        <v-col
          cols="12"
          md="12"
        >
          <v-textarea
            v-model="event.description"
            name="description"
            label="Description"
            dense
            value
            rows="4"
            hint
          />
        </v-col>
        <v-col
          cols="12"
          md="3"
        >
          <div class="block float-right">
            <v-btn @click="removeLine(index)" />
            <v-btn v-if="index + 1 === lines.length" @click="addLine" />
          </div>
        </v-col>
      </v-row>
    </v-expansion-panel-content>
  </v-expansion-panel>
</template>

<script>
export default {
  name: 'UserEvent',
  props: ['line', 'index'],
  data () {
    return {
      event: []
    }
  },
  methods: {
    addLine () {
      this.$emit('addLine')
    },
    removeLine (index) {
      this.$emit('removeLine', index)
    }
  }
}
</script>

질문에서 제시된 것과 유사한 구조를 가진 예가 있다.

{
  name: String,
  events: [
    title: String,
    description: String,
  ],
}

이 예에서는 사용자가 양식을 열어 새 이벤트를 추가할 수 있다.이 양식을 제출할 때 이벤트 데이터는 상위 구성 요소의 상태에 추가된다.

부모

<template>
  <div>
    <input v-model="name" />
    <ul v-if="events.length">
      <li v-for="(event, index) in events" :key="index">
        <span>{{ event.title }}</span>
        <span>{{ event.description }}</span>
      </li>
    </ul>
    <Event v-if="isNewEventFormVisible" @submit="addEvent" />
    <button v-else @click="showNewEventForm">add event</button>
  </div>
</template>
import Event from '~/components/Event';

export default {
  components: { Event },
  data() {
    return {
      name: 'Example Post',
      events: [],
      isNewEventFormVisible: false,
    };
  },
  methods: {
    addEvent({ title, description }) {
      this.isNewEventFormVisible = false;
      this.events.push({ title, description });
      // TODO: call you API here to update
    },
    showNewEventForm() {
      this.isNewEventFormVisible = true;
    },
  },
};

이벤트

<template>
  <form @submit.prevent="onSubmit">
    <input v-model.trim="title" type="text" />
    <br />
    <textarea v-model.trim="description" />
    <button type="submit">submit</button>
  </form>
</template>
export default {
  data() {
    return {
      title: '',
      description: '',
    };
  },
  methods: {
    onSubmit() {
      this.$emit('submit', {
        title: this.title,
        description: this.description,
      });
    },
  },
};

이벤트가 편집 가능한 보다 정교한 버전을 상상할 수 있을 것이다.그럴 때는 각각Event소품을 사용하는 대신 소품을 입력에 값으로 바인딩할 수 있음v-models

참조URL: https://stackoverflow.com/questions/58365536/grabbing-data-from-multiple-child-components-vue-js

반응형