自学内容网 自学内容网

Vue 2 —监视器实现动态切换表单属性值

目录

一、需求背景

二、监视器语法

三、实例展示

1、HTML部分

2、JS部分

四、使用场景总结

1. 表单验证

2. 动态更新 UI

3. 数据同步

4. 计算属性的替代方案

计算属性的优势 :

简洁性:

监视器的优势 :

灵活性:

多属性依赖:

副作用管理:

5. 异步操作

7. 条件渲染

8. 数据初始化

9. 深度监听

10. 性能优化


一、需求背景

        项目中有一个功能内部要实现,用户在下拉框表单选择内容时,若切换表单选项,之前表单内选择的内容将自动重置,确保用户每次选择的内容是唯一的。

        此时,应该选择Vue中的监视器,使用监视器属性来实现上述的功能。

二、监视器语法

        在 Vue 2 中,监视器(Watcher)用于监听数据的变化,并在变化时执行相应的处理逻辑。监视器可以通过 watch 选项来定义。

watch: {
  // 监听单个属性
  propertyName: function(newVal, oldVal) {
    // 执行处理逻辑
  },

  // 监听嵌套属性
  'object.propertyName': function(newVal, oldVal) {
    // 执行处理逻辑
  },

  // 深度监听对象或数组
  object: {
    handler: function(newVal, oldVal) {
      // 执行处理逻辑
    },
    deep: true
  }
}

三、实例展示

1、HTML部分

在模板中,根据 form.operation 的值,动态显示不同的表单项:

        <el-col :span="24">
          <el-form-item label="* 说明备注:">
            <el-select v-model="form.operation" style="width: 80%" placeholder="请选择操作类型">
              <el-option
                v-for="option in operationOptions"
                :key="option.value"
                :label="option.label"
                :value="option.value"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-form-item v-if="form.operation === '焊接'" label="* 焊接内容:">
            <el-select
              v-model="form.weldingContent" multiple style="width: 80%" placeholder="请选择焊接内容">
              <el-option v-for="option in weldingOptions" :key="option.value" :label="option.label" :value="option.value">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item v-if="form.operation === '装配'" label="* 装配内容:">
            <el-select
              v-model="form.assembleContent" multiple style="width: 80%" placeholder="请选择装配内容">
              <el-option v-for="option in assembleOptions" :key="option.value" :label="option.label" :value="option.value">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item v-if="form.operation === '测试'" label="* 测试结果:">
            <el-radio-group v-model="form.testingContent">
              <el-radio label="成功">成功</el-radio>
              <el-radio label="失败">失败</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item v-if="form.testingContent === '失败' && form.operation === '测试'" label="* 失败原因:">
            <el-input type="textarea" v-model="form.failureReason" style="width: 80%"
                      placeholder="请简述失败原因"></el-input>
          </el-form-item>
          <el-form-item v-if="form.operation === '问题描述'" label="* 问题描述:">
            <el-input type="textarea" v-model="form.questReason" style="width: 80%"
                      placeholder="请简述遇到的问题/操作"></el-input>
          </el-form-item>
        </el-col>

