vue的计算属性(computed)

发布于:2023-01-04 ⋅ 阅读:(282) ⋅ 点赞:(0)

什么是计算属性

概念

计算属性是vue里面为了简化在模板语法中对响应式属性做计算而存在的

什么时候应该使用计算属性

根据现有响应式的值得到一个新的值

计算属性怎么使用

vue3之前是使用选项式 api【Options API】的,vue3之后使用了组合式api【Composition API】
在选项式api中

<script>
export default {
  data() {
    return {
      author: {
        name: 'John Doe',
        books: [
          'Vue 2 - Advanced Guide',
          'Vue 3 - Basic Guide',
          'Vue 4 - The Mystery'
        ]
      }
    }
  },
  computed: {
    publishedBooksMessage() {
      return this.author.books.length > 0 ? 'Yes' : 'No'
    }
  }
}
</script>

<template>
  <p>Has published books:</p>
  <span>{{ publishedBooksMessage }}</span>
</template>

在组合式api中
1. 使用setup语法糖

<script setup>
import { reactive, computed } from 'vue'

const author = reactive({
  name: 'John Doe',
  books: [
    'Vue 2 - Advanced Guide',
    'Vue 3 - Basic Guide',
    'Vue 4 - The Mystery'
  ]
})

// a computed ref
const publishedBooksMessage = computed(() => {
  return author.books.length > 0 ? 'Yes' : 'No'
})
</script>

<template>
  <p>Has published books:</p>
  <span>{{ publishedBooksMessage }}</span>
</template>

2. 使用setup方法
和其他的属性一样需要return暴露出来才可以使用
或者直接写在return返回对象中

<script>
import {reactive, computed } from 'vue'
export default {
  setup(){
    const author = reactive({
      name: 'John Doe',
      books: [
        'Vue 2 - Advanced Guide',
        'Vue 3 - Basic Guide',
        'Vue 4 - The Mystery'
      ]
    })

    return{
      author,
      publishedBooksMessage:computed(() => {
        return author.books.length > 0 ? 'Yes' : 'No'
      })
    }
  },

  mounted() {
    console.log(this.count) // 0
  }

}

</script>

<template>
  <p>Has published books:</p>
  <span>{{ publishedBooksMessage }}</span>
</template>

计算属性与xxx的区别

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

<script setup>
import { reactive, computed } from 'vue'

const author = reactive({
  name: 'Foo Bar',
  firstName: 'Foo',
  lastName: 'Bar',
  fullName: 'Foo Bar',
  books: [
    'Vue 2 - Advanced Guide',
    'Vue 3 - Basic Guide',
    'Vue 4 - The Mystery'
  ]
})

// a computed ref
const publishedBooksMessage = computed(() => {
  console.log("触发计算属性")
  return author.books.length > 0 ? 'Yes' : 'No'
})
function set(){
  console.log("触发set方法")
  return author.books.length > 0 ? 'Yes' : 'No'
}
function add(){
  author.books.push("book")
}
</script>

<template>
  <p>Has published books:</p>
  <p>
    计算属性
  </p>
  <p>{{ publishedBooksMessage }}</p>
  <p>{{ publishedBooksMessage }}</p>
  <p>{{ publishedBooksMessage }}</p>
  <p>
    方法
  </p>
  <p>{{ set() }}</p>
  <p>{{ set() }}</p>
  <p>{{ set() }}</p>
  
  <button @click="add">
    添加
  </button>
</template>

计算属性vs监听器
计算属性可以监听多个属性的变化,选项式api中watch只可以一个一个的监听
watch没有返回值

data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }

计算属性有哪些特性

  1. 看起来像一个方法,其实它是一个属性使用时不能在后面加()
  2. 必须有返回值必须有return
  3. 命名不能与其他属性重复我怎么知道你要使用哪个
  4. 计算属性是有缓存的依赖的值没有改变时就不进行计算,直接返回缓存的值
  5. 计算属性是基于它们的响应式依赖进行缓存的不是响应式的就不管
  6. 不能直接对计算属性进行修改要使用get,set方法

计算属性的注意事项

不能直接修改计算属性,只能通过改变它所依赖的响应式属性来改变它

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}
<script setup>
import { reactive, computed } from 'vue'

const author = reactive({
  name: 'John Doe',
  books: [
    'Vue 2 - Advanced Guide',
    'Vue 3 - Basic Guide',
    'Vue 4 - The Mystery'
  ]
})

// a computed ref
const publishedBooksMessage = computed(() => {
  return author.books.length > 0 ? 'Yes' : 'No'
})
function set(){
  publishedBooksMessage.value = "123314" // 计算属性返回的是一个ref所以要改变它需要.value
  // 提示 about:srcdoc:160 Write operation failed: computed value is readonly
}
</script>

<template>
  <p>Has published books:</p>
  <span>{{ publishedBooksMessage }}</span>
  <button @click="set">
    点击
  </button>
</template>

不要在里面修改dom
不要在里面做异步请求
因为有缓存,很多时候的是直接返回缓存的值,从而不执行dom操作和异步请求,这样会导致许多的bug出现