การใช้ $ refs ในคุณสมบัติที่คำนวณ


87

ฉันจะเข้าถึง$refsภายในคอมพิวเตอร์ได้อย่างไร จะไม่ได้กำหนดไว้เสมอในครั้งแรกที่เรียกใช้คุณสมบัติที่คำนวณ


6
ใช่จะกำหนดเฉพาะเมื่อการวนรอบการเรนเดอร์แรกเสร็จสิ้น สำหรับสิ่งที่คุ้มค่าไม่แนะนำให้ใช้ $ refs ในคุณสมบัติที่คำนวณอย่างชัดเจนเนื่องจากไม่มีปฏิกิริยา vuejs.org/v2/guide/components.html#Child-Component-Refsคุณอาจต้องหารูปแบบที่ดีกว่านี้ ...
Cobaltway

การใช้ฟังก์ชั่นนาฬิกาภายในตัวยึด: ป้อนคำอธิบายลิงก์ที่นี่
Phong Tran

คำตอบ:


135

จะตอบคำถามของตัวเองที่นี่ฉันไม่พบคำตอบที่น่าพอใจจากที่อื่น บางครั้งคุณเพียงแค่ต้องการเข้าถึงองค์ประกอบ dom เพื่อทำการคำนวณบางอย่าง หวังว่านี่จะเป็นประโยชน์กับคนอื่น ๆ

ฉันต้องหลอกให้ Vue อัปเดตคุณสมบัติที่คำนวณเมื่อติดตั้งส่วนประกอบแล้ว

Vue.component('my-component', {
    data(){
        return {
            isMounted: false
        }
    },
    computed:{
        property(){
            if(!this.isMounted)
                return;
            // this.$refs is available
        }
    },
    mounted(){
        this.isMounted = true;
    }
})

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

@Bondsmith ขอโทษฮ่าฮ่าฉันเป็นผู้ถามและตอบเดาว่าฉันลืมที่จะยอมรับคำตอบของตัวเอง
Eric Guan

ฉันไม่ได้ตระหนัก มันตลกดีツ
Bondsmith

มีประโยชน์มากขอบคุณ @EricGuan ที่สละเวลาตอบคำถามของคุณเองเพื่อช่วยเหลือผู้อื่น
timmyLtus

ว้าวมีประโยชน์มาก
passionLearner

20

ฉันคิดว่าการอ้างคำแนะนำ Vue jsเป็นสิ่งสำคัญ:

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

ดังนั้นจึงไม่ใช่สิ่งที่คุณควรทำแม้ว่าคุณจะสามารถแฮ็กข้อมูลได้ตลอดเวลา


15

หากคุณต้องการ$refsหลังv-ifคุณสามารถใช้updated() ตะขอ

<div v-if="myProp"></div>


updated() {
    if (!this.myProp) return;
    /// this.$refs is available
},

เคล็ดลับเรียบร้อย! รวมv-ifเงื่อนไขในcomputedตรรกะของเพื่อให้ได้รับการลงทะเบียนเป็นการอ้างอิง คำตอบสำหรับความอยากรู้ขององค์ประกอบที่มีrefและสลับโดยv-if
plong0

9

ฉันเพิ่งมาพร้อมกับปัญหาเดียวกันนี้และตระหนักว่านี่เป็นสถานการณ์ประเภทที่คุณสมบัติที่คำนวณแล้วจะไม่ทำงาน

ตามเอกสารปัจจุบัน ( https://vuejs.org/v2/guide/computed.html ):

"[... ] แทนที่จะเป็นคุณสมบัติที่คำนวณเราสามารถกำหนดฟังก์ชันเดียวกันเป็นวิธีการได้สำหรับผลลัพธ์สุดท้ายทั้งสองวิธีจะเหมือนกันทุกประการอย่างไรก็ตามความแตกต่างคือคุณสมบัติที่คำนวณจะถูกแคชตามปฏิกิริยา การอ้างอิงคุณสมบัติที่คำนวณได้จะประเมินอีกครั้งก็ต่อเมื่อการอ้างอิงเชิงปฏิกิริยาบางอย่างมีการเปลี่ยนแปลง "

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

ตัวอย่างเช่นในกรณีของฉันฉันมีปุ่มที่ต้องปิดใช้งานเมื่อไม่มีแถวที่เลือกในตารางอ้างอิงของฉัน ดังนั้นรหัสนี้จะไม่ทำงาน:

<button :disabled="!anySelected">Test</button>

computed: {
    anySelected () {
      if (!this.$refs.table) return false

      return this.$refs.table.selected.length > 0
    }
}

สิ่งที่คุณทำได้คือแทนที่คุณสมบัติที่คำนวณเป็นวิธีการและสิ่งนั้นควรทำงานได้อย่างถูกต้อง:

<button :disabled="!anySelected()">Test</button>

methods: {
    anySelected () {
      if (!this.$refs.table) return false

      return this.$refs.table.selected.length > 0
    }
}

3
ฉันคิดว่าแนวทางนี้เป็นแนวทางที่ดีที่สุด มันไม่ได้แพร่กระจายคำแนะนำในการออกไปdata(), updated()และส่วนอื่น ๆ สะอาดและรัดกุม
MongoLato

3

สำหรับผู้ใช้คนอื่น ๆ เช่นฉันที่ต้องการเพียงแค่ส่งข้อมูลบางอย่างไปยัง prop ฉันใช้dataแทนcomputed

Vue.component('my-component', {
    data(){
        return {
            myProp: null
        }
    },    
    mounted(){
        this.myProp= 'hello'    
        //$refs is available              
        // this.myProp is reactive, bind will work to property
    }
})

1

ใช้การผูกคุณสมบัติถ้าคุณต้องการ : ปิดใช้งาน prop เป็นปฏิกิริยาในกรณีนี้

<button :disabled="$refs.email ? $refs.email.$v.$invalid : true">Login</button>

แต่ในการตรวจสอบสองฟิลด์ฉันไม่พบวิธีอื่นที่เป็นวิธีการจำลอง:

<button
    :disabled="$refs.password ? checkIsValid($refs.email.$v.$invalid, $refs.password.$v.$invalid) : true">
            {{data.submitButton.value}}
</button>

methods: {
   checkIsValid(email, password) {
      return email || password;
   }
}

0

ฉันอยู่ในสถานการณ์ที่คล้ายกันและฉันแก้ไขด้วย:

  data: () => {
   return { 
    foo: null,
   }, // data

จากนั้นคุณดูตัวแปร:

    watch: {
     foo: function() {
       if(this.$refs)
        this.myVideo = this.$refs.webcam.$el;
       return null;
      },
    } // watch

สังเกตสิ่งifที่ประเมินการมีอยู่this.$refsและเมื่อมีการเปลี่ยนแปลงคุณจะได้รับข้อมูลของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.