Vue2+TypeScript中如何通过子组件向父组件v-model传递两类数据?
Vue 2 + TypeScript + vue-property-decorator 实现多数据从子组件传递到父组件
Vue 2 中单个组件默认只支持一个 v-model,所以不能直接给 attachments 也用 @VModel 装饰器。另外,input[type="file"] 无法通过 v-model 直接绑定数据,因为文件输入框的值是只读的,必须通过监听 change 事件来处理选中的文件。
下面是正确的实现方案:
父组件修改
使用 .sync 修饰符绑定 attachments,配合子组件的自定义事件更新父组件数据:
<template> <ChildComponent v-model="data" :attachments.sync="attachments" /> </template> <script lang="ts"> import { Component, Vue } from 'vue-property-decorator' import ChildComponent from '~/components/ChildComponent' @Component({ components: { ChildComponent } }) export default class ParentComponent extends Vue { data: { firstname: string; lastname: string } = { firstname: '', lastname: '' }; attachments: File[] = []; // 明确类型为File数组,替代any提升类型安全性 } </script>
子组件修改
用 @Sync 装饰器处理 attachments,同时手动处理文件输入框的 change 事件:
<template> <form> <input type="text" v-model="data.firstname" /> <input type="text" v-model="data.lastname" /> <input type="file" multiple @change="handleFileChange" /> </form> </template> <script lang="ts"> import { Component, VModel, Sync, Vue } from 'vue-property-decorator' @Component export default class ChildComponent extends Vue { @VModel() data!: { firstname: string; lastname: string }; // 明确数据类型 @Sync('attachments', { type: Array }) attachments!: File[]; handleFileChange(event: Event): void { const target = event.target as HTMLInputElement; if (target.files) { // 将FileList转为数组赋值,@Sync会自动触发update:attachments事件更新父组件 this.attachments = Array.from(target.files); } } } </script>
关键说明
@Sync装饰器:等价于父组件传递:attachments="attachments"并监听@update:attachments="attachments = $event",vue-property-decorator会自动处理事件触发逻辑。- 文件输入框处理:必须通过
change事件获取target.files,再转为数组赋值给attachments,因为FileList是类数组对象,直接赋值可能引发异常。 - 类型规范:尽量避免使用
any,明确数据类型能提升TypeScript的类型检查能力,减少潜在bug。
内容的提问来源于stack exchange,提问作者Olivier.C
相关产品推荐
相关产品推荐

