Vue 2 กำลังปรับปรุงคุณสมบัติของบวัตถุอยู่ในตารางคู่ลำดับจากรอบการส่วนประกอบ

0

คำถาม

ฉันต้องทำงานอยู่บน Vue 2 โครงการซักพักและจา upgrading ของเรา linting ความต้องการฉันค้นพบที่เรามี prop การกลายพันธุ์เกิดข้อผิดพลาดในหลากหลายของเด็กส่วนประกอบ ในโครงการของเราเรามองผ่านเป็น singleton วัตถุเป็นอุปกรณ์ประกอบที่จะมีส่วนประกอบและถูกปรับปรับปรุงที่วัตถุงตรงจากเด็กส่วนประกอบ Vue ดูเหมือนจะแนะนำให้ใช้ v-bind.sync คุณสมบัติ สำหรับปรับปรุง props จากเด็กส่วนประกอบ(หรือใช้มพล่ามคำเชยๆออกมาไม่หยุด v-bind แล้ว v-on). เรื่องนี้อย่างไรก็ตามไม่ได้แก้ปัญหาของ prop ทำการแก้ไขจากรอบการส่วนประกอบ ในอาเรย์.

เอาเรื่องนี้(ชั่วโมง)รหัสสำหรับตัวอย่างเช่นนั้นใช้ prop การกลายพันธุ์:

ข้อควรจำ: เดาว่า const sharedObject: { arrayElements: Array<{ isSelected: boolean }> } = ...

หน้า.vue

<template>
  ...
  <Component1 :input1="sharedObject" />
  ...
</template>

Component1.vue

<template>
  ...
  <template v-for="elem in sharedObject.arrayElements">
    <Component2 :input2="elem" />
  </template>
  ...
</template>

Component2.vue

<template>
  ...
  <q-btn @click="input2.isSelected = !input2.isSelected"></q-btn>
  ...
</template>

อะไรคือคนที่เหมาะสมทางของกำลังปรับปรุงเป็นทรัพย์สินเหมือน input2.isSelected จากรอบการส่วนประกอบใน Vue 2? ทั้งหมดเข้ามาใกล้แล้วผมคิดของเป็นมีข้อบกพร่อง

มีชีวิตที่ยากลำบากเหมือนเข้ามาใกล้แล้ว

ฉัน เชื่อ ว่าเราจะชอบฟองนั่น input2.isSelected มีการแก้ไขอยู่ Component2 ต้อง Page.vueอย่างไรก็ตามนี่ดูเหมือนจะเหมือนกัให้ยุ่งเหยิงรหัสหรือไม่สบายใจรู้สึกนั่นเราเป็นแค่ที่จะข่ม linting เกิดข้อผิดพลาดใน roundabout ทาง


เพื่อแสดงให้เห็น"ยุ่งเหยิงรหัส"วิธีก่อนอื่นโปรดสังเกตว่า Page.vue ยังไม่รู้จักดัชนีของของ elem ใน sharedObject.arrayElements. ดังนั้นเราคงต้องส่งเสีเป็นวัตถุต้อง Page.vue จาก Component1 ซึ่งบรรจุของรัฐ input2.isSelected เช่นกันของดัชนีของ elem ใน sharedObject.arrayElements. มันจะยุ่งยากอย่างรวดเร็ว แล้วเรื่องตัวอย่างที่เราต้อง:

Component1.vue

<template>
  ...
  <template v-for="elem in sharedObject.arrayElements">
    <template v-for="elem2 in elem.arrayElements">
       <Component2 :input2="elem2" />
    </template>
  </template>
  ...
</template>

ในกรณีนี้งั้นเราอาจจะต้องผ่านขึ้นมา 2 indices! มันดูไม่เหมือนเป็นอาศัยอยู่ได้วิธีแก้ปัญหาของฉัน


