vue新增占比选项以及填写比例

本文介绍了一个施工管理系统中如何实现施工人员的新增与删除功能,并确保单个人员施工占比不超过100%。通过oninput事件限制输入框只接受数字且不超过100%,使用Vue.js实现添加和删除施工人员的操作,同时确保所有人员的施工占比总和不超过100%。在删除操作中,检查是否至少存在一位施工人员,新增操作则需先填写上一位人员信息。此外,还提供了计算并调整施工占比的函数以保持总和在合理范围内。

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

现在需要实现一个功能:新增/删除某个施工人员,并填写它占有总工程的比例,不能超过100%。

功能1:限制单个人员的比例,输入框不能填写数字以外的内容,不能填写负数,也不能超过100%。可以使用oninput进行限制:  

oninput="value=value.replace(/[^\d]/g,'')>100?100:value.replace(/[^\d]/g,'')"

通过value.replace方法将所有非数字替换成空,然后判断它是否超过100%。如果超过,则将其替换成100%。

功能2:添加新增/删除操作,用于增加施工人员以及对应的施工占比,其中vue部分如下:

<el-col :span="1">
  <el-button type="danger" @click="deleteMan(item,index)">删除</el-button>
</el-col>
<el-col :span="1">
  <el-button type="primary" @click="add" 
        v-if="index == arrayData.length - 1">新增</el-button>
</el-col>

其中arrayData为当前施工信息,这里数组不能为空。dataNum为当前计数:

arrayData:[{
  id:0,
  realName:'',
  userId:'',
  userName:'',
  orgId:'',
  workRate:''
}],
dataNum:0,

添加与删除部分代码,限制至少有一位人员参与:

deleteMan(item,index){
  if(this.arrayData.length<=1){//如果只有一个输入框则不可以删除
    this.$message.error('无法删除最后一名人员')
    return false
  }
  this.$confirm(`确定移除${item.realName}施工占比?`,'提示',{
    confirmButtonText: '确定',
    cancleButtonText: '取消',
    type: 'danger'
  }).then(() => {
    this.arrayData.splice(index,1)//删除了数组中对应的数据也就将这个位置的输入框删除
    this.dataNum--
  })
},
add(item){
  if(this.arrayData[this.dataNum].realName === ''){
    this.$message.warning('请先填写上一位人员')
    return false
  }
  this.arrayData.push(//增加就push进数组一个新值
    {
      id:++this.dataNum,
      realName:'',
      userId:'',  //id
      userName:'',  //账号
      orgId:'',
      workRate:''
    }
  )
},

功能3:限制所有施工人员的施工占比总和不能大于100%,首先是vue部分,通过函数进行计算:

<el-form-item
  label="施工占比">
  <el-input v-model="item.workRate"
    oninput="value=value.replace(/[^\d]/g,'')>100?100:value.replace(/[^\d]/g,'')"
    @change="calculateWorkRate(item.id)">
    <template slot="append">%</template>
  </el-input>
</el-form-item>

限制施工占比的方法部分js代码,通过监控当前id内容的变化来计算是否超出100%:

calculateWorkRate(id){
  let rate = 0;
  let over = 0;
  this.arrayData.forEach(item => {
    rate += item.workRate == '' ? 0 : parseInt(item.workRate)
    if(rate > 100) over = 100 - rate
    else over = 0
  })
  this.arrayData[id].workRate = parseInt(this.arrayData[id].workRate) + over
},

最后是完整的vue部分,其中handleBtnAdd方法是选择对应施工人员:

<el-row v-for="(item,index) in arrayData" :key="item.id">
  <el-col :span="10">
    <el-form-item
      label="施工人员" >
      <el-input v-model="item.realName" :readonly="true">
        <template slot="append"
        ><el-button type="primary" @click="handleBtnAdd">{{
            "选择"
          }}</el-button></template>
      </el-input>
    </el-form-item>
  </el-col>
  <el-col :span="10">
    <el-form-item
      label="施工占比">
      <el-input v-model="item.workRate"
        oninput="value=value.replace(/[^\d]/g,'')>100?100:value.replace(/[^\d]/g,'')"
        @change="calculateWorkRate(item.id)">
        <template slot="append">%</template>
      </el-input>
    </el-form-item>
  </el-col>
  <el-col :span="1" style="margin-left: 10px">
    <el-button type="danger" @click="deleteMan(item,index)">删除</el-button>
  </el-col>
  <el-col :span="1" style="margin-left: 30px">
    <el-button type="primary" @click="add" v-if="index == arrayData.length - 1">新增</el-button>
  </el-col>