2、JS部分

  watch: {
    'form.operation': function(newVal) {
      // alert('新的操作类型:'+  newVal);
      this.resetFieldsBasedOnOperation(newVal);
    }
  },
  methods: {
    resetFieldsBasedOnOperation(operation) {
      if (operation === '焊接') {
        // alert(operation);
        this.form.testingContent = '';
        this.form.failureReason = '';
        this.form.questReason = '';
        this.form.assembleContent = [];
      } else if (operation === '测试') {
        this.form.weldingContent = [];
        this.form.questReason = '';
        this.form.assembleContent = [];
      } else if (operation === '装配') {
        this.form.weldingContent = [];
        this.form.testingContent = '';
        this.form.failureReason = '';
        this.form.questReason = '';
      } else if (operation === '问题描述') {
        this.form.weldingContent = [];
        this.form.testingContent = '';
        this.form.failureReason = '';
        this.form.assembleContent = [];
      }else if (operation === '其他') {
        this.form.weldingContent = [];
        this.form.testingContent = '';
        this.form.failureReason = '';
        this.form.questReason = '';
        this.form.assembleContent = [];
}

        此处的代码,使用监视器用于监听 form.operation 的变化,并在变化时调用 resetFieldsBasedOnOperation 方法来重置表单字段。 
监听嵌套属性:
'form.operation' 是一个字符串,表示要监听 form 对象中的 operation 属性。
当 form.operation 发生变化时,会触发对应的回调函数。
回调函数参数:
newVal:新值
oldVal:旧值(可选)
方法调用:
在回调函数中,调用了 resetFieldsBasedOnOperation 方法,并传入新的 operation 值。
resetFieldsBasedOnOperation 方法根据不同的 operation 值,重置表单中的相关字段。   

四、使用场景总结

Vue 2 中的监视器(Watcher)在实际开发中有多种应用场景,以下是一些常见的使用场景:

1. 表单验证

当表单字段发生变化时,可以立即进行验证并给出反馈。

watch: {
  'form.email': function(newVal) {
    if (!this.isValidEmail(newVal)) {
      this.formErrors.email = '请输入有效的电子邮件地址';
    } else {
      this.formErrors.email = '';
    }
  }
},
methods: {
  isValidEmail(email) {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
  }
}

2. 动态更新 UI

当数据发生变化时,动态更新 UI 元素的状态或样式。

watch: {
  'user.isOnline': function(newVal) {
    if (newVal) {
      this.userStatus = '在线';
    } else {
      this.userStatus = '离线';
    }
  }
}

3. 数据同步

当某个数据源发生变化时,同步更新另一个数据源。

watch: {
  'localData': function(newVal) {
    this.syncToRemote(newVal);
  }
},
methods: {
  syncToRemote(data) {
    // 同步到远程服务器
  }
}

4. 计算属性的替代方案

        虽然计算属性(Computed Properties)更简洁,但在某些复杂情况下,使用监视器可以更灵活地处理逻辑。

使用计算属性:

// updateFullName 方法将 user.firstName 和 user.lastName 拼接成完整的姓名,并赋值给 user.fullName。
computed: {
  fullName() {
    return `${this.user.firstName} ${this.user.lastName}`;
  }
}

使用监视器:

watch: {
  'user.firstName': function(newVal) {
    this.updateFullName();
  },
  'user.lastName': function(newVal) {
    this.updateFullName();
  }
},
methods: {
  updateFullName() {
    this.user.fullName = `${this.user.firstName} ${this.user.lastName}`;
  }
}

计算属性的优势 :

简洁性:

计算属性的定义更加简洁,不需要显式地编写回调函数。
计算属性会自动缓存结果,只有在其依赖的数据发生变化时才会重新计算。

监视器的优势 :

灵活性:

监视器可以执行更复杂的逻辑,而不仅仅是简单的计算。
可以在回调函数中执行异步操作、副作用操作(如发送网络请求、修改其他数据等)。

多属性依赖:

计算属性只能依赖于当前组件的数据属性,而监视器可以监听多个属性的变化。
在上面的例子中,我们需要同时监听 user.firstName 和 user.lastName,使用监视器可以更方便地实现这一点。

副作用管理:

计算属性不适合处理有副作用的操作,因为它们会在每次依赖数据变化时重新计算。
监视器可以在数据变化时执行副作用操作,如更新其他数据、发送网络请求等。

5. 异步操作

当数据发生变化时,触发异步操作,如发送网络请求。

watch: {
  'user.activity': function(newVal, oldVal) {
    console.log(`User activity changed from ${oldVal} to ${newVal}`);
  }
}

具体示例:

<template>
  <div>
    <h1>用户活动记录</h1>
    <select v-model="user.activity">
      <option value="online">在线</option>
      <option value="offline">离线</option>
      <option value="idle">空闲</option>
    </select>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      user: {
        activity: 'online'
      }
    };
  },
// 监听 user.activity 属性的变化。
// 当 user.activity 发生变化时,触发回调函数,打印变化信息并调用 logUserActivity 方法
  watch: {
    'user.activity': function(newVal, oldVal) {
      console.log(`User activity changed from ${oldVal} to ${newVal}`);
      this.logUserActivity(newVal, oldVal);
    }
  },
// logUserActivity 方法是一个异步函数,使用 axios 发送 POST 请求到 /api/log-activity。
  methods: {
    async logUserActivity(newVal, oldVal) {
      try {
        const response = await axios.post('/api/log-activity', {
          userId: this.user.id, // 假设用户ID已经存在
          oldActivity: oldVal,
          newActivity: newVal
        });
        console.log('Activity logged successfully:', response.data);
      } catch (error) {
        console.error('Error logging activity:', error);
      }
    }
  }
};
</script>

7. 条件渲染

根据数据的变化,动态显示或隐藏组件。

watch: {
  'form.showAdvancedOptions': function(newVal) {
    if (newVal) {
      this.showAdvancedSection = true;
    } else {
      this.showAdvancedSection = false;
    }
  }
}

8. 数据初始化

在数据初始化时执行一些操作,确保初始状态正确。

watch: {
  'initialData': {
    immediate: true,
    handler(newVal) {
      if (newVal) {
        this.processInitialData(newVal);
      }
    }
  }
},
methods: {
  processInitialData(data) {
    // 处理初始数据
  }
}

9. 深度监听

对于复杂的数据结构,使用深度监听来捕获内部属性的变化。

watch: {
  'complexObject': {
    deep: true,
    handler(newVal, oldVal) {
      console.log('Complex object changed');
    }
  }
}

10. 性能优化

在某些情况下,可以使用监视器来优化性能,避免不必要的计算或渲染。

watch: {
  'largeDataset': {
    deep: true,
    handler(newVal) {
      this.updateChart(newVal);
    }
  }
},
methods: {
  updateChart(data) {
    // 更新图表数据
  }
}


原文地址:https://blog.csdn.net/weixin_49171365/article/details/143809259

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!