Salutations.
To provide some context, my intention in posing this query is to dynamically render a child component within a form based on the selection made using the <app-selector>
Vue component, as straightforward as that.
To simplify matters, I have included a snippet below to showcase the issue I am trying to resolve.
Essentially, I aim to determine how the computed property cardTypeComponent
functions. However, I am struggling to understand why the first return (return this.form
) returns the object (this.form
) with the desired property (card_type
), while the second return (
return this.form.card_type ? this.form.card_type + 'Compose' : ''
) provides an empty string, suggesting that this.form.card_type
is undefined
even though it seems clear from the first return that it is not treated as such.
There is more complexity involved, including a server-side validation process after selecting an option before populating the value inside the this.form
object. Additionally, the form interaction occurs in steps, so the component is only rendered after the user selects an option and clicks a button to access the corresponding form fields linked to that card type, rather than being immediately displayed upon selection as shown in the snippet. However, delving into these details may complicate the main question at hand. Thank you in advance.
Please refer to the Fiddle link provided 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>