<>二、常用 Composition API

<>7. 计算属性与监视

<>7.1 computed函数

* 与Vue2.x中computed配置功能一致
* 写法 <template> <h1>一个人的信息</h1> 姓:<input type="text" v-model=
"person.firstName"> <br> <br> 名:<input type="text" v-model="person.lastName"> <
br> <br> <span>全名:{{ person.fullName }}</span> <br> 全名:<input type="text" v-
model="person.fullName"> </template> <script> import {reactive, computed} from
'vue' export default { name: 'Demo', /* computed: { fullName(){ return
this.person.firstName + '-' + this.person.lastName } }, */ //数据 setup(){ //数据
let person = reactive({ firstName: '张', lastName: '三', })
//计算属性——简写(没有考虑计算属性被修改的情况) /* person.fullName = computed(() => { return
person.firstName + '-' + person.lastName }) */ //计算属性——完整写法(考虑读和写) person.
fullName= computed({ get(){ return person.firstName + '-' + person.lastName },
set(value){ const newArr = value.split('-') person.firstName = newArr[0] person.
lastName= newArr[1] } }) //返回一个对象(常用) return { person, } } } </script>
<>7.2 watch函数

* 与Vue2.x中watch配置功能一致
* 两个小“坑”:
* 监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)。
* 监视reactive定义的响应式数据中某个属性时:deep配置有效。 <template> <h2>当前求和为:{{ sum }}</h2> <
button @click="sum++">点我+1</button> <hr> <h2>当前的信息为:{{ msg }}</h2> <button
@click="msg+='!'">修改信息</button> <hr> <h2>姓名:{{ person.name }}</h2> <h2>年龄:{{
person.age }}</h2> <h2>薪资:{{ person.job.j1.salary }}</h2> <button @click=
"person.name += '~'">修改姓名</button> <button @click="person.age++ ">增长年龄</button>
<button @click="person.job.j1.salary++">涨薪</button> </template> <script> import
{ref, reactive ,watch} from 'vue' export default { name: 'Demo', //Vue2
//watch: { //简写 /* sum(newValue, oldValue){ console.log('sum的值变化了!', newValue,
oldValue); } */ //完整 /* sum: { immediate: true, deep: true, handler(newValue,
oldValue){ console.log('sum的值变化了!', newValue, oldValue); } } */ //}, //数据 setup(
){ //数据 let sum = ref(0) let msg = ref('你好啊') let person = reactive({ name: '张三'
, age: 18, job: { j1: { salary: 20 } } }) //情况一:监视ref所定义的响应式数据 watch(sum, (
newValue, oldValue) => { console.log('sum变了',newValue, oldValue); }, {immediate:
true}) //情况二:监视ref所定义的多个响应式数据 watch([sum, msg], (newValue, oldValue) => {
console.log('sum或msg变了', newValue, oldValue); },{immediate: true}) /*
情况三:监视reactive所定义的一个响应式数据的全部属性 1. 注意:此处无法正确的获取oldValue 2.
注意:强制开启了深度监视(deep配置无效) */ watch(person, (newValue, oldValue) => { console.log(
'person变化了', newValue, oldValue); }) //情况四:监视reactive所定义的一个响应式数据中的某个属性 watch(()
=> person.age, (newValue, oldValue) => { console.log('person年龄变化了', newValue,
oldValue); }) //情况五:监视reactive所定义的一个响应式数据中的某些属性 watch([() => person.age, () =>
person.name], (newValue, oldValue) => { console.log('person年龄或姓名变化了', newValue,
oldValue); }) //特殊情况 watch(() => person.job, (newValue, oldValue) => { console.
log('person的job变化了', newValue, oldValue); }, {deep: true})
//此处由于监视的是reactive定义的对象中的某个属性,所以deep配置有效 //返回一个对象(常用) return { sum, msg, person,
} } } </script>
<>7.3 watchEffect函数

* watch的套路是:既要指明监视的属性,也要指明监视的回调。
* watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。
* watchEffect有点像computed:
* 但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
* 而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。
//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。 watchEffect(() => { const x1 = sum.
valueconst x2 = person.job.j1.salary console.log('watchEffect所指定的回调执行了'); })
<>8. 生命周期

