Vue3里computed与watch使用

computed

现有如下场景,输入框输入字符,可以过滤如下列表,如下图,当我输入a后,得到另一个结果:
请添加图片描述
请添加图片描述
用vue3写法如下:

<template>
  <div>
    <input type="text" v-model="obj.mytext" />
    <ul>
      <li v-for="data in filterlist()" :key="data">{{ data }}</li>
    </ul>
  </div>
</template>

<script>
import { reactive } from "vue";
export default {
  setup() {
    const obj = reactive({
      mytext: "",
      datalist: ["aaa", "bbb", "abc", "bbb", "bcc", "add", "bcd"],
    });
    const filterlist = () => {
      return obj.datalist.filter((item) => item.includes(obj.mytext));
    };
    return {
      obj,
      filterlist,
    };
  },
};
</script>

现在我们用computed在vue3里也实现这一效果,代码如下:

<template>
  <div>
    <input type="text" v-model="obj.mytext" />
    <ul>
      <li v-for="data in computedList" :key="data">{{ data }}</li>
    </ul>
    {{ filterlist() }} {{ filterlist() }}{{ computedList }}{{ computedList }}
  </div>
</template>

<script>
import { reactive, computed } from "vue";
export default {
  setup() {
    const obj = reactive({
      mytext: "",
      datalist: ["aaa", "bbb", "abc", "bbb", "bcc", "add", "bcd"],
    });
    const filterlist = () => {
      console.log("filterlist");
      return obj.datalist.filter((item) => item.includes(obj.mytext));
    };
    const computedList = computed(() => {
      console.log("computedList");
      return obj.datalist.filter((item) => item.includes(obj.mytext));
    });
    return {
      obj,
      filterlist,
      computedList,
    };
  },
};
</script>

页面效果如下:
请添加图片描述
我们可以看到控制台打印了两次filterlist,只打印了一次computed,
多次调用computed就能体现出它的优化性能,它会走缓存,它会把第一次执行的结果保存一份,下一次就会直接用第一次保存的结果,不会重复的执行computed里的事情。

watch

刚刚上面那个场景,输入框输入字符,可以过滤如下列表,我们还可以这样写,效果是一样的:

<template>
  <div>
    <input type="text" v-model="obj.mytext" @input="handleInput" />
    <ul>
      <li v-for="data in obj.datalist" :key="data">{{ data }}</li>
    </ul>
  </div>
</template>

<script>
import { reactive } from "vue";
export default {
  setup() {
    const obj = reactive({
      mytext: "",
      datalist: ["aaa", "bbb", "abc", "bbb", "bcc", "add", "bcd"],
      oldlist: ["aaa", "bbb", "abc", "bbb", "bcc", "add", "bcd"],
    });

    const handleInput = () => {
      obj.datalist = obj.oldlist.filter((item) => item.includes(obj.mytext));
    };

    return {
      obj,
      handleInput,
    };
  },
};
</script>

现在我们用watch监听输入框双向绑定obj.mytext的改变,然后进行过滤操作,代码如下:

<template>
  <div>
    <input type="text" v-model="obj.mytext" />
    <ul>
      <li v-for="data in obj.datalist" :key="data">{{ data }}</li>
    </ul>
  </div>
</template>

<script>
import { reactive, watch } from "vue";
export default {
  setup() {
    const obj = reactive({
      mytext: "",
      datalist: ["aaa", "bbb", "abc", "bbb", "bcc", "add", "bcd"],
      oldlist: ["aaa", "bbb", "abc", "bbb", "bcc", "add", "bcd"],
    });

    watch(
      () => obj.mytext,
      () => {
        console.log("watch");
        obj.datalist = obj.oldlist.filter((item) => item.includes(obj.mytext));
      }
    );

    return {
      obj,
    };
  },
};
</script>

当我依次输入abc时,页面效果如下:
请添加图片描述
我们能看到打印了三次watch,说明watch监听事件执行了三次,而watch的写法值得注意的是先import引入watch,然后watch里第一个先写监听的值,第二个写回调方法的调用,即写成:

import { watch } from "vue";
export default {
  setup() {
    watch(
      () => 监听的值,
      () => {
        //监听的回调方法
      }
    )
  }
};

数据监听:watch

侦听一个或者多个数据的变化,数据变化时执行回调函数,watch的第三个参数(俩个额外参数 immediate控制立刻执行,deep开启深度侦听)
监听单个数据
1.导入watch函数
2.执行watch函数传入要侦听的响应式数据(ref对象)和回调函数

<script setup>
  // 1. 导入watch
  import { ref, watch } from 'vue'
  const count = ref(0)
  const setCount =  ()=>{
    count.value++
  }
  // 2. 调用watch 侦听变化
  watch(count, (newValue, oldValue)=>{
    console.log(`count发生了变化,老值为${oldValue},新值为${newValue}`)
  })
</script>
 
<template>
  <button @click="setCount">{{ count }}</button>
</template>

在这里插入图片描述
侦听多个数据
侦听多个数据,第一个参数可以改写成数组的写法,得到的新旧值也是数组的形式
说明:同时侦听多个响应式数据的变化,不管哪个数据变化都需要执行回调

<script setup>
  // 1. 导入watch
  import { ref, watch } from 'vue'
  const count = ref(0)
  const name = ref('cp')
  const setCount = ()=>{
    count.value++
  }
  const setName = ()=>{
    name.value += 'p'
  }
  // 2. 调用watch 侦听变化
  watch([count, name], ([newCount, newName],[oldCount,oldName])=>{
    console.log(`count或者name变化了`,[newCount, newName],[oldCount,oldName])
  })
</script>
 
<template>
  <button @click="setCount">{{ count }}</button>
  <button @click="setName">{{ name }}</button>
</template>

在这里插入图片描述
immediate立即监听
第三个参数,在侦听器创建时立即触发回调,响应式数据变化之后继续执行回调

<script setup>
  // 1. 导入watch
  import { ref, watch } from 'vue'
  const count = ref(0)
  const setCount = ()=>{
    count.value++
  }
  // 2. 调用watch 侦听变化
  watch(count, (newValue, oldValue)=>{
    console.log(`count发生了变化,老值为${oldValue},新值为${newValue}`)
  },{
    immediate: true
  })
</script>
 
<template>
  <button @click="setCount">{{ count }}</button>
</template>

在这里插入图片描述
deep深度监听
第三个参数,通过watch监听的ref对象默认是浅层侦听的,直接修改嵌套的对象属性不会触发回调执行,需要开启deep

<script setup>
  // 1. 导入watch
  import { ref, watch } from 'vue'
  const state = ref({ count: 0 })
  // 2. 监听对象state
  watch(state, ()=>{
    console.log('数据变化了')
  },{
    immediate:true,
    deep:true
  })
  const changeStateByCount = ()=>{
    // 直接修改不会引发回调执行
    state.value.count++
  }
</script>
 
<template>
  <button @click="changeStateByCount">{{ state.count }}</button>
</template>

1、对象更深层的值变化了,但是没有监听到
在这里插入图片描述
2、对象更深层的值变化了,也监听到了
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值