0đź‘Ť
âś…
There’re some errors in your code:
@click="!(displayAddressBook)"
should be@click="displayAddressBook = !displayAddressBook"
– the first really does nothing (interesting), the second (suggested) sets the value ofdisplayAddressBook
to the opposite it has currently.- the input-address component does not really do anything with the input field (missing
v-model
) - the changes in the child component (
input-address
) are not sent back to the parent (added awatch
er to do that in the child component) - the parent component (
mail-composer
) has to handle the values emitted from the child (added the@address-change
action handler) - the
v-for
in yourinput-address
component does not have akey
set. Addedkey
by using the index for it (not the best solution, but easy to do). - just put
createmail.to: {{ createmail.to }}
at the end ofMailComposer
, so you can see how it changes
Suggestions
- always use CamelCase for component names – if you get used to it, then you get less “why is it not working?!” moments
- watch for typos:
createmail
doesn’t look good –createEmail
or just simplycreateemail
would be better (ok, it doesn’t look so nice – maybe you should choose a totally different name for that)
Vue.component('InputAddress', {
props: ["addresses"],
data() {
return {
displayAddressBook: false,
address: null
}
},
template: `
<div>
<label><b>To: </b>
<input
type="text"
v-model="address"
/>
<button
@click="displayAddressBook = !displayAddressBook"
>
Address Book
</button>
</label>
<ul v-if="displayAddressBook">
<li
v-for="(address, i) in addresses"
:key="i"
@click="clickAddressHandler(address)"
>
{{address}}
</li>
</ul>
</div>
`,
watch: {
address(newVal) {
// emitting value to parent on change of the address
// data attribute
this.$emit('address-change', newVal)
}
},
methods: {
clickAddressHandler(address) {
// handling click on an address in the address book
this.address = address
this.displayAddressBook = false
}
}
})
Vue.component('MailComposer', {
props: ['addressesbook'],
data() {
return {
createmail: {
to: '',
subject: '',
body: ''
}
}
},
methods: {
send: function(createmail) {
this.$emit('send', createmail);
},
addressChangeHandler(value) {
this.createmail.to = value
}
},
template: `
<div>
<input-address
:addresses="addressesbook"
v-model="createmail.to"
@address-change="addressChangeHandler"
/>
<p>
<b>Subject: </b>
<input
type="text"
v-model="createmail.subject"
/>
</p>
<p>
<b>Body: </b>
<textarea v-model="createmail.body"></textarea>
</p>
<button @click="send(createmail)">Send</button><br />
createmail.to: {{ createmail.to }}
</div>
`
});
new Vue({
el: "#app",
data: {
addressesbook: [
'abcd@abcd.com',
'fghi@fghi.com'
]
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<mail-composer :addressesbook="addressesbook" />
</div>
Source:stackexchange.com