* Vue3.0中可以继续使用Vue2.x中的生命周期钩子,但有有两个被更名:
* beforeDestroy改名为 beforeUnmount
* destroyed改名为 unmounted
* Vue3.0也提供了 Composition API 形式的生命周期钩子,与Vue2.x中钩子对应关系如下:
* beforeCreate===>setup()
* created=======>setup()
* beforeMount ===>onBeforeMount
* mounted=======>onMounted
* beforeUpdate===>onBeforeUpdate
* updated =======>onUpdated
* beforeUnmount ==>onBeforeUnmount
* unmounted =====>onUnmounted <template> <h2>当前求和为:{{ sum }}</h2> <button
@click="sum++">点我+1</button> </template> <script> import {onBeforeMount, ref,
onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted} from 'vue'
export default { name: 'Demo', //通过配置项的形式使用生命周期钩子 beforeCreate(){ console.log(
'---beforeCreate---'); }, created(){ console.log('---created---'); },
beforeMount(){ console.log('---beforeMount---'); }, mounted(){ console.log(
'---mounted---'); }, beforeUpdate(){ console.log('---beforeUpdate---'); },
updated(){ console.log('---updated---'); }, beforeUnmount() { console.log(
'---beforeUnmount---'); }, unmounted(){ console.log('---unmounted---'); }, //数据
setup(){ console.log('---setup---'); //数据 let sum = ref(0)
//通过组合式API的形式去使用生命周期钩子 onBeforeMount(() => { console.log('---onBeforeMount---');
}) onMounted(() => { console.log('---onMounted---'); }) onBeforeUpdate(() => {
console.log('---onBeforeUpdate---'); }) onUpdated(() => { console.log(
'---onUpdated---'); }) onBeforeUnmount(() => { console.log(
'---onBeforeUnmount---'); }) onUnmounted(() => { console.log('---onUnmounted---'
); }) //返回一个对象(常用) return { sum, } } } </script>
<>9. 自定义hook函数

* 什么是hook?
——本质是一个函数,把setup函数中使用的Composition API进行了封装。
* 类似于vue2.x中的mixin。
* 自定义hook的优势:复用代码,让setup中的逻辑更清楚易懂。
usePoint.js
import { reactive, onMounted, onBeforeUnmount } from 'vue' export default
function (){ //实现鼠标打点的相关数据 let point = reactive({ x: 0, y: 0 }) //实现鼠标打点的方法
function savePoint(e){ point.x = e.pageX point.y = e.pageY console.log(e.pageX,
e.pageY); } //实现鼠标打点的相关的生命周期钩子 onMounted(() => { window.addEventListener('click'
, savePoint) }) onBeforeUnmount(() => { window.removeEventListener('click',
savePoint) }) return point }
App.vue
<template> <button @click="isShowDemo = !isShowDemo">切换隐藏/显示</button> <Demo v-
if="isShowDemo"></Demo> <hr> <Test></Test> </template> <script> import {ref}
from 'vue' import Demo from './components/Demo.vue' import Test from
'./components/Test.vue' export default { name: 'App', components: {Demo, Test},
setup(){ let isShowDemo = ref(true) return {isShowDemo} } } </script>
components/Demo.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' import usePoint from '../hooks/usePoint' export default {
name: 'Demo', //数据 setup(){ //数据 let sum = ref(0) let point = usePoint()
//返回一个对象(常用) return { sum, point } } } </script>
<>10. toRef

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

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

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

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

APP.vue
<template> <h2>姓名:{{ name }}</h2> <h2>年龄:{{ age }}</h2> <h2>薪资:{{ job.j1.salary
}}</h2> <button @click="name += '~'">修改姓名</button> <button @click="age++ ">增长年龄<
/button> <button @click="job.j1.salary++">涨薪</button> </template> <script>
import {ref, reactive, toRef, toRefs} from 'vue' export default { name: 'Demo',
//数据 setup(){ //数据 let person = reactive({ name: '张三', age: 18, job: { j1: {
salary: 20 } } }) // const name1 = person.name // console.log('%%%', name1); //
const name2 = toRef(person, 'name') // console.log('###', name2); const x =
toRefs(person) console.log('@@@', x); //返回一个对象(常用) return { // name:
toRef(person, 'name'), // age: toRef(person, 'age'), // salary:
toRef(person.job.j1, 'salary') ...toRefs(person) } } } </script>

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信