计算属性与监视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>