首页技术栈归档照片墙音乐日记随想收藏夹友链留言关于

计算属性与监视vue3.x

写作时间:2026-07-08

计算属性与监视vue3.x

vue3.x computed函数

与Vue2.x中computed配置功能一致

测试

App.vue

<template>
  <Dome/>
</template>
<script>
import Dome from './components/Dome.vue'
export default {
  name: 'App',
  components: { Dome },
}
</script>

Dome.vue

<template>
    <h1>信息</h1>
     姓:<input type="text" v-model="person.firstName"/>
     <br/>
    名:<input type="text" v-model="person.lastName"/>
    <br/>
    <span>全名:{{person.fullName}}</span>
    <br/>
    全名:<input type="text" v-model="person.fullName"/>
</template>
<script>
 import {reactive,computed} from "vue"
export default {
  name: 'Dome',
  setup(){
    let person=reactive({
      firstName:"张",
      lastName:"三",
    })
    //计算属性,给person追加一个属性-简写(没有考虑计算属性被修改的情况)
     person.fullName=computed(()=>{
      return person.firstName+"-"+person.lastName
    })
    //计算属性完整写法(考虑读和写)
    person.fullName=computed({
      get(){
         return person.firstName+"-"+person.lastName
        },
       set(value){
          const nameArr=value.split("-")
          person.firstName=nameArr[0]
          person.lastName=nameArr[1]
       } 
    })
    return{
      person
    }
  }
}
</script>

vue3.x watch函数

与Vue2.x中watch配置功能一致。

两个小“坑”:

监视reactive定义的响应式数据时: oldValue无法正确获取、强制开启了深度监视(deep配置失效)

监视reactive定义的响应式数据中某个属性时: deep配置有效。

基本类型的监听Dome.vue

<template>
    <h2>当前求和为:{{sum}}</h2>
    <button @click="sum++">点我加1</button>
    <hr/>
    <h2>当前的信息为:{{msg}}</h2>
    <button @click="msg+='!'">修改信息</button> 
    <hr/>
     <h2>姓名:{{ponsen.name}}</h2>
    <h2>年龄:{{ponsen.age}}</h2>
    <button @click="ponsen.name+='~'">修改姓名</button> 
     <button @click="ponsen.age++">增长年龄</button> 
     <hr/>  
     <h2>涨薪:{{ponsen.job.java.salary}}</h2>
     <button @click="ponsen.job.java.salary++">涨薪</button> 
</template>
<script>
import {ref,watch,reactive} from "vue"
export default {
  name: 'Dome',
  //vue2.x的写法
  // watch:{
  //   //简单版的写法
  //   //  sum(newValue,oldVale){
  //   //    console.log("sum的值发生了变化",newValue,oldVale)
  //   //  }
  //   //完整版的写法
  //   sum:{
  //     immediate:true,//立即监听
  //     deep:true,//深度监视
  //     handler(newValue,oldVale){
  //        console.log("sum的值发生了变化",newValue,oldVale)
  //     }
  //   }
  // },
  setup(){
   let sum=ref(0)
   let msg=ref("你好")
   let ponsen=reactive({
     name:"张三",
     age:18,
     job:{
       java:{
         salary:20
       }
     }
   })
   //vue3.x写法
   //情况一:监视ref所定义的响应式数据
  //  watch(sum,(newValue,oldVale)=>{
  //    console.log("sum的值发生了变化",newValue,oldVale)
  //  })


  //情况二:监视多个ref所定义的响应式数据
    // watch([sum,msg],(newValue,oldVale)=>{
    // console.log("sum或msg的值发生了变化",newValue,oldVale)
    // },{immediate:true})

  /**
   * 情况三:监视reactive所定义的一个响应式数据,
   * 注意1:此处无法正确获取到oldVale
   * 注意2:强制开启了深度监视(deep配置无效)
   */
    // watch(ponsen,(newValue,oldVale)=>{
    //   console.log("ponsen发生了变化",newValue,oldVale)
    // },{deep:false})//此处的deep配置无效

    //情况四:监视reactive所定义的一个响应数据中的末一个值
    //  watch(()=>ponsen.age,(newValue,oldVale)=>{
    //   console.log("ponsen的年龄发生了变化",newValue,oldVale)
    // })

    //情况五:监视reactive所定义的一个响应数据中的某一些属性
     // watch([()=>ponsen.age,()=>ponsen.name],(newValue,oldVale)=>{
      //console.log("ponsen的名字和年龄发生了变化",newValue,oldVale)
    })

     //特殊情况
     watch(()=>ponsen.job,(newValue,oldVale)=>{
      console.log("ponsen的年龄发生了变化",newValue,oldVale)
    },{deep:true})//此处由于监视的是reactive素定义的对象中的某个属性,所以deep配置有效

   return{
     sum,
     msg,
     ponsen
   }
  }
}
</script>

vue3.x watcrEffect函数

watch的套路是:既要指明监视的属性,也要指明监视的回调。

watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。

watchEffect有点像computed

但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值

而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。

watcrEffect监视Dome.vue

<template>
    <h2>当前求和为:{{sum}}</h2>
    <button @click="sum++">点我加1</button>
    <hr/>
    <h2>当前的信息为:{{msg}}</h2>
    <button @click="msg+='!'">修改信息</button> 
    <hr/>
     <h2>姓名:{{ponsen.name}}</h2>
    <h2>年龄:{{ponsen.age}}</h2>
    <button @click="ponsen.name+='~'">修改姓名</button> 
     <button @click="ponsen.age++">增长年龄</button> 
     <hr/>  
     <h2>涨薪:{{ponsen.job.java.salary}}</h2>
     <button @click="ponsen.job.java.salary++">涨薪</button> 
</template>
<script>
import {ref,reactive,watchEffect} from "vue"
export default {
  name: 'Dome',
  setup(){
   let sum=ref(0)
   let msg=ref("你好")
   let ponsen=reactive({
     name:"张三",
     age:18,
     job:{
       java:{
         salary:20
       }
     }
   })
      //watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
     watchEffect(()=>{
       const x1=sum.value;
       const x2=ponsen.job.java.salary;
       console.log("watchEffect所指定的被回调了")
     })
   return{
     sum,
     msg,
     ponsen
   }
  }
}
</script>

vue2和vue3生命周期对比

vue2生命周期

vue3生命周期

vue2和vue3生命周期的区别

Vue3.0中可以继续使用Vue2.x中的生命周期钩子,但有有两个被更名:

o beforeDestroy改名为beforeUnmount

o destroyed改名为unmounted

Vue3.0也提供了Composition API形式的生命周期钩子,与Vue2.x中钩子对应关系如下:

o beforeCreate ===> setup()

o created=======> setup()

o beforeMount ===> onBeforeMount

o mounted=======> onMounted

o beforeUpdate ===> onBeforeUpdate

o updated=======> onUpdated

o beforeUnmount ==> onBeforeUnmount

o unmounted=====> onUnmounted

自定义hook函数

什么是hook?

本质是一个函数,把setup函数中使用的Composition APl进行(封装。

类似于vue2.x中的mixin

自定义hook的优势:复用代码,让setup中的逻辑更清楚易懂。

在src下新建一个hooks包,在包下新建一个usePoint.js文件

import {reactive,onMounted,onBeforeMount} from "vue"
 export default function(){
  let point=reactive({
    x:0,
    y:0
  })
   //定义一个方法
  function savePoint(event){
    point.x=event.pageX
    point.y=event.pageY
    console.log(event.pageX,event.pageY)
  }

  //绑定一个点击事件 
  onMounted(()=>{
    window.addEventListener("click",savePoint)
  })
  //移除一个点击事件
  onBeforeMount(()=>{
    window.removeEventListener("click",savePoint)
  })
  //返回数据
  return point;
 }

Dome.vue

<template>
    <h2>当前求和为:{{sum}}</h2>
    <button @click="sum++">点我加1</button>
    <hr/>
    <h2>当前鼠标点击的坐标为,x:{{point.x}},y:{{point.y}}</h2>
</template>
<script>
import {ref} from "vue"
//引入usePoint
import usePoint from "../hooks/usePoint"
export default {
  name: 'Dome',
  setup(){
   let sum=ref(0)
   //接收usePoint
   let point=usePoint();
   return{
     sum,
     point
   }
  }
}
</script>

vue3.x toRef和toRefs 函数

作用:创建一个ref对象,其value值指向另一个对象中的某个属性

语法:const name = toRef(person, ' name ' )

应用:要将响应式对象中的某个属性单独提供给外部使用时。

扩展: toRefs 与toRef功能一致,但可以批量创建多个ref对象,语法:toRefs(person)

<template>
     <h2>姓名:{{name}}</h2>
    <h2>年龄:{{age}}</h2>
    <button @click="name+='~'">修改姓名</button> 
     <button @click="age++">增长年龄</button> 
     <hr/>  
     <h2>涨薪:{{job.java.salary}}</h2>
     <button @click="job.java.salary++">涨薪</button> 
</template>
<script>
import {toRef,reactive,toRefs} from "vue"
export default {
  name: 'Dome',
  setup(){
   let ponsen=reactive({
     name:"张三",
     age:18,
     job:{
       java:{
         salary:20
       }
     }
   })
   return{
    //  name:toRef(ponsen,"name"),
    //  age:toRef(ponsen,"age"),
    //  salary:toRef(ponsen.job.java,"salary")
    //只能...只能获取导一层对象中的值,如果还要在获取嵌套中的则需要手动点出来
    ...toRefs(ponsen)
   }
  }
}
</script>
avatar

yuanyourdomain

写代码,做研究,记录生活。

RECOMMENDED

MyBatis 动态 SQL

2026-07-08

Nginx 基础入门

2026-07-08

Maven 多模块与私服

2026-07-08