#typescript #nuxt.js #vuejs3 #vue-composition-api
Вопрос:
Я новичок в Vue 3 и Nuxt JS Composition API (машинопись). Я создаю простой компонент формы/ввода, который, как я ожидал, будет вести себя при использовании на странице, передавая данные от родителя и от ввода дочернего компонента, каждое изменение входного значения будет передаваться родителю и будет обновляться в родительском шаблоне. Но, похоже, родитель не «уловил» излучаемое событие. Ниже приведена структура проекта.
|components
|----/forms
|-------- vi-form.vue
|-------- vi-input.vue
|pages
|----test.vue
|...everything else is as same as normal Nuxt JS Composition API project
компонентыформыvi-файл ввода.vue
<template lang="pug">
div()
input( v-model.trim="_model" :required="_isRequired" )
</template>
<script lang="ts">
import { computed, defineComponent, inject, ref, useContext, watch } from '@nuxtjs/composition-api'
export default defineComponent({
props: {
isRequired: {
type: Boolean
},
label: {
type: String
},
model: String
},
setup(props, { emit }) {
const _isRequired = computed(() => {
return props['isRequired'] || false
})
const _label = computed(() => {
return props['label'] || ''
})
const _model = computed({
get():string {
if (props['model'] != undefined)
return props['model']
return ''
},
set(value: string) {
emit('update:model', value)
}
})
return { _isRequired, _label, _model }
},
})
</script>
компонентыформыvi-форма.vue
<template lang="pug">
form(@submit.prevent='_submitCb')
slot
div
button(type='button' @click='_resetValue = !_resetValue')
span()
| {{ _cancelLbl }}
button(type='submit')
span()
| {{ _submitLbl }}
</template>
<script lang="ts">
import { computed, defineComponent, provide, ref } from '@nuxtjs/composition-api'
export default defineComponent({
props: {
submitCb: {
type: Function
},
submitLbl: {
type: String
},
cancelCb: {
type: Function
},
cancelLbl: {
type: String
},
resetForm: {
type: Boolean
}
},
setup(props) {
const _submitCb = computed(() => {
if (!props['submitCb']) {
return () => {
console.log('default submit callback')
}
}
return props['submitCb']
})
const _submitLbl = computed(() => {
return props['submitLbl'] || 'Submit'
})
const _cancelCb = computed(() => {
if (!props['cancelCb']) {
return () => {
console.log('default cancel callback')
}
}
return props['cancelCb']
})
const _cancelLbl = computed(() => {
return props['cancelLbl'] || 'Cancel'
})
const _resetForm = computed(() => {
if (props['resetForm'] amp;amp; (props['resetForm'] == true || props['resetForm'] == 'true'))
{
return true
}
return false
})
const _resetValue = ref(false)
provide('resetValue', _resetValue)
return { _submitCb, _submitLbl, _cancelCb, _cancelLbl, _resetForm, _resetValue }
},
})
</script>
pagestest.vue
<template lang="pug">
div(class="w-50 m-auto")
vi-form(:submitCb='submit' submitLbl='Submit' class="border")
vi-input(label="Fullname" :model="fakeData.full_name")
div(class="p-2 border")
h2() Form data
p() Fullname: {{ fakeData.full_name }}
</template>
<script lang="ts">
import { defineComponent, reactive, ref } from '@nuxtjs/composition-api'
export default defineComponent({
setup() {
const fakeData = reactive({
full_name: 'John Doe',
})
const submit = () => {
console.log(fakeData.full_name)
}
return { submit, fakeData }
},
})
</script>
My problem it I can not emit the event update:value
to parent, I tried emit with input
but still it seem that the parent page doesn’t handle this event. I also tested that if I put an input box in parent template and assign `v-model=’fakeData’ on it, I can alter the input’s value in parent and the child’s input value will also changed, but not the other way around.
Another try is that if I explicitly write like this
vi-input(label="Fullname" :model="fakeData.full_name" @update.value='v => fakeData = v')
then it works, I can change the parent’s data from the child component but this method of explicitly adding @update.value
in the component is not wrote in anywhere of the Vue documents that I read.
I’ve read articles about passing input data between child and parent component and they all showed this is kind of the correct way to do it but I still don’t understand why my code not working.
Vue 3 document ,
Vue 3 Data down Event up
Could anyone help me on this problem?