优雅的computed~

1,509 阅读3分钟

前言

要说Vue里我最喜欢的配置项,那绝对是computed,你 !是 !我的神!!

src=http___imgo.upan.cc_img2022_4_11_8_2022041199588905.jpg&refer=http___imgo.upan.webp

对于任何复杂逻辑,你都应当使用计算属性

计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值

用法

经典玩法

官方教程

var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})

当 this.message 发生改变时,this.reversedMessage 的绑定也会更新

配合Vuex

不再赘述.详情请查看官方文档 mapState | mapGetters

状态转化

假设我们一个表单组件拥有多个状态,不同状态下标题不同,我们可以完全这么写

{
  data(){
    return {
      state:0 // 0新增 1查看 2编辑
    }
  },
  computed: {
    formTitle() {
      return ["新增表单","查看表单","编辑表单" ][this.state];
    },
    /* ... */
  }
}

非常经典的使用场景,当我们要切换状态时,只需要修改this.state的值,Vue内部就会自动将this.formTitle更新为对应的文本

配合响应式的对象

Vue.observable的用法和Vue3中的reactive很像,想了解Vue.observable用法的同学请移步文档学习;

// store.js
export const store = Vue.observable({a: 1});
// com1.vue
{
  computed:{
    xxx(){
      return store.a 
    }
  }
}

当我们修改store.a时,com1.vue的计算属性xxx也会触发更新,如果多个vue文件使用同一个store,我们就可以实现最基本的组件状态共享

整理表单提交数据

小伙伴们不知道有没有这么一种情况:我们要提交的数据和表单组件绑定的数据格式有出入,或者数据要多添加额外字段

花火.jpg 这时候我们依然可以祭出computed;

/**
    接口所需数据
    updateUserId:'001',
    userId:'007'
    userName:'王大拿'
    startTime:'2020-01-01 00:00:00'
    endTime:'2020-02-01 23:59:59'
  **/
{
  data(){
    userList:[/*人员列表*/],
    myUserId:'001',// 创建人
    rawForm:{ 
      userId:'007',// 用户Id
      date:['2020-01-01','2020-02-01'] // 日期范围
    }
  },
  computed:{
    submitData(){
      return {
        updateUserId:this.myUserId,
        userId:this.rawForm.userId,
        userName:this.userList.find(({userId})=>userId===this.rawForm.userId).userName,
        startTime:this.rawForm.date[0]+' 00:00:00',
        endTime:this.rawForm.date[1]+' 23:59:59',
      }
    }
  }
}

这样我们在提交时可以直接提交this.submitData,总体代码也会变得更规整(<--强行夸赞)

进阶

解锁computed新玩法getter/setter计算属性 setter后,我们就可以用computed玩的更花了

路由控制

{
  computed:{
    routePath:{
      get(){
        return this.$route.path
      },
      set(path){
        // 修改this.routePath时,发起路由跳转
        this.$router.push(path);
      }
    }
  }
}

这样计算属性this.routePath展示的就是当前路由的的path,也可以通过修改this.routePath='xxxx'来跳转页面(一般在导航组件使用,可以确定当前链接高亮,并实现跳转功能)

配合输入组件

我们可以通过一个多选列表全选功能来理解 配合输入组件 (codepen.io)

尾声

但是我在工作过程中,发现computed使用率还是很少,同事更喜欢一遍遍写着一模一样的赋值语句,各种监听数据来触发更新,后期需求更新时免不得一顿批量修改和注释代码,组件内部文件里面充斥着从未使用的数据,如果不能克制这种懒散的毛病,那就多学一点这种看起来更优雅的写法吧