vue3_计算属性解决什么问题?

265 阅读2分钟

computed解决什么问题?

当我们在模板中进行复杂运算的时候:

<script setup>
import { ref } from 'vue'
// 分割小数点并判断第一位是否是数字
// 我们得到的a可能为空或者其他值,所以需要做许多的判断
const a = ref('bbb.123.abc')
</script>
<template>
  <div>
    {{ typeof a == 'string' ? Number.isNaN(a.split('.')[0]) : typeof a }}
  </div>
  <!-- 有时候我们需要重复计算某一个参数的值 -->
  <div>
    {{ typeof a == 'string' ? Number.isNaN(a.split('.')[0]) : typeof a }}
  </div>
</template>

当我们需要动态多个样式属性时:

<script setup>
import { ref } from 'vue'const border = ref('1px solid #000')
</script>
<template>
  <div
    :style="{
      width: '100px',
      height: '100px',
      textAlign: 'center',
      border: border
    }"
  >
  </div>
</template>

如果我们都在模板上写一些复杂的表达式,就会让模板变得很复杂,难以维护。行为样式相分离可以让我们减少很多问题。我们就使用computed改造如上代码:

<script setup>
import { ref, computed } from 'vue'
// 分割小数点并判断第一位是否是数字
const a = ref('bbb.123.abc')
const border = ref('1px solid #000')
​
const comValue = computed(()=>{
  return typeof a.value == 'string' ? Number.isNaN(a.value.split('.')[0]) : typeof a.value
})
​
const comStyle = computed(()=>{
  return {
    width: '100px',
    height: '100px',
    textAlign: 'center',
    border: border.value
  }
})
</script><template>
  <!-- dom结构就变得清晰可见了 -->
  <div :style="comStyle">{{ comValue }}</div>
  <!-- 重复计算一个值 -->
  <div :style="comStyle">{{ comValue }}</div>
</template>

computed跟普通函数什么区别?

计算属性与普通方法的主要区别:计算属性有缓存,只有响应式数据改变的时候,才会执行,而普通方法每次渲染是都会执行。节约性能。

computed如何使用?

基本语法
<script setup>
import { ref, computed } from 'vue'let data = ref(0)
​
const num = computed(()=> {
  // 必须有可以响应的值,属性才能发生变化
  return data.value
})
​
function changeValue(){
  data.value ++
}
</script><template>
  <div>
    <button @click="changeValue">触发修改值</button>
    <div>我的值是{{num}}</div>
  </div>
</template>
修改计算属性值

当我们想修改值时,需要用到计算属性的gettersetter,如果直接修改值会出现如下图提示:

import { ref, computed } from 'vue'let data = ref(0)
​
let num = computed(()=> {
  return data.value
})
​
function handleClick(){
  data.value++
}
​
function handleChange(){
  // 直接修改计算属性
  num.value = 100
}
​
</script>
​
<template>
  <a @click="handleClick">点击我 ++</a>
  <br>
  <a @click="handleChange">点击我修改 count 值</a>
  <div>我是计算属性的值{{num}}</div>
</template>

image-20221202145042272.png

由于计算属性默认是可读的。修改值时会收到一个运行时警告。使用以下方法修改:

// 将上述的计算属性改为如下
let num = computed({
  get(){
    return data.value
  },
  set(val){
    // 计算属性修改时,会触发set方法,回调参数是修改后 num 的值
    console.log('value', val)
    // 通过修改 get 方法中关联的值,间接修改 num
    data.value = 99
  }
})
计算属性传参

有时候我们需要根据参数来返回相应的值,computed传递参数在开发中也是经常碰到:

<script setup>
import { ref, computed } from 'vue'let data = ref(0)
​
const num = computed(()=> {
  // 使用闭包
  return (val) => {
    console.log('val', val)
    return data.value
  }
})
</script><template>
  <div>我的值是{{num(2)}}</div>
</template>

注意事项

computed 中不应该做异步请求或者去更改DOM