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

前端 - vue2项目,computed和watch带来的问题,该怎么解决?

黎奇思
2023-09-16

场景是这样的,一张新建/编辑页,编辑页的数据是接口获取的。页面里的表单元素里有一些复杂的计算逻辑,请问:
1.计算逻辑是写在methods里,然后表单元素change或者input的时候调用它,还是直接写在computed里计算它?
2.我一开始是这么写的,computed计算出需要的结果a,b,c,d(且这四个值又能通过表单元素被修改,如input)。然后watch监听a,b,c,d的变化,赋值给表单元素绑定的值。但是发现一个问题,在编辑页的时候,由于表单数据是接口获取的,在接口获取到后,computed会计算,从而watch监听到,此时假设a后端返回的值是人为修改后的数值1,但是实际被computed计算成了2,就导致页面展示数据是计算后的。这就有问题。该如何解决?
3.如果写在change或者input里感觉就会比较恶心,需要考虑的情况复杂,尤其是涉及到多个值联动的情况。

共有3个答案

皮献
2023-09-16
  1. 首先,Vue 是 MVVM 框架,MVVM 的核心是数据驱动,应该尽量维护数据而不是 UI
  2. 在此基础上,我们应该维护最底层的数据,高层数据交给框架处理,换言之,就是交给 computed 处理
  3. 尽量少用 watch,也尽量不侦听事件,把高层数据和视图变换留给框架
  4. 所以数据返回后,就只替换底层数据,这样不应该出问题。
卫增
2023-09-16

1.尽量写computed,不用太考虑依赖值变动的情况
2、
先给页面一个变量判断页面的数据是不是初始化了,后端返回值还没初始化的时候不要触发computed逻辑:

<template>  <div>    <!-- 表单元素绑定到计算属性的值 -->    <input v-model="computedValue">  </div></template><script>export default {  data() {    return {      // 初始化标志      initialized: false,    };  },  computed: {    // 计算属性,根据需要的逻辑计算值    computedValue() {      if (this.initialized) {        // 在初始化完成后才进行计算        return this.calculateValue();      } else {        // 在初始化之前返回接口数据或默认值        return this.apiData || defaultValue;      }    },  },  methods: {    // 复杂的计算逻辑    calculateValue() {      // 在这里进行计算      return /* 计算结果 */;    },  },  created() {    // 从接口加载数据    this.loadDataFromApi().then((data) => {      // 将接口数据赋值给data属性      this.apiData = data;      // 设置初始化标志为true,触发computed计算      this.initialized = true;    });  },};</script>
毛声
2023-09-16

该问题涉及到Vue.js中的computed属性和watch监听器,以及它们的使用和问题解决方案。

  1. 关于计算逻辑的写法,建议将其直接写在computed属性中,因为computed属性会在依赖的计算属性发生变化时重新计算,这样可以避免在表单元素change或input时进行重复计算。
  2. 关于computed计算结果被修改的问题,可以通过在computed属性中设置缓存来解决。在computed属性中添加一个名为cache的属性,并在计算函数中使用该属性进行计算。这样,如果计算结果没有变化,那么下次计算时就可以直接使用缓存结果,避免重复计算。
  3. 关于多个值联动的情况,可以使用Vue.js中的依赖关系来避免重复计算。在computed属性中添加依赖关系,让Vue.js自动根据依赖关系更新计算结果。例如:
computed: {  result() {    const a = this.a;    const b = this.b;    // 计算结果...  },  dependencyA() {    return this.a;  },  dependencyB() {    return this.b;  }}

这样,当a或b发生变化时,Vue.js会自动更新result的计算结果,而不需要手动调用computed属性的计算函数。

 类似资料:
  • 1.手机翻转,或者折叠屏该怎么监听然后动态重新渲染echarts,需要加防抖或者节流吗? 2.横向条形图,左右两边的label怎么永远出现在可视范围内?比如148.00就已经飘出去了,看不全,还有左侧还有很多留白区域,不够美观 3.饼图中间的title的text和subtext能响应式的改变字体大小吗?像这种情况,字体完全超出了饼图范围

  • markdown图片可以传到本地文件夹但只能传jpg,png传不了,数据库也有路径,但是不渲染出来 头像上传七牛云,密钥和域名都写得对的但点击就报400

  • vue2前端跨域问题,后端放置到公网上,所有人都可以访问,还配置了access-control-allow-origin为*,前端拿接口地址到浏览器可以拿到数据,使用apiPost测试,接口可以拿到数据,但是放到前端代码里面就跨域,如下图 vue2前端跨域问题

  • 场景是这样的,我们的单据新建页点击提交按钮后,拿到单据ID,然后根据单据ID触发工作流初始化接口获取到工作流人员信息。问题在于,点击提交后,该怎么展示选人比较好,一个弹框?或者在原有页面下新增选人信息?更或者关闭当前页,在另一个页面弹框选人?想听听各位的想法,你们业务上是怎么做的。

  • 比如,我切换图片时,触发以下method: 这里自动切换到当前图片对象 最后在watch时使用到了computed后的对象,但是computed是在watch之后执行的,activeImage数据就不对,有没有什么办法解决?

  • 怎么让span相对于最外层的div固定定位?(fixed),为什么最外层div的postion设置为了relative,span的postion设置为fixed,top:0,right:0后,会跑到整个页面的右上角?