当前位置: 首页 > 知识库问答 >
问题:

vue2 - Vue 2 中如何优雅地处理表单列表项添加与删除而不直接操作 props?

通安宁
2024-06-04

vue2做一个类似表单列表的东西,可添加删除表单项,但是目前是直接操作props,能帮我不直接操作props吗

//外部表单export default {  name: 'OutForm',  template: `  <el-form ref="outForm" class="outForm" :model="form" :inline="true" >     <el-form-item prop="name" label="表单名称" :rules="[{required:true}]">      <el-input v-model="form.name"></el-input>    </el-form-item>    <el-form-item label="表单组">      <NestForm ref="nestForm" :group="form.activityGroup"></NestForm>    </el-form-item>    <el-form-item label="表单数据为">      {{form}}    </el-form-item>    <el-form-item>      <el-button @click="handleSubmit">提交表单</el-button>    </el-form-item>  </el-form>  `,  data() {    return {      form: {        name: 'zs',        activityGroup: [          {            name: '活动一',            region: '区域一',            type: '类型一'          },          {            name: '活动二',            region: '区域二',            type: '类型二'          },        ]      }    }  },  methods: {    handleSubmit() {      this.$refs.outForm.validate((valid) => {        if (valid) {          this.$message.success("提交成功")        } else {          this.$message.error("表单验证失败")        }      })    }  }}
export default {  name: "NestForm",  template: `    <div>      <div v-for="(item,index) in group" :key="index" class="nestItem">        <el-form-item :prop="'activityGroup['+index+']'+'.name'" label="名称" :rules="[{required:true,message:'请输入名称'}]">          <el-input v-model="item.name"></el-input>        </el-form-item>        <el-form-item :prop="'activityGroup['+index+']'+'.region'" label="活动区域" :rules="[{required:true,message:'请输入活动区域'}]">          <el-input el-input v-model="item.region"></el-input>        </el-form-item>        <el-form-item :prop="'activityGroup['+index+']'+'.type'" label="活动形式" :rules="[{required:true,message:'请输入活动形式'}]">          <el-input v-model="item.type"></el-input>        </el-form-item>        <el-form-item>          <el-button type="danger" icon="el-icon-delete" circle @click="handleDelete(index)"/>        </el-form-item>      </div>      <el-button @click="handleAdd">添加活动</el-button>    </div>        `,  props: {    group: {      type: Array,      default() {        return []      }    }  },  methods: {    handleAdd() {      this.group.push({        name: '',        region: '',        type: ''      })    },    handleDelete(index) {      this.group.splice(index, 1)    }  }}

感觉通过父组件的方法改外部值很麻烦呀,求大佬指教有啥巧妙方法

共有2个答案

华和悦
2024-06-04

刚想回答发现AI回答的不错了,你可以参照下。就是用$emit来触发父组件事件。
不要在子组件里修改传入的props,违反了单向数据流的原则,出问题了也比较难排查。

蒲勇
2024-06-04

在Vue 2中,处理类似表单列表项添加与删除而不直接操作props,可以通过使用.sync修饰符或者自定义事件来避免直接修改props。这是因为props是单向数据流,不应该在子组件内部被修改。

以下是通过自定义事件来实现优雅处理表单列表项添加与删除而不直接操作props的方法:

NestForm 组件修改

export default {  name: "NestForm",  props: {    group: {      type: Array,      default: () => []    }  },  methods: {    handleAdd() {      this.$emit('update:group', [...this.group, {        name: '',        region: '',        type: ''      }]);    },    handleDelete(index) {      const updatedGroup = [...this.group];      updatedGroup.splice(index, 1);      this.$emit('update:group', updatedGroup);    }  }}

OutForm 组件模板修改

<template>  <el-form ref="outForm" class="outForm" :model="form" :inline="true" >     <!-- ... 其他表单项 ... -->    <el-form-item label="表单组">      <NestForm :group="form.activityGroup" @update:group="handleUpdateGroup" />    </el-form-item>    <!-- ... 其他表单项 ... -->  </el-form></template>

OutForm 组件方法修改

export default {  // ... 其他部分 ...  methods: {    // ... 其他方法 ...    handleUpdateGroup(newGroup) {      this.$set(this.form, 'activityGroup', newGroup);    },    // ... 其他方法 ...  }}

在这个修改后的例子中,我们移除了NestForm组件中的group数组的直接操作,转而使用$emit来触发一个自定义事件update:group,并传递更新后的数组作为参数。在父组件OutForm中,我们监听这个自定义事件,并在事件处理函数handleUpdateGroup中更新form.activityGroup的值。

这样做的好处是:

  1. 遵循了Vue的props单向数据流原则,避免了直接修改props。
  2. 通过自定义事件,子组件可以通知父组件其内部状态的变化,并由父组件来决定如何处理这个变化。
  3. 代码更加清晰和可维护,因为所有的状态更新都集中在父组件中处理。

请注意,使用$set是为了确保Vue能够检测到数组的变化并触发视图更新。在Vue 2中,如果你直接用一个新数组替换旧数组,Vue可能不会检测到这个变化,因此需要使用$set来确保响应性。如果你使用的是Vue 3,那么就不需要$set,因为Vue 3使用Proxy来实现响应性,可以直接替换数组。

 类似资料:
  • 我的第一个列表中有3个对象,但只有一个包含必需的注释 两个列表都以包含包含注释的唯一对象结尾 如果有人有主意的话,我就有点迷路了!

  • 专家们,需要一些帮助。 执行的JCheckBox操作(在类'A'中)如下所示, 先说一些细节: =扩展JPanel并添加到JTabbedPane的类,即类B

  • lrem key count value 从key对应list中删除count个和value相同的元素。count为0时候删除全部,count为正,则删除匹配count个元素,如果为负数,则是从右侧扫描删除匹配count个元素。复杂度是O(N),N是List长度,因为List的值不唯一,所以要遍历全部元素,而Set只要O(log(N))。 lpop key 从list的头部删除元素,并返回删除元素

  • 一个课程只有一个主题(CoursetType)和一个数字(courseNumType)。 我已经在下面粘贴了两个类的完整代码,但我认为问题是我的action listener创建了一个新对象,然后调用了一个dropClass()方法(实际上是一个list.remove())。但我不确定如何在不创建新对象的情况下传递正确的值。 这是我创建GUI和实现动作侦听器的主要方法和类: 课程类别:

  • 让我们假设我们有这样一个用python编写的琐碎守护进程: 我们使用< code>start-stop-daemon对其进行守护,默认情况下,它会在< code> - stop上发送< code > SIGTERM (< code > TERM )信号。 假设当前执行的步骤是。此时我们正在发送信号。 发生的情况是执行立即终止。 我发现我可以使用<code>signal.signal(signal.

  • 本文向大家介绍vue2 中如何实现动态表单增删改查实例,包括了vue2 中如何实现动态表单增删改查实例的使用技巧和注意事项,需要的朋友参考一下 最近项目中遇到的需求是要操作大量的表单,之前的项目中有做过这方的研究,只不过是用jquery来操作。 项目A 先简单说说以前项目A中的应用场景,可能有小伙伴儿也遇到相同的需求。A项目是公司的OA系统中有的项目,是用java的jsp渲染的页面,需求是要改成: