将prop传递给子组件并使用v-model。

huangapple go评论49阅读模式
英文:

Pass prop to child component with v-model

问题

I have implemented a custom component (InvoiceTypeAndCustomerInfo) that utilizes a VAutocomplete element. The selected customer is passed to the component via props.

However, I am encountering an issue where the VAutocomplete does not pre-select the customer that is passed through the props when the page is initially loaded. Instead, it appears as if no customer is selected by default, even though the customer prop is correctly passed to the VAutocomplete.

Script in InvoiceTypeAndCustomerInfo:

const props = defineProps({
  invoiceType: {
    type: Number,
    required: true,
  },
  customer: {
    type: Object,
    required: true,
  },
})

const customer = ref({ id: 0, fullname: '' })
const customers = ref([{ id: 1, fullname: 'Customer 1' }, { id: 2, fullname: 'Customer 2' }])

Template (AppAutocomplete is the renamed VAutocomplete):

<AppAutocomplete
    v-model="customer"
    :items="customers"
    item-title="fullname"
    item-value="id"
    return-object
    placeholder="Select Customer"
    class="mb-6"
    density="compact"
>

The parent uses InvoiceTypeAndCustomerInfo like this:

<InvoiceTypeAndCustomerInfo 
  :customer="customer"
  :invoice-type="invoiceType" 
  @customer-changed="customerChanged"
/>

where customer is defined like this:

const customer = ref({ id: 2, fullname: 'Customer 2' })

Why doesn't the VAutocomplete component display the customer from the props?

英文:

I have implemented a custom component (InvoiceTypeAndCustomerInfo) that utilizes a VAutocomplete element. The selected customer is passed to the component via props.

However, I am encountering an issue where the VAutocomplete does not pre-select the customer that is passed through the props when the page is initially loaded. Instead, it appears as if no customer is selected by default, even though the customer prop is correctly passed to the VAutocomplete.

Script in InvoiceTypeAndCustomerInfo:

const props = defineProps({
  invoiceType: {
    type: Number,
    required: true,
  },
  customer: {
    type: Object,
    required: true,
  },
})

const customer = ref({ id: 0, fullname: &#39;&#39; })
const customers = ref([{ id: 1, fullname: &#39;Customer 1&#39; }, { id: 2, fullname: &#39;Customer 2&#39; }])

Template (AppAutocomplete is the renamed VAutocomplete):

&lt;AppAutocomplete
    v-model=&quot;customer&quot;
    :items=&quot;customers&quot;
    item-title=&quot;fullname&quot;
    item-value=&quot;id&quot;
    return-object
    placeholder=&quot;Select Customer&quot;
    class=&quot;mb-6&quot;
    density=&quot;compact&quot;
&gt;

The parent uses InvoiceTypeAndCustomerInfo like this:

    &lt;InvoiceTypeAndCustomerInfo 
      :customer=&quot;customer&quot;
      :invoice-type=&quot;invoiceType&quot; 
      @customer-changed=&quot;customerChanged&quot;
    /&gt;

where customer is defined like this:

const customer = ref({ id: 2, fullname: &#39;Customer 2&#39; })

Why doesn't the VAutocomplete component display the customer tfrom the props?

答案1

得分: 0

看起来你两次使用了customer,一次作为引用(ref),一次作为属性(prop)。自动完成使用了引用,其中lastname为空 - 所以实际上已选择了一个值,只是没有标签来显示。

相反,你可以直接使用属性。只需从AppAutocomplete中删除引用和v-model,并将其连接到使用customer属性的方式:

const props = defineProps(['customer'])
const emit = defineEmits(['update:customer'])

在模板中:

<AppAutocomplete
    :modelValue="customer"
    @update:modelValue="emit('update:customer', $event)"
    ...
>

现在你可以这样使用:<InvoiceTypeAndCustomerInfo v-model:customer="yourCustomer"/>


或者,你可以重命名引用并使用观察器将属性值复制到内部引用。这取决于你想如何使用组件,特别是如何发出更新事件,这在问题中没有指定。但无论如何,你将使用观察器如下:

const selectedCustomer = ref()
watch(
  () => props.customer,
  () => selectedCustomer.value = props.customer,
  { immediate: true }
)

<AppAutocomplete
  v-model="selectedCustomer"
  ...
>

现在,对InvoiceTypeAndCustomerInfocustomer的任何更新都会更新所选的值。

希望有所帮助。

英文:

Looks like you are using customer twice, once as ref and once as prop. The autocomplete uses the ref, where lastname is empty - so there actually is a value selected, it just has no label to display.

Instead, you can use the prop directly. Just remove the ref and v-model from the AppAutocomplete, and wire it to work with the customer prop:

const props = defineProps([&#39;customer&#39;])
const emit = defineEmits([&#39;update:customer&#39;])

and in the template:

&lt;AppAutocomplete
    :modelValue=&quot;customer&quot;
    @update:modelValue=&quot;emit(&#39;update:customer&#39;, $event)&quot;
    ...
&gt;

Now you can do &lt;InvoiceTypeAndCustomerInfo v-model:customer=&quot;yourCustomer&quot;/&gt;


Alternatively, you can rename the ref and use a watcher to copy the prop value to the internal ref. This depends on how you want to use the component, particularly how you emit the update event, which is not specified in the question. But in any way, you will use watcher like:

const selectedCustomer = ref()
watch(
  () =&gt; props.customer,
  () =&gt; selectedCustomer.value = props.customer,
  {immediate: true}
)

and

&lt;AppAutocomplete
  v-model=&quot;selectedCustomer&quot;
  ...

Now any update to customer on InvoiceTypeAndCustomerInfo will update the selected value.

Hope it helps

huangapple
  • 本文由 发表于 2023年5月22日 01:35:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76301141.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定