Vue3中的监听器。toRefs与toRef的区别

toRefs与toRef

作用:将一个响应式对象的属性 都换转换ref对象

复制代码
<template>
  <h2>姓名:{{ person.name }}</h2>
  <h2>年龄:{{ person.age }}</h2>
  <h2>性别:{{ person.gender }}</h2>
  <button @click="changeName">修改名字</button>
  <button @click="changeAge">修改年龄</button>
  <button @click="changeGender">修改性别</button>
</template>

<script lang="ts" setup name="Person">

import {reactive, toRef, toRefs} from "vue";

let person = reactive({name: '张三', age: 20, gender: '男'})

//通过toRefs 将person中的属性 批量取出(ref),保持响应式
let {name, gender} = toRefs(person)

//通过toRef将person中的一个属性 取出来(ref) 保持响应式
let age = toRef(person, 'age');


const changeName = () => {
  name.value += "*";
}
const changeAge = () => {
  age.value += 1;
}
const changeGender = () => {
  gender.value = "女"
}

</script>

<style scoped>

</style>

computed

作用:根据已有属性计算新的属性,有缓存机制 当已有属性改变时计算属性也会变

复制代码
<template>
  姓:<input type="text" v-model="firstName"/><br/><br/>
  名:<input type="text" v-model="laseName"/><br/><br/>
  <!--  全名:<span>
        {{ fullName }}
        {{ fullName }}
        {{ fullName }}
        {{ fullName }}
        </span>-->
  全名:<input type="text" v-model="fullName"/>
</template>

<script lang="ts" setup name="Person">

import {computed, ref} from "vue";

let firstName = ref("张");
let laseName = ref("三");

//通过计算属性(只读取)不修改
// let fullName = computed(() => {
//   console.log("执行了计算属性 fullName")
//   return firstName.value + "-" + laseName.value;
// })

//通过计算属性(读/写)不修改
let fullName = computed({
  get() {
    //读取
    console.log("fullName get");
    return firstName.value + "-" + laseName.value;
  },
  set(value) {
    //写入
    console.log("fullName set,", value);
    let arr = value.split("-");
    firstName.value = arr[0];
    laseName.value = arr[1];
  }
})


</script>

<style scoped>

</style>

watch 监视

在Vue3中 watch只能监视四中数据

1.ref定义的数据

2.reactive定义的数据

3.函数返回的一个值

4.包含上述内容的数组

监视ref定义的基本数据类型

复制代码
<template>
  <h1>情况一:监视ref定义的数据</h1>
  <h2>count:{{ count }}</h2>
  <button @click="changeCount">点击count+1</button>

</template>

<script lang="ts" setup name="Person">
import {ref, watch} from "vue";

let count = ref(0);

const changeCount = () => {
  count.value += 1;
}

//监视ref定义的数据
const stopWatch = watch(count, (newValue, oldValue) => {
  console.log("count改变了", newValue, oldValue)
  if (count.value >= 5) {
    //停止监视
    stopWatch();
  }
})


</script>

<style scoped>

</style>

监视ref定义的对象类型数据

数据:直接写数据名,监视的是对象的地址,如果要监视对象的属性,启用深度监视

复制代码
<template>
  <h1>情况二:监视ref定义的对象类型数据</h1>
  <h2>姓名:{{ person.name }}</h2>
  <h2>年龄:{{ person.age }}</h2>
  <button @click="changeName">修改姓名</button>
  <button @click="changeAge">修改年龄</button>
  <button @click="changePerson">修改对象</button>
</template>

<script lang="ts" setup name="Person">
import {ref, watch} from "vue";

let person = ref({name: "张三", age: 25});
const changeName = () => {
  person.value.name += "~";
}
const changeAge = () => {
  person.value.age += 1;
}
const changePerson = () => {
  person.value = {name: "李四", age: 30};
}

//监视ref定义的对象类型数据
//监视person对象的整体改变
// watch(person, (newValue, oldValue) => {
//   console.log("person改变了", newValue, oldValue)
// })

//deep: true 深度监视 监视对象下所有的属性
/***
 * 参数1:被监视的数据
 * 参数2:监视的回调函数
 * 参数3,配置对象(deep.immediate.....)
 */
watch(person, (newValue, oldValue) => {
  console.log("person改变了", newValue, oldValue)
}, {deep: true})


</script>

<style scoped>

</style>

监视reactive定义的对象类型数据

默认开启深度监视

复制代码
<template>
  <h1>情况二:监视ref定义的对象类型数据</h1>
  <h2>姓名:{{ person.name }}</h2>
  <h2>年龄:{{ person.age }}</h2>
  <button @click="changeName">修改姓名</button>
  <button @click="changeAge">修改年龄</button>
  <button @click="changePerson">修改对象</button>
  <hr/>
  <h2>测试:{{ obj.a.b.c.d }}</h2>
  <button @click="test">修改d</button>


</template>

<script lang="ts" setup name="Person">
import {reactive, watch} from "vue";

let person = reactive({name: "张三", age: 25});

let obj = reactive({a: {b: {c: {d: 666}}}})


const changeName = () => {
  person.name += "~";
}
const changeAge = () => {
  person.age += 1;
}
const changePerson = () => {
  // person = {name: "李四", age: 30};
  Object.assign(person, {name: "李四", age: 30})
}

const test = () => {
  obj.a.b.c.d = 888;
}

/**
 * 通过 reactive 定义的对象类型数据 监视 默认开启深度监视
 */
watch(person, (newValue, oldValue) => {
  console.log("person改变了", newValue, oldValue)
})

watch(obj, (newValue, oldValue) => {
  console.log("obj改变了", newValue, oldValue)
})
</script>

<style scoped>

</style>

监视ref或者reactive定义的对象类型数据中的 "某个属性"

复制代码
<template>
  <div>
    <h2>监视reactive或者 ref定义的对象类型的某个属性</h2>

    <h2>姓名:{{ person.name }}</h2>
    <h2>年龄:{{ person.age }}</h2>
    <h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>

    <button @click="changeName">修改姓名</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="changeC1">修改第一台车</button>
    <button @click="changeC2">修改第二台车</button>
    <button @click="changeCar">修改整辆车</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import {reactive, watch} from "vue";

let person = reactive({
  name: "张三",
  age: 25,
  car: {
    c1: '比亚迪',
    c2: "雅迪"
  }
})
const changeName = () => {
  person.name += "!";
}
const changeAge = () => {
  person.age += 1;
}
const changeC1 = () => {
  person.car.c1 = "奥迪";
}
const changeC2 = () => {
  person.car.c2 = "小牛";
}
const changeCar = () => {
  person.car = {c1: "爱玛", c2: '小刀'};
}

//监视响应式对象中的某个数据 并且该数据是基本类型,要写函数式
// watch(() => person.name, (newValue, oldValue) => {
//   console.log("name发生了改变",newValue, oldValue);
// })

/**
 * 监视响应式对象中的 某个属性 并且改属性为对象类型,
 * 直接写,写函数,更推荐函数式
 */
watch(() => person.car, (newValue, oldValue) => {
  console.log("car发生了改变", newValue, oldValue);
}, {deep: true})

//直接写的方式监视  只能监视到 属性的改变,并且在替换后 不能在监视
watch(person.car, (newValue, oldValue) => {
  console.log("car发生了改变", newValue, oldValue);
}, {deep: true})

</script>

<style scoped>

</style>

监视上述多个数据

复制代码
<template>
  <div>
    <h2>监视上述多个数据</h2>

    <h2>姓名:{{ person.name }}</h2>
    <h2>年龄:{{ person.age }}</h2>
    <h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>

    <button @click="changeName">修改姓名</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="changeC1">修改第一台车</button>
    <button @click="changeC2">修改第二台车</button>
    <button @click="changeCar">修改整辆车</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import {reactive, watch} from "vue";

let person = reactive({
  name: "张三",
  age: 25,
  car: {
    c1: '比亚迪',
    c2: "雅迪"
  }
})
const changeName = () => {
  person.name += "!";
}
const changeAge = () => {
  person.age += 1;
}
const changeC1 = () => {
  person.car.c1 = "奥迪";
}
const changeC2 = () => {
  person.car.c2 = "小牛";
}
const changeCar = () => {
  person.car = {c1: "爱玛", c2: '小刀'};
}

watch([() => person.name, person.car], (newValue, oldValue) => {
  console.log("person.name, person.car",newValue, oldValue)
}, {deep: true});
</script>

<style scoped>

</style>
相关推荐
非凡ghost几秒前
Affinity Photo(图像编辑软件) 多语便携版
前端·javascript·后端
非凡ghost3 分钟前
VideoProc Converter AI(视频转换软件) 多语便携版
前端·javascript·后端
endlesskiller9 分钟前
3年前我不会实现的,现在靠ai辅助实现了
前端·javascript
用户9047066835711 分钟前
commonjs的本质
前端
Zyx200715 分钟前
用 JavaScript 打造 AI 大脑:前端开发者的新时代——基于 Brain.js 的浏览器端 NLP 实战
javascript·机器学习
Sailing19 分钟前
5分钟搞定 DeepSeek API 配置:从配置到调用一步到位
前端·openai·ai编程
麦麦大数据20 分钟前
F035 vue+neo4j中医南药药膳知识图谱可视化系统 | vue+flask
vue.js·知识图谱·neo4j·中医·中药·药膳·南药
Pa2sw0rd丶21 分钟前
如何在 React 中实现键盘快捷键管理器以提升用户体验
前端·react.js
麦麦大数据26 分钟前
F037 vue+neo4j 编程语言知识图谱可视化分析系统vue+flask+neo4j
vue.js·flask·知识图谱·neo4j·可视化·编程语言知识图谱
非凡ghost37 分钟前
ToDoList(开源待办事项列表) 中文绿色版
前端·javascript·后端