Vue.Js hesaplanan özellikleri parametreleri iletebilir miyim


199

Vue.js'de hesaplanan özelliklerde parametre iletmek mümkün mü? Ben hesaplı kullanarak getters / setter sahip görebiliyorum, onlar bir parametre almak ve bir değişkene atayabilirsiniz. dokümantasyondaki gibi :

// ...
computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}
// ...

Bu da mümkün mü:

// ...
computed: {
  fullName: function (salut) {
      return salut + ' ' + this.firstName + ' ' + this.lastName    
  }
}
// ...

Computed özelliği bir argüman alır ve istenen çıktıyı döndürür. Ancak bunu denediğimde, bu hatayı alıyorum:

vue.common.js: 2250 Yakalanmamış TypeError: fullName bir işlev değil (…)

Bu gibi durumlar için yöntemler kullanmalı mıyım?


5
Hayır, parametreleri hesaplanan özelliklere geçiremezsiniz. Evet, yöntemleri kullanmak bunu yapmanın en kolay yoludur.
nils

Yanıtlar:


270

Büyük olasılıkla bir yöntem kullanmak istiyorsunuz

<span>{{ fullName('Hi') }}</span>

methods: {
  fullName(salut) {
      return `${salut} ${this.firstName} ${this.lastName}`
  }
}

Daha uzun açıklama

Teknik olarak, aşağıdaki gibi bir parametreyle hesaplanan bir özelliği kullanabilirsiniz:

computed: {
   fullName() {
      return salut => `${salut} ${this.firstName} ${this.lastName}`
   }
}

(Teşekkürler Unirgy için temel kod için .)

Hesaplanan özellik ve yöntem arasındaki fark, hesaplanan özelliklerin önbelleğe alınması ve yalnızca bağımlılıkları değiştiğinde değişmesidir. Bir yöntem her çağrıldığında değerlendirilir .

Parametrelere ihtiyacınız varsa, böyle bir durumda bir yöntem üzerinde hesaplanan özellik işlevini kullanmanın hiçbir faydası yoktur. Vue örneğine bağlı parametreli bir getter işlevine sahip olmanıza izin verse de, önbelleği kaybedersiniz, böylece orada gerçekten herhangi bir kazanç olmaz, aslında reaktiviteyi (AFAIU) bozabilirsiniz. Bu konuda daha fazla bilgiyi Vue belgelerinde https://vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods

Eğer yalnızca kullanışlı bir durumdur zorunda bir alıcı kullanmak ve onu parametrelenmişse olması gerekir. Örneğin, bu durum Vuex'te olur . Vuex'te mağazadan parametreli sonuç almanın tek yolu budur (eylemler zaman uyumsuzdur). Bu nedenle bu yaklaşım, alıcıları için resmi Vuex belgeleri tarafından listelenmiştir. Https://vuex.vuejs.org/guide/getters.html#method-style-access


1
Kullanılması <span v-text="fullName('Hi')"></span>yerine, aynı zamanda çalışır.
SalchiPapa

2
Sorun şuydu <span :text="message"></span>, artık Vue 2.0 için çalışmıyor, bunun yerine bir tane kullanmak zorundaydı: <span v-text="message"></span>ya <span>{{ message }}</span>da bu kodda gösterildiği gibi: codepen.io/Ismael-VC/pen/dzGzJa
SalchiPapa

1
Haklısın. Bunun 2.0'da değiştiğini fark etmedim. Düzeltme için teşekkürler!
damienix

4
Hesaplanan özellikler, herhangi bir parametre ile çağrılmasını desteklemeyen ES5 alıcı sözdizimini kullanır (parantez yoktur). Bu, dil düzeyinde bir sınırlamadır ve Vue.js'ye bu şekilde dahil edilmiştir.
damienix

1
@PedroMoreira'ya çok geç cevap verdiğim için üzgünüm, bunu analiz etmek için biraz zaman buldum. Gerçekten yazdıklarımın açık ve karışık olmadığı konusunda haklısın :) Cevabı düzelttim ve daha net ve doğru yapmak için onu yeniden yazmak için elimden geleni yaptım. Şimdi net olup olmadığını bana bildirebilirsiniz. Teşekkürler.
damienix

27

Yöntemleri kullanabilirsiniz, ancak veri değiştirmiyorsa veya dış etkileri yoksa yöntemler yerine hesaplanan özellikleri kullanmayı tercih ederim.

Hesaplanan özelliklere bu şekilde argümanlar iletebilirsiniz (belgelenmez, ancak koruyucular tarafından önerilir, nerede olduğunu unutmayın):

computed: {
   fullName: function () {
      var vm = this;
      return function (salut) {
          return salut + ' ' + vm.firstName + ' ' + vm.lastName;  
      };
   }
}

