vue使用watch监听表单数据变更,如何触发表单重新渲染?

作者站长头像
站长
· 阅读数 4

的形式,动态增减表单,如图所示。想实现一组中的两个下拉框的互斥关系。比如类型选择1 ,则禁用 等级 这一项。

当前实现方法:在数据中加一个isLock字段,默认为 false 。使用 watch 监听,当类型选择1 时,设置 isLock字段为 true。并在 等级 下拉选项绑定 :disabled="item.isLock" 属性。

问题:

  1. watch 监听 设置 isLock字段为 true后,如何触发页面更新?this.$forceUpdate() 无效
  2. 这种思路是否能满足需求?

一、数据结构:

      model: {
        typeId: '',
        partId: '',
        partName: '模块名称',
        projects: [
          {
            isLock: false,
            name: '名称',
            type: '类型',
            standard: '规格',
            level: '等级',
          }
        ]
      },

二、新增方法:

    addItem() {
      this.model.projects.push({
            isLock: false,
            name: '',
            type: '',
            standard: '',
            level: '',
      })
    },

三、watch监听:

watch: {
    model: {
      handler(newName, oldName) {
        for (let i = 0; i < this.model.projects.length; i++) {
          if (this.model.projects[i].projectType === '1') {
            this.model.projects[i].isLock = true
          }
        }
      },
      deep: true
    }
}

四、页面结构:

      <z-form
        ref="modelDialog"
        :model="model"
        :label-width="100"
        label-position="left"
      >
        <z-row>
          <z-col span="8">
            <z-form-item label="模块名称">
              <z-input
                v-model="model.partName"
                :maxlength="40"
                placeholder="请输入..."
                clearable
              />
            </z-form-item>
          </z-col>
        </z-row>
        <div v-for="(item, index) in model.projects" :key="index">
          <z-edit-panel class="m-t-15 p-t-20">
            <z-row>
              <z-col span="8">
                <z-form-item label="类型">
                  <z-select
                    v-model="item.type"
                    placeholder="请选择..."
                    @on-change="handleChange"
                  >
                    <z-option
                      v-for="item in typeName"
                      :value="item.value"
                      :key="item.value"
                      >{{ item.label }}</z-option
                    >
                  </z-select>
                </z-form-item>
              </z-col>
            </z-row>
            <z-row>
              <z-col span="8">
                <z-form-item label="名称">
                  <z-input
                    v-model="item.name"
                    :maxlength="40"
                    placeholder="请输入..."
                    clearable
                  />
                </z-form-item>
              </z-col>
            </z-row>
            <z-row>
              <z-col span="9">
                <z-form-item label="等级">
                  <z-select v-model="item.level" placeholder="请选择...">
                    <z-option
                      v-for="item in projectLevelOption"
                      :value="item.value"
                      :key="item.value"
                      :disabled="item.isLock"    // 禁用
                      >{{ item.label }}</z-option
                    >
                  </z-select>
                </z-form-item>
              </z-col>
              <z-col span="8">
                <z-form-item label="规格">
                  <z-select
                    v-model="item.standard"
                    placeholder="请选择..."
                  >
                    <z-option
                      v-for="item in checkFunction"
                      :value="item.value"
                      :key="item.value"
                      >{{ item.label }}</z-option
                    >
                  </z-select>
                </z-form-item>
              </z-col>
            </z-row>
            <z-row>
              <z-col span="10">
                <z-form-item label="标准">
                  <z-input
                    v-model="item.projectStandard"
                    type="textarea"
                    :autosize="{ minRows: 3, maxRows: 5 }"
                    placeholder="Please enter the detailed address"
                    class="standard-textarea"
                  ></z-input>
                </z-form-item>
              </z-col>
              <z-col span="4">
                <z-form-item
                  class="standardTextarea"
                  v-if="index === model.projects.length - 1"
                >
                  <z-button
                    type="primary"
                    size="small"
                    icon="plus-round"
                    @click="addItem"
                    >添加</z-button
                  >
                </z-form-item>
                <z-form-item
                  class="standardTextarea"
                  v-if="index === model.projects.length - 1"
                >
                  <z-button
                    type="error"
                    size="small"
                    icon="minus-round"
                    @click="delItem"
                    >删除</z-button
                  >
                </z-form-item>
              </z-col>
            </z-row>
          </z-edit-panel>
        </div>
      </z-form>

五、select @on-change 事件 this.$forceUpdate()不更新:

    handleChange(val, index) {
      for (let i = 0; i < this.model.projects.length; i++) {
        if (this.model.projects[i].projectType === '1') {
          this.model.projects[i].isLock = true
        }
      }
      this.$forceUpdate()
    }
回复
1个回答
avatar
test
2024-07-05

低级错误 :disabled="item.isLock" 应该写在 z-select 标签内。

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容