</el-row>
<think>好的,我现在需要帮助用户解决在Vue3中集成和使用CropperJS的问题。首先,用户提供的引用内容提到了Vue-Cropperjs和CropperJS,但需要注意这些引用中有些可能适用于Vue2,而用户现在问的是Vue3。我需要先确认Vue3的支持情况。 根据引用3,Vue-Cropperjs的GitHub仓库地址是https://gitcode.com/gh_mirrors/vu/vue-cropperjs。不过我需要检查这个库是否支持Vue3。通常,许多Vue2的库可能没有官方迁移到Vue3,因此可能需要直接使用CropperJS库,而不是Vue的封装组件。引用4提到安装cropperjs的npm包,并且直接使用new Cropper(),这可能更适合Vue3的组合式API。 接下来,我需要整理步骤。首先安装cropperjs和它的CSS文件。然后在Vue3组件中引入,使用ref来获取图片元素的引用。在onMounted生命周期中初始化Cropper实例,并配置选项。用户可能需要处理上传图片和获取裁剪后的数据,比如通过Canvas导出。 需要注意在Vue3中,使用组合式API,可能需要使用<script setup>语法。同时,要确保在组件卸载时销毁Cropper实例,避免内存泄漏。此外,样式方面需要正确设置容器和图片的大小,否则Cropper可能无法正常显示。 用户可能需要示例代码,所以需要提供一个基本的组件结构,包括模板、脚本和样式部分。同时,要说明如何通过按钮触发获取裁剪结果,比如使用getCroppedCanvas方法。 还要注意引用来源是否正确。例如,引用1和2提到了Vue-Cropper,但可能适用于Vue2,所以在Vue3中推荐直接使用CropperJS,如引用4所示。因此,在回答中应明确说明这一点,避免用户混淆。 最后,生成相关问题时要围绕CropperJSVue3中的使用,比如如何处理响应式、自定义配置、图片上传等。</think>### 在Vue3中集成与使用CropperJS的步骤 #### 1. 安装依赖 ```bash npm install cropperjs # 或 yarn add cropperjs ``` #### 2. 基础组件实现 ```vue <template> <div class="cropper-container"> <img ref="cropperImg" :src="imgSrc" alt="裁剪图片"> <button @click="getCroppedResult">获取裁剪结果</button> </div> </template> <script setup> import { ref, onMounted, onBeforeUnmount } from 'vue'; import Cropper from 'cropperjs'; import 'cropperjs/dist/cropper.css'; const imgSrc = ref('https://example.com/sample.jpg'); const cropperImg = ref(null); let cropperInstance = null; // 初始化Cropper onMounted(() => { cropperInstance = new Cropper(cropperImg.value, { aspectRatio: 16 / 9, // 默认比例 viewMode: 1, // 限制裁剪框不超过图片范围 autoCropArea: 0.8 // 初始裁剪区域比 }); }); // 销毁实例 onBeforeUnmount(() => { if (cropperInstance) { cropperInstance.destroy(); } }); // 获取裁剪结果 const getCroppedResult = () => { const canvas = cropperInstance.getCroppedCanvas(); canvas.toBlob(blob => { // 处理blob对象(上传/预览等) console.log('裁剪结果:', blob); }); }; </script> <style> .cropper-container { max-width: 800px; margin: 0 auto; } img { max-width: 100%; height: auto; } </style> ``` #### 3. 关键配置解析 - `aspectRatio`: 控制裁剪框宽高比,设为`NaN`可自由调整 - `viewMode`: 控制视图模式,`0`无限制,`1`限制裁剪框不超出图片 - `crop(event)`: 通过事件监听裁剪变化 - `autoCropArea`: 初始裁剪区域比(0-1) #### 4. 文件上传集成 建议结合`<input type="file">`实现本地图片上传: ```vue <input type="file" @change="handleFileUpload"> // 在setup中新增: const handleFileUpload = (e) => { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = (event) => { imgSrc.value = event.target.result; cropperInstance.replace(event.target.result); }; reader.readAsDataURL(file); } }; ``` #### 5. 类型声明支持(TypeScript) 在`env.d.ts`中添加: ```typescript declare module 'cropperjs'; ``` ### 注意事项 1. 容器需要明确尺寸,否则可能无法正常渲染 2. 建议使用`v-if`控制组件挂载时机 3. 移动端需添加`touch-action: none`样式避免手势冲突[^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值