EDIT: Lütfen bu çözümü kullanmayın, sadece herhangi bir fayda olmadan kodu karmaşıklaştırır.


Bir referans sağlayabilirseniz gerçekten yardımcı olacaktır. Bu çalışmalı.
Saurabh

@saurabh, github'da gerçekten açıklayıcı olmayan bir sorunun çözümü için özür dilerim ve şu anda bulamıyorum ...
Unirgy

Bu benim için çalışıyor, ancak hayranı olmadığım tek şey, gerçek özellik yerine bir işlev döndürmesi, bu yüzden VueJS aygıtları sonuçları hiçbir yerde göstermiyor. Bunun hesaplanmış özellikler için tipik olup olmadığından emin değilim, ancak sorun gidermeyi biraz zorlaştırıyor.
Nate Ritter

4
Önbelleğe alma işlemini nasıl gerçekleştirir? Parametre değiştiğinde düzgün çalışır mı?
damienix

Ben dönüş işlevi içinde bir şey önbellek olacağını inanmıyorum. Yöntemler arasındaki fark tamamen konvansiyonel olacaktır (yöntemlerin etkisi vardır, hesaplanan sadece elde etmek içindir)
Unirgy

8

Teknik olarak, bir parametreyi hesaplanan bir işleve geçirebiliriz, aynı şekilde vuex'teki bir alıcı işlevine bir parametre geçirebiliriz. Böyle bir işlev, işlevi döndüren bir işlevdir.

Örneğin, bir mağazanın alıcılarında:

{
  itemById: function(state) {
    return (id) => state.itemPool[id];
  }
}

Bu alıcı bir bileşenin hesaplanan işlevlerine eşlenebilir:

computed: {
  ...mapGetters([
    'ids',
    'itemById'
  ])
}

Ve bu hesaplanan işlevi şablonumuzda aşağıdaki gibi kullanabiliriz:

<div v-for="id in ids" :key="id">{{itemById(id).description}}</div>

Parametre alan hesaplanmış bir yöntem oluşturmak için aynı yaklaşımı uygulayabiliriz.

computed: {
  ...mapGetters([
    'ids',
    'itemById'
  ]),
  descriptionById: function() {
    return (id) => this.itemById(id).description;
  }
}

Ve bunu şablonumuzda kullanın:

<div v-for="id in ids" :key="id">{{descriptionById(id)}}</div>

Bununla birlikte, burada Vue ile bir şeyler yapmanın doğru yolu olduğunu söylemiyorum.

Ancak, belirtilen kimliğe sahip öğe mağazada mutasyona uğradığında, görünümün bu öğenin yeni özellikleriyle içeriğini otomatik olarak yenilediğini gözlemleyebilirim (ciltleme iyi çalışıyor gibi görünüyor).


vah bu yüzden benim için çalıştı, vuex kullanmayın. bunun hesaplanmış özellikler yapmanın yasal bir yolu olup olmadığını da bilmek ister.
yeahdixon

1
Bu işe yararken, hesaplanan özelliğe bir yöntemle aynı şekilde davranır. yani hesaplanan bir özelliğin önbellekleme yararlarını kaybeder. Yani, bunu bir yöntem üzerinden kullanmanın gerçek bir kazancı yoktur. "Yöntemler aracılığıyla erişilen alıcıların her aradığınızda çalışacağını ve sonucun önbelleğe alınmadığını unutmayın." Bkz. Vuex.vuejs.org/en/getters.html
James

@ james.brndwgn ama temel alınan veriler değiştirildiğinde yöntemlerin yeniden çalıştırılmayacağından eminim. Gerçekten aradığım tek şey bu.
Alex

@Alex o zaman bir izleyici kullanıyor olmalısınız. Saatler
James

@ james.brndwgn Mümkünse bir gözlemciden çok bilgisayarlı bir özellik kullanmayı tercih ederim. Sadece ifadenizle ilgili sorun yaşıyordum: "Yani, bunu bir yöntem üzerinden kullanmanın gerçek bir kazancı yok." çünkü önbelleklemeden bile önemli bir fark vardır.
Alex

4

Filtreler , Vue bileşenleri tarafından sağlanan, şablon dinamik verilerinizin herhangi bir bölümüne biçimlendirme ve dönüşümler uygulamanızı sağlayan bir işlevdir.

Bir bileşenin verilerini veya herhangi bir şeyi değiştirmezler, ancak yalnızca çıktıyı etkilerler.

Bir ad yazdırdığınızı varsayalım:

