系列文章目录
一、computed 函数
1. 计算属性 — 简写(不考虑计算属性被修改的情况)
- 在 setup 中定义 person 对象,通过 reactive 设置成响应式
- 给 person 添加计算属性,名为 fullName,返回全名
<template>
<div>
<h3>一个人的信息</h3>
姓:<input type="text" v-model="person.firstName" /><br />
名:<input type="text" v-model="person.lastName" /><br />
<span>全名:{
{
person.fullName }}</span><br/>
</div>
</template>
<script>
import {
reactive, computed } from "vue";
export default {
name: "Demo",
setup() {
// 数据
let person = reactive({
firstName: "张",
lastName: "三",
});
// 计算属性——简写(没有考虑计算属性被修改的情况)
person.fullName = computed(()=>{
return person.firstName + '-' + person.lastName
})
// 返回一个对象
return {
person,
};
},
};
</script>
计算属性显示全名:
2. 计算属性 — 完整写法(考虑计算属性被修改的情况)
- 动态修改 input 框,响应式变化
- 完整写法,要在计算属性内配置 get 和 set
- get 里面是返回值,set 里面给对应属性赋值
<template>
<div>
<h3>一个人的信息</h3>
姓:<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">
</div>
</template>
<script>
import {
reactive, computed } from "vue";
export default {
name: "Demo",
setup() {
// 数据
let person = reactive({
firstName: "张",
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>
效果如下:
二、watch 函数
1. 监视 ref 所定义的一个响应式数据
- 第一个参数:监听的是谁
- 第二个参数:监视的回调
- 第三个参数:监视的配置 => 立即执行(页面一经加载就执行一次)
<template>
<div>
<h3>当前求和为:{
{
sum }}</h3>
<button @click="sum++">点我+1</button>
</div>
</template>
<script>
import {
ref, watch } from "vue";
export default {
name: "Demo",
setup() {
// 数据
let sum = ref(0);
// 情况一:监视ref所定义的一个响应式数据
watch(sum, (newValue, oldValue) => {
console.log("sum变了", newValue, oldValue);
}, {
immediate: true});
// 返回一个对象
return {
sum,
};
},
};
</script>
监听 ref 所定义的一个响应式数据:
2. 监视 ref 所定义的多个响应式数据
- 监视多个响应式数据:sum 和 msg
- sum 每次
+1
,msg 每次多一个!
- 监听多个数据:用
[]
括起来
<template>
<div>
<h3>当前求和为:{
{
sum }}</h3>
<button @click="sum++">点我+1</button>
<hr/>
<h3>当前的信息为:{
{
msg }}</h3>
<button @click="msg+='!'">修改信息</button>
</div>
</template>
<script>
import {
ref, watch } from "vue";
export default {
name: "Demo",
setup() {
// 数据
let sum = ref(0);
let msg = ref('你好啊')
// 情况二:监视ref所定义的多个响应式数据
watch([sum, msg], (newValue, oldValue)=>{
console.log('sum或msg变了', newValue, oldValue);
})
// 返回一个对象
return {
sum,
msg,
};
},
};
</script>
按钮分别点击两次:
3. 监视 reactive 所定义一个响应式数据的全部数据
- 监视 reactive 定义的响应式数据时:oldValue 无法正确获取
- 监视 reactive 定义的响应式数据时:强制开启了深度监视(deep 配置失效)
<template>
<div>
<h3>姓名:{
{
person.name}}</h3>
<h3>年龄:{
{
person.age}}</h3>
<button @click="person.name+='~'">修改姓名</button>
<button @click="person.age++">增长年龄</button>
</div>
</template>
<script>
import {
reactive, watch } from "vue";
export default {
name: "Demo",
setup() {
// 数据
let person = reactive({
name: '张三',
age: 18,
})
/*
情况三:监视reactive所定义一个的响应式数据的全部数据
1.注意:此处无法正确的获取oldValue
2.注意:强制开启了深度监视(即deep配置无效)
*/
watch(person, (newValue, oldValue)=>{
console.log('person变化了', newValue, oldValue);
}, {
deep: true})
// 返回一个对象
return {
person
};
},
};
</script>
都是显示的 newValue:
4. 监视 reactive 所定义一个响应式数据中的某个属性
- 要写成函数的形式
() => person.age
<template>
<div>
<h3>姓名:{
{
person.name}}</h3>
<h3>年龄:{
{
person.age}}</h3>
<button @click="person.name+='~'">修改姓名</button>
<button @click="person.age++">增长年龄</button>
</div>
</template>
<script>
import {
reactive, watch } from "vue";
export default {
name: "Demo",
setup() {
// 数据
let person = reactive({
name: '张三',
age: 18,
})
// 情况四:监视reactive所定义一个响应式数据中的某个属性
watch(() => person.age, (newValue, oldValue)=>{
console.log('person的age变化了', newValue, oldValue);
})
// 返回一个对象
return {
person
};
},
};
</script>
某个属性:oldValue 可以获取:
5. 监视 reactive 所定义一个的响应式数据中的某些属性
- 用
[]
包裹起来,写成数组的形式- 多个属性分别用函数形式表示
<template>
<div>
<h3>姓名:{
{
person.name}}</h3>
<h3>年龄:{
{
person.age}}</h3>
<button @click="person.name+='~'">修改姓名</button>
<button @click="person.age++">增长年龄</button>
</div>
</template>
<script>
import {
reactive, watch } from "vue";
export default {
name: "Demo",
setup() {
// 数据
let person = reactive({
name: '张三',
age: 18,
})
// 情况五:监视reactive所定义一个的响应式数据中的某些属性
watch([() => person.name, () => person.age], (newValue, oldValue) => {
console.log('person的name或age变化了', newValue, oldValue);
})
// 返回一个对象
return {
person
};
},
};
</script>
依次点击修改姓名,增长年龄:
6. 监视 reactive 定义的响应式数据中某个属性时:deep配置有效。
- 若设置
deep: false
,则控制台没有输出- 监视 reactive 定义的响应式数据中某个属性时:deep配置有效。
<template>
<div>
<h3>姓名:{
{
person.name}}</h3>
<h3>年龄:{
{
person.age}}</h3>
<h3>薪资:{
{
person.job.j1.salary}}K</h3>
<button @click="person.name+='~'">修改姓名</button>
<button @click="person.age++">增长年龄</button>
<button @click="person.job.j1.salary++">增加薪资</button>
</div>
</template>
<script>
import {
reactive, watch } from "vue";
export default {
name: "Demo",
setup() {
// 数据
let person = reactive({
name: '张三',
age: 18,
job: {
j1:{
salary: 20
}
}
})
// 特殊情况:监视reactive定义的响应式数据中某个属性时:deep配置有效。
watch(() => person.job, (newValue, oldValue) => {
console.log('person的job变化了', newValue, oldValue);
}, {
deep: false})
// 返回一个对象
return {
person
};
},
};
</script>
开启深度监视:
三、watchEffect 函数
1. 对比 watch 和 watchEffect
- watch 的套路:既要指明监视的属性,也要指明监视的回调
- watchEffect 的套路:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性
2. watchEffect 类似于 computed
- 但 computed 注重的计算出来的值(回调函数的返回值),所以必须要写返回值
- 而 watchEffect 更注重的是过程(回调函数的函数体),所以不用写返回值
当点击 点我+1
和 增加薪资
时会被监视:
<template>
<div>
<h3>当前求和为:{
{
sum }}</h3>
<button @click="sum++">点我+1</button>
<hr/>
<h3>薪资:{
{
person.job.j1.salary}}K</h3>
<button @click="person.job.j1.salary++">增加薪资</button>
</div>
</template>
<script>
import {
ref, reactive, watchEffect } from "vue";
export default {
name: "Demo",
setup() {
// 数据
let sum = ref(0);
let person = reactive({
job: {
j1:{
salary: 20
}
}
})
watchEffect(()=>{
const x1 = sum.value
const x2 = person.job.j1.salary
console.log('watchEffect所指定的回调执行了', x1, x2);
})
// 返回一个对象
return {
sum,
msg,
person
};
},
};
</script>
第一个按钮点击一次,第二个按钮点击两次:
四、生命周期钩子
1. 官方图解
2. 通过配置项的形式使用生命周期钩子
- setup 就是一个配置项,通过配置项的形式使用钩子
- 下面对生命周期钩子进行简单测试
App.vue
<template>
<div>
<button @click="isShowDemo = !isShowDemo">切换隐藏/显示</button>
<Demo v-if="isShowDemo" />
</div>
</template>
<script>
import {
ref } from "vue";
import Demo from "./components/Demo.vue";
export default {
name: "App",
components: {
Demo },
setup() {
let isShowDemo = ref(true);
return {
isShowDemo };
},
};
</script>
Demo.vue
<template>
<div>
<h3>当前求和为:{
{
sum }}</h3>
<button @click="sum++">点我+1</button>
</div>
</template>
<script>
import {
ref } from "vue";
export default {
name: "Demo",
setup() {
// 数据
let sum = ref(0);
// 返回一个对象
return {
sum };
},
// 通过配置项的形式使用生命周期钩子
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---');
}
};
</script>
页面一加载:
点击求和:
点击切换/隐藏显示:
3. 通过组合式API的形式去使用生命周期钩子
- 把生命周期钩子写入 setup 配置项里面
<template>
<div>
<h3>当前求和为:{
{
sum }}</h3>
<button @click="sum++">点我+1</button>
</div>
</template>
<script>
import {
ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from "vue";
export default {
name: "Demo",
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>
不积跬步无以至千里 不积小流无以成江海
点个关注不迷路,持续更新中…