Hesaplanan bir mülkte $ ref kullanma


87

$refsBilgisayarlı içeriye nasıl erişirim? Hesaplanan özellik ilk çalıştırıldığında her zaman tanımsızdır.


6
Evet, yalnızca ilk oluşturma döngüsü tamamlandığında tanımlanır. Değeri ne olursa olsun, reaktif olmadığı için hesaplanan özelliklerin içinde $ refs kullanılması kesinlikle önerilmez. vuejs.org/v2/guide/components.html#Child-Component-Refs Daha iyi bir model bulmanız gerekebilir ...
Cobaltway

Monte
edilenin

Yanıtlar:


135

Burada kendi sorumu cevaplayacak olursam, başka hiçbir yerde tatmin edici bir cevap bulamadım. Bazen bazı hesaplamalar yapmak için sadece bir dom öğesine erişmeniz gerekir. Umarım bu başkalarına yardımcı olur.

Bileşen monte edildikten sonra hesaplanan özelliği güncellemesi için Vue'yu kandırmak zorunda kaldım.

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

2
Tam olarak aynı gereksinim vardı ve bulduğum tek uygulanabilir çözüm buydu. Sınıf özelliğini hesaplanan bir özelliğe bağlar ve iç içe bir bileşende (ref) bazı özellikler ayarlanmışsa bazı sınıfları uygulamak zorunda kalır.
Christophe Geers

@Bondsmith Üzgünüm haha, ben soruyu soran ve yanıtlayan benim, sanırım kendi cevabımı kabul etmeyi unuttum
Eric Guan

Fark etmedim Bu çok komik ツ
Bondsmith

çok yardımcı oldu, başkalarına yardım etmek için kendi sorunuzu yanıtlamaya zaman ayırdığınız için teşekkürler @EricGuan
timmyLtus

vay çok yararlı
passionateLearner

20

Vue js kılavuzundan alıntı yapmanın önemli olduğunu düşünüyorum :

$ referanslar yalnızca bileşen oluşturulduktan sonra doldurulur ve reaktif değildirler. Bu sadece doğrudan çocuk manipülasyonu için bir kaçış yolu olarak düşünülmüştür - şablonlar veya hesaplanan özellikler içinden $ refs'e erişimden kaçınmalısınız.

Bu nedenle, her zaman yolunuzu kesebilmenize rağmen, yapmanız gereken bir şey değildir.


15

Eğer gerekirse $refsbir sonraki v-ifsen kullanabilirsiniz updated() kanca.

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


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

düzgün hile! Bağımlılıklar olarak kaydedilmeleri için v-ifkoşulların computedmantığına dahil edin. Tam olarak bir öğenin merakının yanıtı refve değiştirilerek değiştirildiv-if
plong0

9

Sadece aynı problemle geldim ve bunun, hesaplanan özelliklerin çalışmayacağı bir durum olduğunu fark ettim.

Mevcut belgelere göre ( https://vuejs.org/v2/guide/computed.html ):

"[...] Hesaplanan bir özellik yerine, aynı işlevi bir yöntem olarak tanımlayabiliriz. Son sonuç için, iki yaklaşım aslında tamamen aynıdır. Ancak, fark, hesaplanan özelliklerin reaktiflerine göre önbelleğe alınmasıdır. bağımlılıklar. Hesaplanan bir mülk, yalnızca reaktif bağımlılıklarından bazıları değiştiğinde yeniden değerlendirilir "

Dolayısıyla, bu durumlarda (muhtemelen) olan şey, bileşenin monte edilmiş yaşam döngüsünü bitirmenin ve referansları ayarlamanın, hesaplanan özelliğin bağımlılıklarında reaktif bir değişiklik olarak sayılmamasıdır.

Örneğin benim durumumda ref tablomda seçili satır olmadığında devre dışı bırakılması gereken bir düğme var. Yani bu kod çalışmayacak:

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

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

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

Yapabileceğiniz şey, hesaplanan özelliği bir yöntemle değiştirmektir ve bu düzgün çalışmalıdır:

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

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

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

3
Bence bu yaklaşım şu ana kadarki en iyisi. O dışarı talimatları yaymak değil data(), updated()ve diğer parçalar. Temiz ve öz.
MongoLato

3

Benim gibi bazı verileri desteklemesi gereken diğer kullanıcılar için, databunun yerine kullandımcomputed

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

İsterseniz özellik bağlamayı kullanın. : devre dışı pervane bu durumda reaktiftir

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

Ancak iki alanı kontrol etmek için kukla yöntem olarak başka bir yol bulamadım:

<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

Ben de benzer bir durumdaydım ve bunu şu şekilde düzelttim:

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

Ve sonra değişkeni izlersiniz:

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

Dikkat ifvarlığını değerlendirir this.$refsve onu değiştirir verilerinizi olsun.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.