elementUI 表单输入,第二次无法输入bug

144 阅读2分钟

最近又写bug了,点击按钮弹出一个对话框提交内容,这里使用element UI中的dialog组件和form表单组件。第一次打开可以正常输入内容,第二次打开就不可以输入了。

话不多说直接上代码

    <!-- 新增弹窗 -->
    <el-dialog title="新增员工信息" :visible.sync="addDialog" width="500px">
      <el-form
        :model="addForm"
        label-width="100px"
        :rules="rulesAdd"
        ref="addForm"
      >
        <el-form-item label="员工昵称" prop="nickname"
          ><el-input
            type="text"
            v-model="addForm.nickname"
            placeholder="请输入昵称"
            maxlength="15"
            show-word-limit
          ></el-input
        ></el-form-item>

        <el-form-item label="手机号码" prop="phone"
          ><el-input
            type="text"
            v-model="addForm.phone"
            placeholder="请输入手机号码"
            ref="phone"
            maxlength="11"
          ></el-input
        ></el-form-item>
        <el-form-item label="密码" prop="plaintextPassword">
          <el-input
            type="text"
            v-model="addForm.plaintextPassword"
            placeholder="请输入密码"
            maxlength="16"
            show-word-limit
          ></el-input
        ></el-form-item>

        <el-form-item label="所在机构:" prop="orgId">
          <el-select
            clearable
            v-model="addForm.orgId"
            placeholder="请选择所在机构"
            @change="getShopList()"
          >
            <el-option
              v-for="item in orgList"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="所属门店" v-show="showShopList" prop="shopId"
          ><el-select
            v-model="addForm.shopId"
            placeholder="输入或选择门店"
            allow-create
            filterable
          >
            <el-option
              v-for="item in shopList"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            ></el-option></el-select
        ></el-form-item>
        <el-form-item label="性别"
          ><el-radio-group v-model="addForm.sex">
            <el-radio label="0">女</el-radio>
            <el-radio label="1">男</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="邮箱"
          ><el-input
            type="text"
            v-model="addForm.email"
            placeholder="请输入邮箱"
          ></el-input>
        </el-form-item>
        <el-form-item label="生日">
          <el-date-picker
            type="datetime"
            placeholder="选择生日"
            v-model="addForm.birthday"
            style="width: 100%"
            value-format="yyyy-MM-dd HH:mm:ss"
          ></el-date-picker>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDialog = false">取 消</el-button>
        <el-button type="primary" @click="add('addForm')">确 定</el-button>
      </span>
    </el-dialog>

打开弹窗时的回调

正确写法
    //打开新增弹窗
    openAdd() {
      this.type = "add";
      this.showShopList = false;
      this.addForm = {
        shopId: "",
        sex: "0",
        plaintextPassword: "",
        phone: "",
        orgId: "",
        nickname: "",
        email: "",
        birthday: "",
      };
      this.addDialog = true;
    },
错误写法
    //打开新增弹窗
    openAdd() {
      this.type = "add";

      this.showShopList = false;
      this.addForm.nickname = "";
      this.addForm.phone = "";
      this.addForm.orgId = "";
      this.addForm.shopId = "";
      this.addForm.sex = "0";
      this.addForm.plaintextPassword = "";
      this.addForm.birthday = "";
      this.addForm.email = "";
      this.addDialog = true;
    },

原因:

Vue的响应式是通过对象的属性getter/setter来实现的。当我们创建一个新的对象时,Vue会重新收集这个对象的依赖,从而实现响应式更新。如果只是修改对象的属性值,Vue的响应式系统并不会重新收集依赖,因为它认为对象本身没有变化。如我们在错误写法中,并没有真正重置Vue数据绑定的引用。addForm对象的引用没有改变,它仍然是同一个对象,只是它的属性被设置为了默认值,所以再次打开对话框时,表单元素仍然绑定的是上一次的数据,导致无法输入。