简体   繁体   中英

Why if I get the object property within the computed object gets undefined but not the object itself? Which approach fits better in this context?

My Greeting.

To put in context, my purpose of asking this question is to be able to render a child component inside a form based on the selected option of the <app-selector> Vue component as simple and silly as that.

For the sake of simplicity. I've made a snippet down here to expose what I'm trying to figure out. Basically, the aim is to get the component name to be rendered by using the computed property cardTypeComponent . However, I want to fathom the way cardTypeComponent is working, since I cannot see why, in one hand, the first return ( return this.form ) is giving the object ( this.form ) with the property I want ( card_type ) but on the other hand the second return ( return this.form.card_type ? this.form.card_type + 'Compose' : '' ) is giving me an empty string, assuming this.form.card_type is undefined when it is clear looking at the first return that, in fact, is not taking it as undefined .

There is way more context, since once the option is selected there is a validation process from the server before setting the value inside this.form object. Moreover, the form interaction is through steps, so once the user select the option he has to click a button to reach the form fields that corresponds to that type card selected, therefore the component is not going to be rendered the very first moment the user selects an option as in the snippet approach. However, it would entangle what I'm asking. Thanks beforehand.

It is better to use the Fiddle link below.

Snippet

 var appSelector = Vue.component('app-selector', { name: 'AppSelector', template: `<div> <label for="card_type">Card Type:</label> <select :name="name" value="" @change="sendSelectedValue"> <option v-for="option in options" :value="option.value"> {{ option.name }} </option> </select> </div>`, props: { name: { required: false, type: String, }, options: { required: false, type: Array, } }, methods: { sendSelectedValue: function(ev) { this.$emit('selected', ev.target.value, this.name) } } }); var guessByImageCompose = Vue.component({ name: 'GuessByImageComponse', template: `<p>Guess By Image Compose Form</p>` }); var guessByQuoteCompose = Vue.component({ name: 'GuessByQuoteComponse', template: `<p>Guess By Quote Compose Form</p>` }); new Vue({ el: '#app', components: { appSelector: appSelector, guessByImageCompose: guessByImageCompose, guessByQuoteCompose: guessByQuoteCompose, }, data() { return { form: {}, card_types: [ { name: 'Guess By Quote', value: 'GuessByQuote' }, { name: 'Guess By Image', value: 'GuessByImage' } ], } }, computed: { cardTypeComponent: function() { return this.form; // return { card_type: "GuessByImage" || "GuessByQuote" } return this.form.card_type ? this.form.card_type + 'Compose' : ''; // return empty string ("") Why? } }, methods: { setCardType: function(selectedValue, field) { this.form[field] = selectedValue; console.log(this.form.card_type); // GuessByImage || GuessByQuote console.log(this.cardTypeComponent); // empty string ("") Why? } }, mounted() { console.log(this.cardTypeComponent); // empty string ("") } });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <form action="#" method="post"> <app-selector :name="'card_type'" :options="card_types" @selected="setCardType" > </app-selector> {{ cardTypeComponent }} <!-- Always empty string !--> <component v-if="cardTypeComponent !== ''" :is="cardTypeComponent"> </component> </form> </div>

https://jsfiddle.net/k7gnouty/2/

You're setting a property on this.form which is not initialized first in data . This means you have run into Vue's change detection caveat . Use Vue.set when setting it:

methods: {
  setCardType: function(selectedValue, field) {
    Vue.set(this.form, field, selectedValue);
  }
}

Alternatively, you could declare the properties first if that works better for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM