Saul's blog Saul's blog
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)

Saul.J.Wu

立身之本,不在高低。
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)
  • React

  • Vue

    • Element-UI 级联选择框回显问题
    • Element-UI中El-Select的坑
    • Element UI中Switch 开关的小坑,如何使用0和1或其他?
    • Vue,计算属性VS监听属性,到底用哪个?
      • 先说结论:
      • 问题
      • 对象
      • 错误示范
        • 用 computed 来实现效果
      • 正确示例
    • vue项目搭建过程
  • 前端
  • Vue
SaulJWu
2020-07-12

Vue,计算属性VS监听属性,到底用哪个?

# 先说结论:

push是不会触发计算属性的 setter,就算值改变了也不会触发 setter,只有赋值才会,也就是使用=,所以我认为如果不是赋值的 setter 还是用回 watch 吧。

前言

我有一个需求,从服务器获取了一个数据,其中一个属性是inputList,是一个字符串,将属性值列表以逗号给开,渲染前端的时候要求每个都要取出来,这时候我就需要把他分割成数组了。

返回服务器的字段,是字符串,用 inputList记录。

姑且数组用变量 attrValArr 记录。

# 问题

1.当这个数组attrValArr 发生变化时,返回服务器的字段 inputList也要发生变化

或者

2.当字段 inputList发生变化时,数组attrValArr 也要发生变化

其实这个需求很简单,用 vue 的计算属性不就行了,是可以,但是计算属性的 setter 是要=才会触发,而attrValArr是一个数组,用push追加时,是可以让它发生变化,但是返回服务器的字段不会发生变化,这就很尴尬了。

为什么这么说,我们来看下面的代码

# 对象

// 添加类型的表单对象
addAttrForm: {
  // 分类ID
  categoryId: 0,
  // 属性的类型:0规格,1属性
  type: 0,
  // 类型名字
  name: '',
  // 是否支持手动新增
  handAddStatus: 1,
  // 属性值列表,以逗号隔开
  inputList: '',
  // 属性值列表
  attrValArr: [],
  // 控制 添加属性值的输入框 开关
  inputVisible: false,
  // 控制 要添加属性值
  inputValue: ''
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 错误示范

# 用 computed 来实现效果

methods:{
    //测试案例
    function (newValue) {
      if (newValue) {
          this.addFormAttrValList.push(inputValue)
      }
    }
},
computed: {
  // 规格属性分类列表的规格属性值
  addFormAttrValList: {
    // getter
    get: function () {
      let arr = []
      if (this.addAttrForm.inputList && this.addAttrForm.inputList.length > 0) {
        arr = this.addAttrForm.inputList.split(',')
      }
      return arr
    },
    // setter
    set: function (newValue) {
      console.log('newVal' + newValue)
      if (newValue) {
        this.addAttrForm.inputList = newValue.join(',')
      }
    }
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

但是这里并不会触发 setter,非常愚蠢。

push是不会触发计算属性的 setter,就算值改变了也不会触发 setter,只有赋值才会,也就是使用=

那么怎么才会触发?下面这样就触发了

//测试案例
function (newValue) {
  if (newValue) {
      let temp = this.addFormAttrValList
      temp.push(inputValue)
      console.log(temp)
      console.log(this.addFormAttrValList)
      this.addFormAttrValList = temp
  }
}
1
2
3
4
5
6
7
8
9
10

通过 console 我可以发现,这个值都是发生变化了,但是还是不会触发计算属性的 setter

只有执行了第 8 行代码后,才会触发计算属性的 setter

这就很难受了,我还是用回 vue 的 watch 吧。

# 正确示例

watch: {
    'addAttrForm.inputList': function (newVal) {
      this.addAttrForm.attrValArr = this.getAttrValBySpilt(newVal)
    },
    'addAttrForm.attrValArr': function (newVal) {
      this.addAttrForm.inputList = newVal.join(',')
    }
  }
1
2
3
4
5
6
7
8

这样就实现了

(这里要告诉你了,怎么只监听对象的某一个属性,而不是监听整个对象,刚才网上搜别人的都不是这样的。。。有时候我只想监听一两个对象的属性,而不是整个对象,这样子开销小,而且更加优雅)

其实可以放到服务器处理,缺点就是会增加服务器消耗,而且这个明显是渲染问题,别人服务器的数据库存的就是 inputList 字段,不可能要求别人改数据库吧。(其实后台也是我自己在写- -)

帮我改善此页面 (opens new window)
#vue#前端
上次更新: 2021/02/16, 12:29:08
Element UI中Switch 开关的小坑,如何使用0和1或其他?
vue项目搭建过程

← Element UI中Switch 开关的小坑,如何使用0和1或其他? vue项目搭建过程→

最近更新
01
zabbix学习笔记二
02-28
02
zabbix学习笔记一
02-10
03
Linux访问不了github
12-08
更多文章>
Theme by Vdoing | Copyright © 2020-2022 Saul.J.Wu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式