新增表单/编辑表单,共用?或分开?

目前我们写好了一个新增的画面

需求

接下来,常见的需求是,人员的新增之後是人员的编辑。

新增用的画面

编辑用的画面

假设编辑时,只能换头贴,不能改名字的画面

要合并表单的 component

我们的目的,是要将表单的 code 合成一个 compoennt ,让 user 的资料都由这个表单来处理

一开始,还无法一步就做到这件事没关系。只需要把握一个重点「不要加上不必要的 props」。

  • isEdit
  • useType: create, edit, read, manage-read, user-read....

这些加上的 props 都不好

先各别把 createUserForm 和 updateUserForm 做好

两边的 code 差别只差在一个 disabled

这简单!用 isEdit 就可以搞定了 ← 这太「浅想」了。

上次有讲过,表单是一种「写入」资料的方式。
所以,依照「读取」与「写入」我们重新思考一下这个问题

# 新增 修改
avatar 读/写 读/写
name 读/写

如果要再追加一个需求,有一个帐号需要查看所有 user 的资料,但是不可以改

# 新增 修改 查看
avatar 读/写 读/写
name 读/写

这是不是 isEdit 就不行了?继续看下去吧!

盘点一下 Vue 的读与写功能

#
component 外部使用(v-model) :value, checked @input, @change
component 设计 props event ($emit)
component 内 API $props/$attrs $listeners

所以?看得出怎麽做了吗?

合并表单的程序码

只需要在「唯读的地方」,将「写入的语法」拿掉。并且可以侦测拿掉,就可以了。
超级重要: ☆☆☆☆☆

使用 Vue3 时,因为 $listeners 没有继续存在,所以要用 $attrs
参考: $listeners removed

  • :disabled="!$listeners['update:name']"
  <form @submit.prevent="$emit('submit')">
    <p>
      <img :src="avatarSrc" alt=""><br />
      <input
        v-if="$listeners['update:file']"
        type="file"
        @change="$emit('update:file', $event.taget.files.item(0))">
    </p>
    <p><label>name: <br />
      <input
        type="text"
        :disabled="!$listeners['update:name']"
        :value="data.name"
        @input="$emit('update:name', {
          ...data,
          name: $event.target.value
        })"
      ></label>
    </p>
    <input type="submit" value="送出">
  </form>
export default {
  name: 'demo',
  props: {
    data: {
      type: Object,
      required: true,
    },
  },
  data(){
    return {
      new_avatar: null,
    }
  },
  computed: {
    avatarSrc() {
      return this.new_avatar || this.data.avatar;
    }
  },
};

而外部只要透过 @update:name="$store.commit('user', $event)" 就可以阻决定「要不要写入资料」,配合 UserForm 是 pure component 若要改值,要将值传出来并取代原本的物件。

若不改值就不用传了,所以就不要挂上这个 event 就好啦!

src/views/UserCreate.vue

  <UserForm
    :file="$store.getters.file"
    @update:file="updateFile"
    :data="data"
    @update:name="$store.commit('user', $event)"
    @submit="onSubmit"
  ></UserForm>

src/views/UserEdit.vue

  <UserForm
    :file="$store.getters.file"
    @update:file="updateFile"
    :data="data"
    @submit="onSubmit"
  ></UserForm>

src/views/UserRead.vue

这样一来,只要设定好,只有读取的权限,只需要这样使用,component 自己就应该知道如何切换读写权限了

  <UserForm :data="data"></UserForm>

终於有像样一点的进阶心法

这一步,才是刚开始进阶!哈~~
前面是因为这样的做法,是基於前述的小小习惯累积而来的

这个方法,在共用 form 表单时只要变更使用的方式,就可以改变画面的读写形式。

优点

  • 可以应付各种读写变化的需求。
  • 表单变化,不用增加不必要的 props

<<:  [Day24] 发送验证信API、信箱验证API – urls、测试阶段

>>:  [面试][人格特质]当你分享工作经验时会被问到的种种问题

Day 15:树(tree)

树是一种抽象资料结构,跟链结串列一样是由节点组成的资料集合。它的形状类似家族树,或者说像向下生长的树...

Day 23 dio函数库

昨天提到Flutter最常用的网路函数库有HttpClient和http函数库,但其实还有一种叫做d...

Day.7 保有日常备份重要性 - binlog 解析 &备份资料 (mysqldump / binlog)

回顾一下上篇提到的binlog纪录作用,可以用来做资料复原和主从机制下的重要数据纪录。 开始前先了...

【Day20】Git 版本控制 - git tag

这篇文章我想诚实面对自己,也勇敢地说出来。 对。我不知道要写什麽了... 我已经把该怎麽新建本地数据...

[Golang]go test指令说明-心智图总结

1. -cpu a. 用途: 模拟程序在不同CPU核心数的计算机,效能表现。 b. 用来设定测试执行...