Vue3--toRefs、computed计算属性

1,780 阅读1分钟

这是我参与更文挑战的第20天,活动详情查看: 更文挑战

一、 toRefs

toRefs可以将响应式对象中所欲属性包装为ref对象,并2放回包含这些ref对象的普通对象,比如在setup函数中返回一个使用扩展运算符对象类型的响应式数据,这是这个对象类型的属性不再是响应式的,可以使用toRefs将对象中的每个属性都转换成响应式的。

当使用reactive不使用扩展运算符,数据是响应式的

<template>
  <div>
      {{state.title}}  {{state.price}} <br>
      <button @click="changeState">改变状态</button>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive } from 'vue';

export default defineComponent({
  name: '',
  setup() {
      let state = reactive({
          title: '羊肉串',
          price: 5
      })
      let changeState = () => {
          state.title = '猪肉串'
          state.price = 3
          console.log(state,'改变state...');
      }
      return {
          state,
          changeState
      }
}
});
</script>

<style scoped>

</style>

2021-06-22-21-37-26.gif

当我们使用扩展运算符直接拿值,会发现数据不再是响应式的了

 {{title}}  {{price}} <br>
  <button @click="changeState">改变状态</button>
   
setup中
return {
  ...state,
  changeState
}

2021-06-22-21-43-04.gif

为了解决扩展运算符的数据不是响应式的, 我们采用toRefs方法

import { defineComponent, reactive , toRefs} from 'vue';

setup中
 return {
          ...toRefs(state),
          changeState
 }

这样就实现了响应式

2021-06-22-21-46-13.gif

二、computed属性

直接使用

<template>
  <div>
      <p>
          价格: {{price}}
      </p>
      <p>
         <button @click="count > 1 ? count-- : ''">-</button>  数量: {{count}} <button @click="count++">+</button>
      </p>
      <p>
          总金额: {{total}}
      </p>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref,computed } from 'vue';

export default defineComponent({
  name: '',
  setup() {
      let price = ref(10)
      let count = ref(1)
      let total = computed(() => {
          return price.value * count.value
      })
      return {
          price,
          count,
          total
      }
  }
});
</script>

<style scoped>

</style>

2021-06-22-22-43-39.gif

computed使用get和set方法

setup 中
let nickName = ref('')
      let setNickName = computed({
          get() {
              return nickName.value
          },
          set(val:string) {
            nickName.value = val
          }
 })
return {
 setNickName,
 nickName
}   

template中
<p>
          <input type="text" v-model="setNickName"> {{nickName}}
</p>
      

2021-06-22-22-52-58.gif

面试问Vue3中 v-for 和 v-if的优先级

看下面的代码

template中
<ul>
          <li v-for="(item, index) in fruitList" :key="index" v-if="item.id > 1">{{item.name}}</li>
      </ul>
setup中
 let fruitList = [
          {
              id: 1,
              name: '苹果'
          },
          {
              id: 2,
              name: '香蕉'
          },
          {
              id: 3,
              name: '梨子'
          },
      ]
      
  return {
   fruitList
  }

结果报错: 在vue2中v-for的优先级大于v-if, 而在vue3中v-if的优先级大于v-for就报错

image.png

解决方法使用computed计算过滤数据

 <ul>
          <li v-for="(item, index) in filterFruitList" :key="index">{{item.name}}</li>
      </ul>
  let filterFruitList = computed(()=>{
          return fruitList.filter(v => v.id > 1)
      })

image.png