【问题标题】:Vue loop array objects into form checkboxVue循环数组对象到表单复选框
【发布时间】:2021-05-10 11:44:41
【问题描述】:

我正在尝试创建一个“编辑列表”页面,其中显示某人提交的信息。我对如何通过选中第一次选中的框来填充表单中的复选框感到有些困惑。

我知道复选框会查找 false/true 以显示支票,但我的数组如下: [x,y,z] 仅显示为 [true] 或 [false] 导致所有使用 v-model 时会同时检查框,反之亦然。

表格

           <input
              type="checkbox"
              id="Set Photographer"
              value="Set Photographer"
              v-model="returnedListing[0].crew_positions"
            />
            <label for="Set Photographer">Set Photographer</label>
            <input
              type="checkbox"
              id="Producer"
              value="Producer"
              v-model="returnedListing[0].crew_positions"
            />
            <label for="Producer">Producer</label>
            <input
              type="checkbox"
              id="Production Designer"
              value="Production Designer"
              v-model="returnedListing[0].crew_positions"
            />

            <label for="Production Designer">Production Designer</label>

返回列表

 const [actors, returnedListing] = await Promise.all([
        $axios.$get(`/api/v1/actors/`, {
          params: {
            user: body
          }
        }),
        $axios.$get(`/api/v1/listings/`, {
          params: {
            random_public_id: params.id
          }
        })
      ]);

      return { actors, returnedListing };

虚拟 API 对象

{
    "id": 15,
    "title": "NUmber 15",
    "start_date": "2021-03-04",
    "end_date": "2021-02-16",
    "location": "The Bronx",
    "overview": "sdfds",
    "studio": "sdfdsf",
    "poster": null,
    "crew_positions": "Set Photographer, Producer, Production Designer",
    "post_production_positions": "Editing, AD",
    "random_public_id": null,
    "date_submitted": null,
    "user": 1
}

基本上我想弄清楚如果它的值是 ['Set Photographer', 'Producer'] 并在“Production Designer”保持未选中状态时选中这两个框,如何循环返回Listing[0].crew_positions。

【问题讨论】:

  • 您能分享一下您的数据是什么样的吗?
  • @PriyankKachhela 当然,刚刚做了
  • 所以首先你需要将crew_positions使用string的split方法转换成数组,然后你可以使用数组的includes方法来检查值是否在数组中。

标签: javascript vue.js vuejs2


【解决方案1】:

第一个问题(如 cmets 中所述)crew_positions 不是array,而是逗号分隔的string。然后你可以遍历它们并设置复选框。

const returnedListingArray = [{
    "id": 15,
    "title": "NUmber 15",
    "start_date": "2021-03-04",
    "end_date": "2021-02-16",
    "location": "The Bronx",
    "overview": "sdfds",
    "studio": "sdfdsf",
    "poster": null,
    "crew_positions": "Set Photographer, Producer, Production Designer",
    "post_production_positions": "Editing, AD",
    "random_public_id": null,
    "date_submitted": null,
    "user": 1
  },
  {
    "id": 16,
    "title": "NUmber 16",
    "start_date": "2021-03-04",
    "end_date": "2021-02-16",
    "location": "The Bronx",
    "overview": "sdfds",
    "studio": "sdfdsf",
    "poster": null,
    "crew_positions": "Set Photographer, Production Designer",
    "post_production_positions": "Editing, AD",
    "random_public_id": null,
    "date_submitted": null,
    "user": 1
  }
]

Vue.component("CrewPositionInput", {
  props: ["id", "crewPosition", "checked"],
  methods: {
    handleCbClick() {
      this.$emit("update:position-status", this.crewPosition)
    },
  },
  template: `
    <label
      :for="id"
    >
      <input
        type="checkbox"
        :id="id"
        :value="crewPosition"
        :checked="checked"
        @click="handleCbClick"
      />
      {{ crewPosition }}
    </label>
  `
})

Vue.component("CrewPositions", {
  props: ["id", "possibleCrewPositions", "crewPositions"],
  methods: {
    toggleCrew({
      crew
    }) {
      const positions = this.crewPositions.includes(crew) ?
        this.crewPositions.filter(item => item !== crew) : [...this.crewPositions, crew]
      this.$emit("update:crewPositions", positions)
    },
  },
  template: `
    <div>
      <crew-position-input
        v-for="position in possibleCrewPositions"
        :key="position + id"
        :id="position + id"
        :crew-position="position"
        :checked="crewPositions.includes(position)"
        @update:position-status="(crew) => toggleCrew({ crew })"
      />
    </div>
  `
})

new Vue({
  el: "#app",
  data() {
    return {
      returnedListings: [],
      possibleCrewPositions: [],
    }
  },
  mounted() {
    this.returnedListings = returnedListingArray.map(({
      crew_positions,
      id,
      // ...rest // commenting out - this is just a snippet, no need for large objects
    }) => ({
      id,
      crew_positions: crew_positions.split(", "), // splitting string to array
    }))

    // just to make it a little more dynamic:
    this.possibleCrewPositions = [...new Set(this.returnedListings.reduce((a, c) => {
      return [...a, ...c["crew_positions"]]
    }, []))]
  },
  template: `
    <div>
      <crew-positions
        v-for="listing in returnedListings"
        :key="listing.id"
        :id="listing.id"
        :possible-crew-positions="possibleCrewPositions"
        :crew-positions.sync="listing['crew_positions']"
      />
      {{ returnedListings }}
    </div>
  `
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>

简短说明

  1. CrewPositionInput 是一个无状态组件,它接受来自其父级的 idcrewPositionchecked 属性。它唯一能做的就是在click 上发出一个自定义事件,并将this.crewPosition 作为有效负载。
  2. CrewPositions 组件实际上是CrewPositionInput 组件的列表,它将 props 传递给其子组件并处理来自它们的 update:position-status 自定义事件。在任何update:position-status 自定义事件上,它都会向其父级重新发送一个数组(实际上是一个crewPositions 数组)。
  3. 最顶层的组件处理数据处理(如crew_positions拆分)和状态管理(如更新存储的对象数组(returnedListings)中的crew_positions。更新通过.syncmore on sync here)完成) - 这是一种方便的方法,但它有其限制(例如变量和事件的命名必须遵循。某种模式)。

possibleCrewPositions 只是一种基于数据源(动态)创建可用复选框的方法。

【讨论】:

  • 感谢您的帮助,我仍在努力理解每个部分,但我对如何实施解决方案有了大致的了解。我对“船员”的来源/在 toggleCrew 方法中填充的内容有点困惑,但是,如果您能解释一下,那就太好了!
  • @yetiblue 添加了一个简短的解释 - 希望对您有所帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-25
  • 2019-05-29
  • 1970-01-01
  • 1970-01-01
  • 2015-10-29
  • 2021-05-21
  • 1970-01-01
相关资源
最近更新 更多