Vue3 —— 常用 Composition API(一)(computed函数、watch函数、watchEffect函数、生命周期钩子)

系列文章目录



一、computed 函数

1. 计算属性 — 简写(不考虑计算属性被修改的情况)

  1. 在 setup 中定义 person 对象,通过 reactive 设置成响应式
  2. 给 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. 计算属性 — 完整写法(考虑计算属性被修改的情况)

  1. 动态修改 input 框,响应式变化
  2. 完整写法,要在计算属性内配置 get 和 set
  3. 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 所定义的一个响应式数据

  1. 第一个参数:监听的是谁
  2. 第二个参数:监视的回调
  3. 第三个参数:监视的配置 => 立即执行(页面一经加载就执行一次)
	<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 所定义的多个响应式数据

  1. 监视多个响应式数据:sum 和 msg
  2. sum 每次 +1,msg 每次多一个 !
  3. 监听多个数据:用 [] 括起来
	<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 所定义一个响应式数据的全部数据

  1. 监视 reactive 定义的响应式数据时:oldValue 无法正确获取
  2. 监视 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 所定义一个响应式数据中的某个属性

  1. 要写成函数的形式 () => 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 所定义一个的响应式数据中的某些属性

  1. [] 包裹起来,写成数组的形式
  2. 多个属性分别用函数形式表示
	<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配置有效。

  1. 若设置 deep: false ,则控制台没有输出
  2. 监视 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

  1. watch 的套路:既要指明监视的属性,也要指明监视的回调
  2. watchEffect 的套路:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性

2. watchEffect 类似于 computed

  1. 但 computed 注重的计算出来的值(回调函数的返回值),所以必须要写返回值
  2. 而 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. 通过配置项的形式使用生命周期钩子

  1. setup 就是一个配置项,通过配置项的形式使用钩子
  2. 下面对生命周期钩子进行简单测试

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的形式去使用生命周期钩子

  1. 把生命周期钩子写入 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>

不积跬步无以至千里 不积小流无以成江海

点个关注不迷路,持续更新中…

猜你喜欢

转载自blog.csdn.net/qq_45902692/article/details/125907607