基于Element-plus封装配置化表单组件(组件的v-model实现)

本文详细介绍了Vue中v-model的工作原理,包括其在组件内部的实现方式,如何使用计算属性来支持双向绑定,以及如何在一个组件上绑定多个属性。此外还探讨了在处理对象类型数据时的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、预备知识

1.1 组件的v-model

前面我们在input中可以使用v-model来完成双向绑定:

  • 这个时候往往会非常方便,因为v-model默认帮助我们完成了两件事;
  • v-bind:value的数据绑定 和 @input的事件监听
    在这里插入图片描述

如果我们现在封装了一个组件,其他地方在使用这个组件时,是否也可以使用v-model来同时完成这两个功能呢?

  • 也是可以的,vue也支持在组件上使用v-model;

当我们在组件上使用的时候,等价于如下的操作:
在这里插入图片描述

  • 我们会发现和input元素不同的只是属性的名称和事件触发的名称而已;

1.2 组件v-model的实现

那么,为了我们的MyInput组件可以正常的工作,这个组件内的 <input> 必须:

  • 将其 value attribute 绑定到一个名叫 modelValue 的 prop 上;
  • 在其 input 事件被触发时,将新的值通过自定义的 update:modelValue 事件抛出;
    在这里插入图片描述

1.3 computed实现

我们依然希望在组件内部按照双向绑定的做法去完成,应该如何操作呢?我们可以使用计算属性的setter和getter来完成。
在这里插入图片描述

1.4 绑定多个属性

我们现在通过v-model是直接绑定了一个属性,如果我们希望绑定多个属性呢? p也就是我们希望在一个组件上使用多个v-model是否可以实现呢?

  • 我们知道,默认情况下的v-model其实是绑定了 modelValue 属性和 @update:modelValue的事件;
  • 如果我们希望绑定更多,可以给v-model传入一个参数,那么这个参数的名称就是我们绑定属性的名称;

注意:这里我是绑定了两个属性的
在这里插入图片描述

v-model:title相当于做了两件事:

  • 绑定了title属性;
  • 监听了 @update:title的事件;
    在这里插入图片描述

二、如果父组件中的v-model绑定的是一个对象,那么使用ref,而不要使用reactive。

2.1 实现方法一(推荐)

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2.2 实现方法二(错误)

如果父组件中的v-model绑定的是一个对象,子组件不要采用computed这种做法(违背了Vue单向数据流的原则),而要使用上面子组件中使用ref拷贝一个新对象的做法

  • 如果父组件中的v-model绑定的是一个普通的字符串,那么可以采用子组件中使用computed这种做法。
  • 因为父组件中的v-model绑定的是一个对象时,对象的属性值发生改变不会触发computed的set函数,子组件中直接修改了父组件传递过来的modelValue,违背了Vue单向数据流的原则
  • 而父组件中的v-model绑定的是一个普通的字符串时,会触发computed的set函数,子组件中没有直接修改父组件传递过来的modelValue
    在这里插入图片描述
### 封装 Vue3 和 Element Plus 的图片上传组件 #### 组件创建与配置 为了实现一个可重用的图片上传组件,在 `components` 文件夹下新建名为 `UploadImage.vue` 的文件。此操作使得组件可以在整个项目中被轻松调用[^1]。 ```html <template> <div class="upload-container"> <!-- 使用 el-upload 来处理文件选择 --> <el-upload :action="uploadUrl" list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :before-upload="beforeAvatarUpload" :auto-upload="false" ref="uploadRef" > <i class="el-icon-plus"></i> </el-upload> <!-- 预览对话框 --> <el-dialog v-model="dialogVisible" size="tiny"> <img width="100%" :src="dialogImageUrl" alt="" /> </el-dialog> </div> </template> ``` 上述模板定义了一个基于 `el-upload` 构建的基础结构,支持预览和移除已选图片的功能[^2]。 #### 方法定义 在 `<script setup>` 或者选项 API 中定义必要的逻辑来控制上传行为: ```javascript <script lang="ts"> import { ref } from 'vue'; // 定义变量用于存储临时状态 const dialogImageUrl = ref(''); const dialogVisible = ref(false); const uploadRef = ref(null); function handleRemove(file, fileList) { console.log(file, fileList); } function handlePictureCardPreview(file) { dialogImageUrl.value = file.url; dialogVisible.value = true; } function beforeAvatarUpload(file) { const isJPG = file.type === 'image/jpeg' || file.type === 'image/png'; const isLt2M = file.size / 1024 / 1024 < 2; if (!isJPG) { ElMessage.error('仅允许上传 JPG/PNG 格式的图片!'); } if (!isLt2M) { ElMessage.error('图片大小不得超过 2MB!'); } return isJPG && isLt2M; } </script> ``` 这段脚本提供了对上传前验证的支持以及对于用户交互事件(如点击预览按钮)作出响应的能力[^3]。 #### 自动化提交与手动触发 当设置 `:auto-upload="false"` 参数时,意味着不会自动发起 HTTP 请求;相反地,开发者可以通过编程方式通过 `.submit()` 调用来启动上传过程。这给予开发人员更大的灵活性去决定何时发送请求给服务器[^4]。 ```typescript // 手动触发表单提交 function submitForm() { (uploadRef as any).submit(); } ``` 以上就是构建一个简单而有效的 Vue3 图片上传组件所需的关键要素和技术细节说明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值