new Vue({
  el: '#container',
  data() {
    return {
      name: 'Maria',
      lastname: 'Silva'
    }
  },
  filters: {
    prepend: (name, lastname, prefix) => {
      return `${prefix} ${name} ${lastname}`
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="container">
  <p>{{ name, lastname | prepend('Hello') }}!</p>
</div>

Bir filtre uygulamak için sözdizimine dikkat edin. filterName. Unix'e aşina iseniz, bir işlemin çıktısını bir sonrakine girdi olarak aktarmak için kullanılan Unix boru operatörü budur.

Bileşenin filters özelliği bir nesnedir. Tek bir filtre, değeri kabul eden ve başka bir değer döndüren bir işlevdir.

Döndürülen değer aslında Vue.js şablonunda yazdırılan değerdir.


3

Ayrıca bir işlevi döndürerek alıcılara argümanlar iletebilirsiniz. Bu, özellikle mağazadaki bir diziyi sorgulamak istediğinizde kullanışlıdır:

getters: {
  // ...
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }

Yöntemlerle erişilen alıcıların, her aradığınızda çalışacağını ve sonucun önbelleğe alınmadığını unutmayın.

Buna Yöntem Stili Erişimi denir ve Vue.js belgelerinde belgelenir .


2

Parametreleri iletebilirsiniz, ancak ya bir vue.js yolu değildir ya da yaptığınız yol yanlıştır.

Ancak bunu yapmanız gereken durumlar vardır. Size getter ve setter kullanarak hesaplanan özelliğe değer ileten basit bir örnek göstereceğim.

<template>
    <div>
        Your name is {{get_name}} <!-- John Doe at the beginning -->
        <button @click="name = 'Roland'">Change it</button>
    </div>
</template>

Ve senaryo

export default {
    data: () => ({
        name: 'John Doe'
    }),
    computed:{
        get_name: {
            get () {
                return this.name
            },
            set (new_name) {
                this.name = new_name
            }
        },
    }    
}

Düğme tıklandığında bilgisayarlı mülke 'Roland' adını veriyoruz ve set() veriyoruz adı 'John Doe' yerine 'Roland' olarak değiştiriyoruz.

Aşağıda hesaplanan alıcı ve ayarlayıcı ile kullanıldığında yaygın bir kullanım durumu vardır. Aşağıdaki vuex mağazanız olduğunu varsayalım:

export default new Vuex.Store({
  state: {
    name: 'John Doe'
  },
  getters: {
    get_name: state => state.name
  },
  mutations: {
    set_name: (state, payload) => state.name = payload
  },
})

Ve bileşeninizde v-modelvuex deposunu kullanarak bir girdiye eklemek istiyorsunuz .

<template>
    <div>
        <input type="text" v-model="get_name">
        {{get_name}}
    </div>
</template>
<script>
export default {
    computed:{
        get_name: {
            get () {
                return this.$store.getters.get_name
            },
            set (new_name) {
                this.$store.commit('set_name', new_name)
            }
        },
    }    
}
</script>

1

Neyi başarmaya çalıştığınızdan tam olarak emin değilim ama hesaplanmış yöntemi kullanarak mükemmel bir şekilde iyi görüneceksiniz!


1
computed: {
  fullName: (app)=> (salut)=> {
      return salut + ' ' + this.firstName + ' ' + this.lastName    
  }
}

kullanmak istediğinde

<p>{{fullName('your salut')}}</p>

1

Hesaplanan bir işlevi vardır düşünülebilir. Dolayısıyla, değerleme konusundaki bir örnek için açıkça aşağıdakileri yapabilirsiniz:

    methods: {
        validation(attr){
            switch(attr) {
                case 'email':
                    const re = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
                    return re.test(this.form.email);
                case 'password':
                    return this.form.password.length > 4
            }
        },
        ...
    }

Hangi gibi kullanacaksınız:

  <b-form-input
            id="email"
            v-model="form.email"
            type="email"
            :state="validation('email')"
            required
            placeholder="Enter email"
    ></b-form-input>

Hesaplamaya özgü önbelleği hala özleyeceğinizi unutmayın.


0

Params kullanmak için evet yöntemleri vardır. Yukarıda belirtilen cevaplar gibi, örneğin, yürütme çok hafif olduğu için yöntemleri kullanmak en iyisidir.

Yalnızca referans olarak, yöntemin karmaşık ve maliyetin yüksek olduğu bir durumda, sonuçları aşağıdaki gibi önbelleğe alabilirsiniz:

data() {
    return {
        fullNameCache:{}
    };
}

methods: {
    fullName(salut) {
        if (!this.fullNameCache[salut]) {
            this.fullNameCache[salut] = salut + ' ' + this.firstName + ' ' + this.lastName;
        }
        return this.fullNameCache[salut];
    }
}

not: Bunu kullanırken, binlerce uğraşıyorsanız bellek için watchout

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.