学习vue3二 computed,watch,watchEffect

computed用法

计算属性就是当依赖的属性的值发生变化的时候,才会触发他的更改,如果依赖的值,不发生变化的时候,使用的是缓存中的属性值。

有两种写法,对象模式和函数模式。他们的区别是:函数模式只可以读取计算属性,对象模式可以对计算属性的值进行修改

案例:

<script setup lang="ts">
  import { ref,computed } from 'vue'
  let firstName = ref('John')
  let lastName = ref('Doe')
  let fullName = computed(() => { return firstName.value + '-' + lastName.value })
  function  change():void {
    fullName.value = 'Tom-foot'
  }
</script>

<template>
  <div>
    <input type="text" v-model="firstName" />
    <input type="text" v-model="lastName" />
    <br />
    Full Name: {{ fullName }}
    <button @click="change">Change</button>
  </div>
</template>

<style scoped>
input {
  margin: 5px;
  display: block;
  height: 30px;
}
</style>

对象形式案例:

<script setup lang="ts">
  import { ref,computed } from 'vue'
  let firstName = ref('John')
  let lastName = ref('Doe')
  let fullName = computed({
    get: () => firstName.value + '-' + lastName.value,
    set: (newValue) => {
      [firstName.value, lastName.value] = newValue.split('-')
    }
  })
  function  change():void {
    fullName.value = 'Tom-foot'
  }
</script>

<template>
  <div>
    <input type="text" v-model="firstName" />
    <input type="text" v-model="lastName" />
    <br />
    Full Name: {{ fullName }}
    <button @click="change">Change</button>
  </div>
</template>

<style scoped>
input {
  margin: 5px;
  display: block;
  height: 30px;
}
</style>

computed表格案例

<script setup lang="ts">
  import { ref,computed,reactive } from 'vue'
  const search = ref('')
  interface Data {
    name: string
    price: number
    num: number
  }
  const formData = reactive<Data[]>([
    {
      name: 'apple',
      price: 10,
      num: 1
    },
    {
      name: 'banana',
      price: 5,
      num: 2
    },
    {
      name: 'orange',
      price: 15,
      num: 3
    }
  ])
  const filterData = computed(() => {
    return formData.filter(item => item.name.includes(search.value))
  })
  const total = computed(() => {
    let sum = 0
    filterData.value.forEach(item => {
      sum += item.price * item.num
    })
    return sum
  })
</script>

<template>
  <div>
    <input type="text" placeholder="搜索" style="width: 300px" v-model="search"/>
    <table cellpadding="0" cellspacing="0" border="1" style="margin-top: 50px">
      <thead>
        <tr>
          <th>名称</th>
          <th>数量</th>
          <th>价格</th>
          <th>总价</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(item,index) in filterData" :key="index">
          <td>{{ item.name }}</td>
          <td>
            <button @click="item.num > 1 ? item.num-- : null">-</button>
            {{item.num}}
            <button @click="item.num < 99 ? item.num++ : null">+</button>
          </td>
          <td>{{ item.price }}</td>
          <td>{{ item.price * item.num }}</td>
          <td><button @click="formData.splice(index,1)">删除</button></td>
        </tr>
      </tbody>
      <tfoot>
        <tr>
          <td colspan="5">总计:{{total}}</td>
        </tr>
      </tfoot>
    </table>
  </div>
</template>

<style scoped>
input {
  margin: 5px;
  display: block;
  height: 30px;
}
th,td {
  width: 200px;
  height: 20px;
}
</style>

watch用法

监听一个数据源,并执行相关回调函数

watch第一个参数监听源

watch第二个参数回调函数cb(newVal,oldVal)

watch第三个参数一个options配置项是一个对象{

immediate:true //是否立即调用一次

deep:true //是否开启深度监听 reactive自动开启

}

监听多个ref案例:

<script setup lang="ts">
  import { ref,reactive,watch } from 'vue'
  const value = ref({
    name: '张三',
    age: 18
  })
  const value2 = ref({
    name: '张三',
    age: 18
  })

  watch([value,value2], (newValue, oldValue) => {
    // 新旧value都会改变
    console.log(newValue, oldValue)
  },{
    immediate: true,
    deep: true
  })
</script>

<template>
  <input type="text" v-model="value.age">
  <input type="text" v-model="value2.age">
</template>

<style scoped>

</style>

也会变成一个proxy数组,按照监听源数组的顺序进行排列

监听Reactive

使用reactive监听深层对象开启和不开启deep 效果一样

监控reactive的单一属性值

<script setup lang="ts">
  import { ref,reactive,watch } from 'vue'

  const value2 = reactive({
    name: '张三',
    age: 18,
    person: {
      salay: 100,
      address: {
        city: '北京'
      }
    }
  })
  watch(()=> value2.person.salay, (newValue, oldValue) => {
    console.log(newValue, oldValue)
  })
</script>

<template>
  <input type="text" v-model="value2.person.salay">
</template>

<style scoped>

</style>

watchEffect

立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。也就是在函数里面用到的一些数据都会对其进行监听

案例:

也是不能深层监听的,也就是用到哪个数据就监听哪个数据

<script setup lang="ts">
  import { ref,reactive,watchEffect } from 'vue'
  const value = ref({
    foo: {
      bar: 'hello'
    }
  })
  watchEffect(()=> {
    console.log(value.value)
  },{
    flush: 'post'
  })
</script>

<template>
  <input type="text" v-model="value.foo.bar">
</template>

<style scoped>
input {
  margin: 5px;
  display: block;
  height: 30px;
}
</style>

在触发监听之前会调用一个函数可以处理你的逻辑例如防抖

停止跟踪 watchEffect 返回一个函数 调用之后将停止更新

案例:

<script setup lang="ts">
  import { ref,reactive,watchEffect } from 'vue'
  const value = ref({
    foo: {
      bar: 'hello'
    }
  })
  const stop = watchEffect(()=> {
    console.log(value.value.foo.bar)
  },{
    flush: 'post'
  })
  stop()
</script>

<template>
  <input type="text" v-model="value.foo.bar">
</template>

<style scoped>
input {
  margin: 5px;
  display: block;
  height: 30px;
}
</style>

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值