ทางเลือกนั้นฉันคิดคือเรียกกลับฟังก์ชัน(ผ่านเป็นอุปกรณ์ประกอบผ่านทางส่วนประกอบลำดับชั้นในผังต้นไม้นั่นต้องใช้ฐานข้อมูลองอีลีเมนต์เราต้องการจะปรับปรุงและเป็นสิ่งที่มีคุณสมบัติของเราต้องการจะปรับปรุง(ใช้ Object.assign).

นี่มันทำให้ฉัน มาก ไม่ค่อยดีทุกครั้งตั้งแต่ฉันไม่รู้เหตุผลที่แท้จริงทำไมเราไม่สามารถปรับปรุงขอผ่าน-จา-อ้างอิงถึงอุปกรณ์ประกอบจากเด็กส่วนประกอบ. ฉันมันดูเหมือนมันเป็นแค่ roundabout ทางของกำลังปรับปรุงห้องผ่าน-จาก Component2 โดยไม่มี linter ถึงต้องคอยสังเกตไงล่ะ ถ้ามันมีบางเวทย์มนต์ทำการแก้ไขมันเกิดขึ้นกับพวกอุปกรณ์ประกอบตอนที่พวกเขาเดินผ่านเพื่อเด็กส่วนประกอบแล้วแน่นอนว่าส่งในวัตถุที่ฉันได้รับใน Component2 ที่เรียกกลับฟังก์ชั่นและรุงภาพลักษณ์ที่สมบูรณ์มันอยู่ที่พ่อแม่ส่วนประกอบคงโดยทั่วไปเป็นกำลังปรับปรุงที่อุปกรณ์ประกอบที่เด็กส่วนประกอบ,แต่มันซับซ้อนกว่านั้นแน่

อะไรคือคน ที่เหมาะสม ทางของสู้กับปัญหานี้อยู่ใน Vue 2?

1

คำตอบที่ดีที่สุด

3

คำถามที่ดีมากและการวิเคราะห์ของปัจจุบันของรัฐของนานขนาดนี้-ยืนเรื่องสำคัญที่สุดใน Vue ecosystem.

ใช่รุงภาพลักษณ์ที่สมบูรณ์"ค่าประเภท"จะบพวกอุปกรณ์ประกอบจากเด็ก เป็นปัญหา ที่มันสร้างขึ้น runtime ปัญหาเรื่อง(พ่อแม่ overwriting การเปลี่ยนแปลงตอนที่ส่งค่าการแสดงผล)และทำให้ Vue นสร้างเป็น runtime เกิดข้อผิดพลาดตอนที่มันจะเกิดขึ้น...

รุงภาพลักษณ์ที่สมบูรณ์เป็นทรัพย์สินของวัตถุเดินผ่านเป็นอุปกรณ์ประกอบที่ปลอดภัยแล้วจาก"นรหัสได้ผลดี"POV. โชคร้ายที่มันมีบางอย่างมีคนอยู่ในสังคมกับความเห็น(และหลายคนที่หูหนวกตาบอดตามพวกเขา)ว่านี่คือการต่อต้านรูปแบบ. ฉันไม่เห็นด้วยกับมันและเลี้ยงของอาร์กิวเมนต์หลายครั้งแล้ว(ตัวอย่างเช่น นี้). คุณอธิบายเหตุผลที่ดี-มันสร้างที่เปล่าประโยชน์เลยมีความซับซ้อน/boilerplate รหัส...

ดังนั้นสิ่งที่คุณกำลังรับมือกับมันแค่ linting กฏ(vue/ไม่-mutating-บพวกอุปกรณ์ประกอบ). มันเป็นเรื่อง ปัญหา/อย่าง นั้นเสการปรับแต่งค่าตัวเลือกนั้นควรจะอนุญาตให้บรรเทาคความเข้มงวดของกฏข้องกับหลายคดีอาร์กิวเมนต์หนึ่งตัวแต่มันได้น้อยมากความสนใจจาก maintainers(รู้สึกอิสระที่จะเลี้ยงของคุณเสียงนั่นเหมือนกัน)

สำหรับตอนนี้สิ่งที่คุณทำได้คือ:

  1. ปิดการทำงานของกฏ(ไกลจากดีแต่โชคดีที่ต้องขอบคุณเป็น Vue runtime เกิดข้อผิดพลาดคุณสามารถจับตัวจริงไม่ถูกต้องคดีระหว่างการพัฒนานแค่อดี)
  2. ยอมรับความเป็นจริงและใช้การวนรอบการทำงาน

Workaround ใช้ทั่วเมือง(ร้านขายเหมือน Vuex หรือ Pinia)

ข้อควรจำ:Pinia คือกำหนดเป็นคนต่อรุ่นของ Vuex จะมีเดียวกับรูปแบบ api

ท่านนายพลความคิดคือการสถานที่ที่ sharedObject ในร้านขายขอและใช้บพวกอุปกรณ์ประกอบเดียวที่จะนำมายังเด็กส่วนประกอบที่สิ่งที่ถูกต้อง-อยู่ในคดีของคน Component2 จะได้รับการดัชนีโดยอุปกรณ์ประกอบและดึงข้อมูที่ถูกต้องธาตุจากร้านขายของการใช้มัน

ร้านไหนดีสำหรับการวิเคราะห์ของเราเชื่อถือได้ใครโกลบอลของรัฐแต่ใช้แค่อร้องล่ะเมอร์เซดีสปิดให้มิค linting กฏมันแย่มาก ยังเป็นผลให้ส่วนประกอบเป็นควบคู่ไปที่ร้านขายของตัทั้งสอง reusability ต้องทรมานสักเพียงและทดสอบที่นั้นยาก

Workaround-เหตุการณ์

ใช่มันเป็นไปได้ที่จะสร้างองยุ่งยาแล้วมากมายของ boilerplate รหัสโดยใช้เพียงเหตุการณ์(โดยเฉพาะอย่างยิ่งถ้าคุณรังส่วนประกอบมากกว่าระดับ 2)แต่มันมีวิธีที่จะทำให้ทุกอย่างตั้งคำถามทำงานเรียบร้อย

ตัวอย่างเช่นในกรณีของคุณ Component2 ไม่จำเป็นต้องรู้ดัชนีที่คุณสามารถรับมือกับเหตุการณ์แบบนี้

// Component1
<template>
  ...
   <template v-for="elem in sharedObject.arrayElements">
    <template v-for="(elem2, index) in elem.arrayElements">
       <Component2 :input2="elem2" @update="updateElement($event, index)" />
    </template>
  </template>
  ...
</template>

ในกรณีของคุณค Component2 ทำการเปลี่ยนของเดี่ยวตรรกะทรัพย์สินแล้ว $event จะเรียบง่ายตรรกะ. ถ้ามันมีมากกว่าหนึ่งพื้นที่ที่ต้องการเปลี่ยนแปลงไปข้างใน Component2, $event สามารถเป็นวัตถุและคุณสามารถใช้วัตถุกระจายรูปแบบการสั่งงานกับ"simplify ง" Component2 (โดยใช้หนึ่งเหตุการณ์แทนที่จะเป็นของหลาย-หนึ่งสำหรับแต่ละบ้าน)

// Component2
<template>
  ...
  <input v-model="someText" type="text">
  <q-btn @click="updateInput('isSelected', !input2.isSelected)"></q-btn>
  ...
</template>
<script>
export default {
  props: ['input2'],
  computed: {
    someText: {
      get() { return this.input2.someText },
      set(newVal) { updateInput('someText', newVal) }
    }
  },
  methods: {
    updateInput(propName, newValue) {
      const updated = { ...this.input2 } // make a copy of input2 object
      updated[propName] = newValue  // change selected property

      this.$emit('update', updated) // send updated object to parent
    }
  }
}
</script>

เอ่อ...ฉันชอบแค่แบบอักษรที่จะปิดการใช้งานผู้ปกครองและตั้งค่าบางอย่างชัดเจนตั้งชื่อ conventions เพื่อบ่งบอกว่าส่วนประกอบต้องรับผิดชอบสำหรับการเปลี่ยนมันเป็นข้อมูล...

โปรดสังเกตว่ามันมีอีกการวนรอบการทำงานแบบใช้ this.$parent, inject\provide หรือเหตุการณ์รถบัสแต่พวกนั้น แย่จริงๆ

2021-11-24 09:42:19

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่